How do I make a field reference another field which is not a primary key in MySQL? - mysql

I know that foreign keys need not reference only primary keys but they can also reference a field that has a unique constraint on it. For my scenario, I am setting up a quiz where for each test, I have a set of questions. My table design is like this
The point is, in my 2nd table where I will put all the answer options, I want the question number field to link to the first table question number. How do I do this? Or is there an alternative to this design?
Thank you

Ideally there should be a question_id primary key column in the test_question table, and you would use this as the foreign key in the test_answer table.
With your composite primary key in the test_question table, you should make a corresponding composite foreign key:
CONSTRAINT FOREIGN KEY (test_id, question_no) REFERENCES test_question (test_id, question_no)
This is in addition to the foreign key just for the test_id column.

Add another table purely for answers, and link them via the question_no field.
A DB table should hold information on one sort of item. Questions and answers are separate sorts of information so should be in separate tables. Adding a separate table also allows changes to questions and answers independently. Additionally, if they are separate, you could add a language field to each table and have a multi-lingual quiz

Short answer:
You can JOIN on any columns or expressions. There is no "requirement" for a FOREIGN KEY, PRIMARY KEY, UNIQUE, or anything else.
Long answer:
However,... For performance (in large tables), some things make a difference.
If you are JOINing to a PK, Unique key, or even an indexed column, the query cold run faster.
Why have a FOREIGN KEY? An FK is two things:
A "constraint" that says that the value must exist in the other table. Also, with things like ON DELETE CASCADE, it can provide actions to take if the indicated row is removed. The constraint requires looking in the other table each time a write occurs (eg INSERT).
An Index. That is, specifying a FK automatically adds an INDEX (if not already present) to make the constraint faster.
Getting the id
Here is the "usual" way to do a pair of inserts, where you need the second to 'point' to the first:
INSERT INTO t1 ... -- with an AUTO_INCREMENT id
grab LAST_INSERT_ID() -- that id
INSERT INTO t2 ... -- and include the id from above
For AUTO_INCREMENT to work it must be the first column of some key. (Note: a PRIMARY KEY is a UNIQUE is a key (aka INDEX).)
Optionally you can specify a FK on the second table to point out the connection between the tables.
And, as spelled out in other answers, a FK could involve more than one column.
Entities and Relations
Sometimes, a set of tables like yours is best 'designed' this way:
Determine the "entities": users, tests, questions, answers
Relations and whether they are 1:1, 1:many, or many:many... Users:test is many-to-many; tests:questions is 1:many (unless you want questions to be shared between tests).
Answers is more complex since each 1 answer depends on the user and question.
1:1 -- rarely practical; may as well merge the tables together.
1:many -- a link (FK?) in one table to the other.
many:many -- need a bridge table with (usually) 2 columns, namely ids linking to the two tables.

Related

Multiple column key or multiple column unique [duplicate]

