Combining Foreign Keys - mysql

In MySQL, how do you combine 2 foreign keys in a table to become a primary key?
I have two tables, one Staff, one Roles, each containing their own primary keys, StaffID and RoleID. I have created a third table called StaffRole which will contain the StaffID and RoleID, keeping in mind this is a one to many relationship, as a staff member may have 1 or more roles.
How would you combine the foreign key of StaffID and RoleID to create a new unique primary keys for the table StaffRole.

Technically, what you are describing is not a one-to-many relationship, but instead it is a many-to-many relationship since one Staff record relates to many Role records, but one Role record also relates to many different Staff. Your use of the join table StaffRole is the typical way of handling the relationship.
This is semantics, but it isn't really a matter of combining the two foreign keys, so much as just creating a third key which is the composite of the two and also the primary key. So your table will have two FOREIGN KEY definitions, one each for the two columns, and one composite PRIMARY KEY definition across both of the columns.
CREATE TABLE StaffRole (
StaffID INT NOT NULL,
RoleID INT NOT NULL,
/* Composite primary key on both columns */
PRIMARY KEY (StaffID, RoleID),
/* Two separate foreign keys */
FOREIGN KEY (StaffID) REFERENCES Staff (StaffID),
FOREIGN KEY (RoleID) REFERENCES Roles (RoleID)
) ENGINE=InnoDB;
Note, I have specified InnoDB as the table type, since MySQL will not enforce the FOREIGN KEYs on MyISAM tables.

You can create a StaffRoleID as a primary key, and use StaffID and RoleID as foreign keys.

Related

Primary Key/Foreign Key for a table with two junction tables

Lets say I have table A with two junction tables B and C, how would I go about creating primary keys for table A? I have two of these types of table in a diagram I drew, the circle keys are foreign keys btw.
Image with junction tables
Your games table needs only one primary key: this identifies each specific game. In the junction tables, the primary keys are composed of the game primary key and the directors (or types) primary key.
Taken from the reference in the tutorial MySQL Primary Key:
CREATE TABLE roles(
role_id INT AUTO_INCREMENT,
role_name VARCHAR(50),
PRIMARY KEY(role_id)
);
It is difficult to provide information about your specific question because there is too little details in it.
From your comment "if a table has two junction tables attached to it, would it need to have two primary keys?". No.
A primary key is actually a logical concept (a design mechanism) used to define a logical model. A primary key is a set of attributes (columns) that together uniquely identify each end every Tuple (row) in a relation (table). One of the rules of a primary key is that there is only one per relation.
The logical model is used, as mentioned, as the design to create the physical model, relations become tables, attributes become columns, Primary keys may become unique indexes. Foreign Keys may become indexes in the related table and so on.
Many RDBMS's allow the specification of a PRIMARY KEY in a physical table definition. Most also allow definition of FOREIGN KEYs on a physical table also. What they do with them may vary from one implementation to another. Many use the definition of a PRIMARY KEY to define a UNIQUE INDEX of some sort to enforce the "must uniquely identify" each and every record in the table.
So, No, your games_directors table does not need, nor can it have, two primary keys. if you did choose to specify a PRIMARY KEY, you would need to specify all the columns that uniquely identify records in the games_directors table - most likely PRIMARY KEY (game_id, director_id).
Similarly, the PRIMARY KEY for the games table would likely be PRIMARY KEY (game_id), for the directors would likely be PRIMARY KEY (director_id) and for game types it would likely be PRIMARY KEY (game_type_id).
You might use a foreign key from your games_directors table to ensure that when records are added to it that the corresponding director exists in the games table and the directors table. In this case, your games_directors table will have two foreign key relationships (one to games and another to directors). But only one PRIMARY KEY.
So you might end up with something like this:
create table games (
game_id integer,
PRIMARY KEY (game_id)
);
create table directors (
director_id integer,
PRIMARY KEY (director_id)
);
CREATE TABLE games_directors (
game_id INTEGER NOT NULL,
director_id INTEGER NOT NULL,
commission_paid DECIMAL(10,2),
PRIMARY KEY (game_id, director_id),
FOREIGN KEY (game_id) REFERENCES games(game_id),
FOREIGN KEY (director_id) REFERENCES directors(director_id)
);
NB: I didn't tested the above using PostgreSql. The syntax should work for most RDBMS's, but some may require tweaking slightly.
Indexes can be used to speed up access to individual records within table. For example, you might want to create an index on director name or director id (depending upon how you most frequenytly access that table). If you mostly access the director table with an equality condition like this : where director_name = 'fred' then an index on director_name might make sense.
Indexes become more useful as the number of records in the tables grows.
I hope this answers your question. :-)

In M:N database relationship it's better to reference by a composite PK or two foreign keys

I have a database that involves a table called U and a table called P .
table U
U_Id primary key.
table P
P_Id primary key
There is many to many relationship between the two tables.
I have two ways to create relationship between the two table:
1) create a new table that contains a composite Primary Key (U_Id,P_Id)
2) create a new table that contains references from U table and P table as foreign keys.
(U_id and P_id as foreign keys )
Third_Table
U_id FK not null
P_Id FK not null
What the better option?
Options 1 and 2 aren't opposed. Your relationship table will contain U_Id and P_Id as foreign keys, and the combination of these two columns should at least be marked as a unique key, if not a primary key.
Some DB designers prefer to introduce a surrogate identifier as primary key. Others (including myself) prefer to use the combination of foreign keys as the primary key.
2) create a new table that contains references from U table and P table as foreign keys.
That you need for referential integrity, else the 3rd table could have values that do not refer to anything. (Hurrah for many-to-nothing rows!)
1) create a new table that contains a composite Primary Key (U_Id,P_Id)
If you don't do that, what will be the primary key to the 3rd table? It will have one, right?
A primary key is one form of unique constraint. If a table has more than one unique constraint, the choice of which one to call the primary key is arbitrary. In your case, though, there's only one.
You need some kind of unique constraint on the 3rd table to prevent duplicate rows. Primary Key (U_Id,P_Id) says than any {U_Id,P_Id} pair is unique, and identifies that relationship. From what you say, that's what you want.
I would expect a composite key consisting of two foreign keys. Example code (untested):
CREATE TABLE Q
(u_id INT NOT NULL FOREIGN KEY REFERENCES U (u_id),
p_id INT NOT NULL FOREIGN KEY REFERENCES P (u_id),
PRIMARY KEY (u_id, pi_id));

Use of Primary Key as Foreign Key in Foreign Key Table

This may sound confusing and or simple but..
If I use a foreign key from Table B in Table A, which has a separate primary key. Do I need to include Table A's primary key as a foreign key in Table B?
Thanks!
========================================================================
EDIT:
Okay, let me try and clarify my question a bit.
In the case above, should I use Taco_ID as a FK in Table 2? Or is does it completely unnecessary?
In general, you don't usually make foreign keys bidirectionally like that. If you do, it means that the two tables exist in a 1-to-1 relationship: Each taco has a type, and each taco type can only be used by one taco. If you have a relationship like this, there's not really any reason to have them in separate tables, they could just be additional columns in the same table.
Normally foreign keys are used for 1-to-many or many-to-many relationships.
A 1-to-many relationship would be if many different tacos can be of the same type. They each have Taco_Type_ID foreign key.
For a many-to-many relationship, you typically use a separate relation table.
CREATE TABLE Taco_Types (
Taco_ID INT, -- FK to Table1.Taco_ID
Taco_Type_ID INT, -- FK to Table2.Taco_Type_ID
PRIMARY KEY (Taco_ID, Taco_Type_ID)
);
foreign keys and primary keys are SOMETIMES related, but not always. A foreign key in a table literally just means "whatever value is in this field MUST exist in this other table over ---> here". Whether that value is a PK or not in that other table is irrelevant - it just has to exist, and it has to be unique. That may fit the bill of being a primary key, but being primary is NOT required.
You can have composite foreign keys, e.g. in a (silly) address book, the child table you list a person's phone numbers in COULD be keyed with (firstname, lastname), but that runs into the problem of "ok, which John Smith does this number belong to?".
In most databases, foreign key references must be to primary keys or unique keys (and NULLs are allowed). MySQL recommends this but does not require it:
However, the system does not enforce a
requirement that the referenced columns be UNIQUE or be declared NOT
NULL. The handling of foreign key references to nonunique keys or keys
that contain NULL values is not well defined for operations such as
UPDATE or DELETE CASCADE. You are advised to use foreign keys that
reference only UNIQUE (including PRIMARY) and NOT NULL keys.
Do you need to reference primary keys for a foreign key relationship? First, you don't even need to declare foreign key relationships. I think they are important because they allow the database to maintain referential integrity. But, they are not required. Nor is there any semantic difference in queries, based on the presence of foreign keys (for instance, NATURAL JOIN does not use them). The optimize can make use of the declared relationship.
Second, if you are going to declare the foreign key, I would recommend using the primary key of the referenced table. That is, after all, one of the major reasons for having primary keys.