Here's what's confusing me. I often have composite primary keys in database tables. The bad side of that approach is that I have pretty extra work when I delete or edit entries. However, I feel that this approach is in the spirit of database design.
On the other side, there are friends of mine, who never use composite keys, but rather introduce another 'id' column in a table, and all other keys are just FKs. They have much less work while coding delete and edit procedures. However, I do not know how they preserve uniqueness of data entries.
For example:
Way 1
create table ProxUsingDept (
fkProx int references Prox(ProxID) NOT NULL,
fkDept int references Department(DeptID) NOT NULL,
Value int,
PRIMARY KEY(fkProx,fkDept)
)
Way 2
create table ProxUsingDept (
ID int NOT NULL IDENTITY PRIMARY KEY
fkProx int references Prox(ProxID) NOT NULL,
fkDept int references Department(DeptID) NOT NULL,
Value int
)
Which way is better? What are the bad sides of using the 2nd approach? Any suggestions?
I personally prefer your 2nd approach (and would use it almost 100% of the time) - introduce a surrogate ID field.
Why?
makes life a lot easier for any tables referencing your table - the JOIN conditions are much simpler with just a single ID column (rather than 2, 3, or even more columns that you need to join on, all the time)
makes life a lot easier since any table referencing your table only needs to carry a single ID as foreign key field - not several columns from your compound key
makes life a lot easier since the database can handle the creation of unique ID column (using INT IDENTITY)
However, I do not know how they
preserve uniqueness of data entries.
Very simple: put a UNIQUE INDEX on the compound columns that you would otherwise use as your primary key!
CREATE UNIQUE INDEX UIX_WhateverNameYouWant
ON dbo.ProxUsingDept(fkProx, fkDept)
Now, your table guarantees there will never be a duplicate pair of (fkProx, fkDept) in your table - problem solved!
You ask the following questions:
However, I do not know how they
preserve uniqueness of data entries.
Uniqueness can be preserved by declaring a separate composite UNIQUE index on columns that would otherwise form the natural primary key.
Which way is better?
Different people have different opinions, sometimes strongly held. I think you will find that more people use surrogate integer keys (not that that makes it the "right" solution).
What are the bad sides of using the
2nd approach?
Here are some of the disadvantages to using a surrogate key:
You require an additional index to maintain the unique-ness of the natural primary key.
You sometimes require additional JOINs to when selecting data to get the results you want (this happens when you could satisfy the requirements of the query using only the columns in the composite natural key; in this case you can use the foreign key columns rather than JOINing back to the original table).
There are cases like M:N join tables where composite keys make most sense (and if the nature or the M:N link changes, you'll have to rework this table anyway).
I know it is a very long time since this post was made. But I had to come across a similar situation regarding the composite key so I am posting my thoughts.
Let's say we have two tables T1 and T2.
T1 has the columns C1 and C2.
T2 has the columns C1, C2 and C3
C1 and C2 are the composite primary keys for the table T1 and foreign keys for the table T2.
Let's assume we used a surrogate key for the Table T1 (T1_ID) and used that as a Foreign Key in table T2, if the values of C1 and C2 of the Table T1 changes, it is additional work to enforce the referential ingegrity constraint on the table T2 as we are looking only at the surrogate key from Table T1 whose value didn't change in Table T1. This could be one issue with second approach.

Two Primary Keys

here is the pictorial representation of my partial database. BrandNo is a primary key in Suppliar Table, that is being used as Foreign Key in others.
In LotDetails Table I need BrandName as Foreign Key. This sounds absurd as i can make either
a Single Primary Key OR
a Composite Key
that will be used as Foreign Key.
I know that I can use BrandNo as Foreign Key and Display BrandName, but for the sake of KNOWLEDGE (and yes EASE ofcourse) i want to know that
Is it possible to use two attributes of a table as Foreign Keys separately in different Tables?
EDITTED
BrandNo is just a Serial Number and Brand Name can be the Name of any Brand.
BrandNo is needed in 4 Tables as shown, whereas BrandName is needed in only one table.
Thanks!
Yes! A FK don't need to reference a PK, you even don't need to reference a indexed column but for the sake of relational integrity (and sanity) you must reference a unique valued column (thus is why we "like" to reference a PK or at least a unique non clustered indexed column).
It's sound a bit weird but you can build a relational tableAB holding IdA, IdB and tableA and tableB referencing tableAB respective columns.
btw: a table don't need to own a PK but cannot exist two PK. In general the table is physical ordered by the PK.
Yes that's quite possible. Assuming BrandName is a candidate key on its own then in principle you can reference it in just the same way as BrandNo. In that case BrandName and BrandNo would not be a composite key, they would both be separate candidate keys.
By convention and for simplicity and ease of use it is usual to choose just one key per table to be used for foreign key references. Usually (not always) that is the one designated as "primary" key but it doesn't have to be so if you find a good reason to do otherwise.
When you create foreign key references, the key in the referenced table should be a primary key. It doesn't make sense to have a "partial" reference.
Instead, you should have a Brands table that has a primary key (perhaps BrandId, perhaps BrandName -- I prefer the former). Then tables that need information about a brand can directly reference this table.

What are keys used for in MySQL? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
mySQL's KEY keyword?
Like
PRIMARY KEY (ID),
KEY name (name),
KEY desc (desc),
etc.
what are they useful for?
Keys are used to enforce referential integrity in your database.
A primary key is, as its name suggests, the primary identification of a given row in your table. That is, each row's primary key will uniquely identify that row.
A unique key is a key that enforces uniqueness on that set of columns. It is similar to a primary key in that it will also uniquely identify a row in a table. However, there is the added benefit of allowing NULL in some of those combinations. There can only be 1 primary key, but you can have many unique keys.
A foreign key is used to enforce a relationship between 2 tables (think parent/child table). That way, a child table can not have a value of X in its parent column unless X actually appears in the parent table. This prevents orphaned records from appearing.
The primary key constraint ensures that the column(s) are:
not null
unique (unique sets if more than one column)
KEY is MySQL's terminology in CREATE TABLE statements for an index. Indexes are not ANSI currently, but all databases use indexes to speed up data retrieval (at the cost of insertion/update/deletion, because of maintenance to keep the index relevant).
There are other key constraints:
unique
foreign key (for referential integrity)
...but your question doesn't include examples of them.
keys are also called indexes. They are used for speeding up queries. Additionally keys can be constrains (unique key and foreign key). The primary key is also unique key and it identifies the records. The record can have other unique keys as well, that do not allow to duplicate a value in a given column. Foreign key enforces referential integrity (#Derek Kromm already wrote excellent description). The ordinary key is used only for speeding up queries. You need to index the columns used in the WHERE clause of the queries. If you have no index on the column, MySQL will need to read the whole table to find the records you need. When index is used, MySQL reads only the index (which is usually a B+ tree) and then read only those record from the table it found in the index.
Primary KEY is for creating unique/not null constraint for each row in the table. Also searching by this key is the fastest. You can create only one PK in the table.
Ordinary key/index is key for speeding your searching by this column, sorting, grouping and joining with other table by this key.
Indexes drawback:
Adding new indexes to table will influence on speed or running insert/update/delete statements. So you should select columns for indexing in your table very carefully.
Key are used for relation purposes between tables and you are able to create joins in order to select data from multiple tables
What, you didn't fine the wikipedia entry comprehensive? ;-)
So, a key, in a relational database (such as MySQL, PostgreSQL, Oracle, etc) is a data constraint on a column or set of columns. The most common keys are the Primary key and foreign keys and unique keys.
A foreign key specifically relates the data of one table to data in another table. You might see that a table blog_posts has a foreign key to users based on a user_id column. This means that every user_id in blog_posts will have a corresponding entry in the users column (this is a one-to-many relationship -- a topic for another time).
If a column (or group of columns) has a unique key, that means that there can only be one such incidence of the key in the table. Often you'll see things like email addresses be unique keys -- you only want one email address per user. I've also seen a combination of columns match to a unique key -- the five columns, first_name, last_name, address, city, and state, will often be a unique key -- realistically, there can only be one William Gates at 1835 73rd Ave NE, Medina, Washington. (I do realize that it is possible for a William Gates Jr. to be born, but the designers of that database didn't really care).
The primary key is the primary, unique identifier of a given table. By definition it is a unique key. It is something which cannot be null and must be unique. It holds a special place of prominence among the indexes of a given table.

RDBMS best practices - autoid for association table?

I have two tables, let's say they are called table A and table B. An item from table B can be present in multiple instances of A, and each A can contain multiple Bs so I have a table called a_b which links them together by their primary keys. My question is when I define this association table, should I have a primary key on the association table? Or is it not needed? Just trying to avoid ending up on TDWTF, that's all :)
The primary key would be on the table A PK column and table B PK column in your association table. That way, you ensure you don't get any duplicate rows in your association table by accident.
One of the main purposes of primary keys is to guarantee referential integrity. That is, keep the data in your table clean, with no duplicates. The PK in this case will ensure you never have 2 duplicate rows in the association table.
I think you might want to use a primary key in order to show your intent. If for example you do not want
a, b
a, b
Then a primary key defined on A.a and B.b would make that more clear. If you don't care, but you have a,b and other fields, then adding a surrogate key as your primary key might help in giving you a uniform way to delete a row that you do not want. Otherwise you will have to delete where a=a and b=b and ?? then pick some field value from the row you want deleted. Whereas with a surrogate key you can just pick the row and say delete where mykey = 36 or something...
But really it depends on the business case. Many intersect tables have some kind of date range, or additional fields related to the relationship in addition to the keys of the two tables. Defining a primary key on the existing columns, a new surrogate key, some unique indexes, some constraints, or even having no indexes could all be valid courses of action depending upon your needs.
I would say definitely do whatever makes your intentions the most clear.
Not needed. Both keys should form the primary key of your association table. If you're going to be doing bidirectional navigation, consider adding an index with the keys reversed.
The primary key is needed always.
However, I'd say it depends what should it be. If you are going to use some sort of ORM systems (e.g. Hibernate) then it is best to have a surrogate identifier, while those two foreign keys (pointing to tables A and B) should form a unique index.
Also, if there would ever be a need to reference such a relationship from another table then this surrogate identifier would be really handy.

What is the difference between an Index and a Foreign Key?

I want to create a database with 3 tables. One for posts and one for tags and one that links posts to tags with the post_id and tag_id functioning as foreign key references.
Can you explain what an Index would be in this scenario and how it differs from a Foreign Key and how that impacts my database design?
an index on a table is a data structure that makes random access to the rows fast and efficient. It helps to optimize the internal organization of a table as well.
A foreign key is simply a pointer to a corresponding column in another table that forms a referential constraint between the two tables.
An index is added as a fast look up for data in the table.
An index can have constraints, in that the column or columns that are used to make the index might have to be unique (unique: only one row in the database is returned for that index, or non-unique: multiple rows can be returned). The primary key for the table is a unique index, and usually only has one column.
A foreign key is a value in a table that references a unique index in another table. It is used as a way to relate to tables together. For example, a child table can look up the one parent row via its column that is a unique index in the parent table.
You'll have foreign keys in the third table. Indexes are not necessary, you need them if you have lots of data where you want to find something by Id quickly. Maybe you'll want an index on posts primary key, but DBMS will probably create it automatically.
Index is a redundant data structure which speeds up some queries.
Foreign key, for practical matters, is a way to make sure that you have no invalid pointers between the rows in your tables (in your case, from the relationship table to posts and tags)
Question: Can you explain what an Index would be in this scenario and how it differs from a Foreign Key and how that impacts my database design?
Your foreign keys in this case are the two columns in your Posts_Tags table. With a foreign key, Each foreign key column must contain a value from the main table it is referencing. In this case, the Posts and Tags tables.
Posts_Tags->PostID must be a value contained in Posts->PostID
Posts_Tags->TagID must be a value contained in Tags->TagID
Think of an index as a column that has been given increased speed and efficiency for querying/searching values from it, at the cost of increased size of your database. Generally, primary keys are indexes, and other columns that require querying/searching on your website, in your case, probably the name of a post (Posts->PostName)
In your case, indexes will have little impact on your design (they are nice to have for speed and efficiency), but your foreign keys are very important to avoid data corruption (having values in them that don't match a post and/or tag).
You describe a very common database construct; it's called a "many-to-many relation".
Indexes shouldn't impact this schema at all. In fact, indexes shouldn't impact any schema. Indexes are a trade-off between space and time: indexes specify that you're willing to use extra storage space, in exchange for faster searches through the database.
Wikipedia has an excellent article about what database indexes are: Index (database)
To use foreign keys in mysql, you need to create indexes on both tables. For example, if you want the field a_id on table b to reference the id field on the table a, you have to create indexes on both a.id and b.a_id before you can create the reference.
Update: here you can read more about it: http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html