Two primary non composite keys in a table

I am working on a project and I realized I am unsure about how to use multiple primary keys. I have a table named "User_Details" that has the details of Customer ID, email address and password. From my understanding, I can use both Customer ID and email address as the primary key. In this case do I use only one as Primary Key or both? If I use both, do they become composite primary keys?
(PS. I have other tables, where the foreign key is the customer ID)
You can only have one primary key, but you could definitely have other unique fields.
Usually using an integer / id as primary key is preferred over a string key, and an id is presumably auto assigned, where as email could change - which would be a problem for foreign key relations.
Since you already use customer Id as a foreign key in other tables, I would suggest you continue to do that.
You can only have one primary key, but you can have multiple columns in your primary key, alternatively you can also have Unique Indexes on your table, which will work a bit like a primary key in that they will enforce unique values, and will speed up querying of those values.
Easiest way tho is a Composite Primary Key which is a primary key made from two or more columns. For example:
CREATE TABLE userdata (
userid INT,
userdataid INT,
info char(200),
primary key (userid, userdataid),
);
Here is more info: Link
You can have a Composite Primary Key which is a primary key made from two or more columns. For example:
CREATE TABLE userdata (
userid INT,
userdataid INT,
info char(200),
primary key (userid, userdataid),
);
A table can have multiple candidate keys. Each candidate key is a column or set of columns that are UNIQUE, taken together, and also NOT NULL. Thus, specifying values for all the columns of any candidate key is enough to determine that there is one row that meets the criteria, or no rows at all.
Candidate keys are a fundamental concept in the relational data model.
It's common practice, if multiple keys are present in one table, to designate one of the candidate keys as the primary key. It's also common practice to cause any foreign keys to the table to reference the primary key, rather than any other candidate key.
I recommend these practices, but there is nothing in the relational model that requires selecting a primary key among the candidate keys.

Non-unique foreign key

Do foreign keys have to be unique?
I'm trying to create a table that stores the foreign key that references to a user and a column 'profileIconId'. The purpose of the table is to have a list of icons that the user owns. I would like to use cascade delete.
My other choice is to use SELECT FROM WHERE to retrieve the list and use DELETE FROM WHERE to delete all rows that matches the key when the user is removed.
No, they don't. In fact, one of the most common uses of a foreign key is a one-to-many relationship, such as between Customers and Orders, for example.
No, Foreign Key in a table doesn't have to be unique in said table.
BUT, as it is the Primary Key of another table, it must be unique in this table.
No.
But the values must exists first on the parent table before you can insert it on the table.
No, foreign keys do not have to be unique. Indeed, a lack of uniqueness is requisite for one-to-many or many-to-many relations.
Foreign key(s) must reference a unique set of attributes in the referenced table. So, your foreign keys: user and profileIconId don't need to be unique, but what they reference does.
Consider the following schema:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
... omitted ...
);
CREATE TABLE icons (
id INTEGER PRIMARY KEY,
... omitted ...
);
CREATE TABLE user_icons (
user INTEGER REFERENCES users,
profileIconId INTEGER REFERENCES icons
);
The user and profileIconId values do not need to be unique in the user_icons table, but id in users and icons must be unique (or technically a candidate primary key).
Note, the referenced columns in this case must be unique to qualify as Primary Keys.
This would be an acceptable way to accomplish the goal of creating a table that fulfills the user has zero or many icons relationship.