Non-unique foreign key - mysql

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.

Related

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.

How to specify a foreign key in mysql

I have created 3 tables in a music tracks database
Track ( id, album, genre)
Album( id, title)
Contributed ( artist, track, role)
I have chosen Id as primary keys for the first table, ( I'd, album) for the second table.
Do I need a primary key in my third table? What is my foreign key? How do I specify my foreign key?What are the unique identifiers in my third table?
I tried to populate it using tracks as foreign key( referenced to Track table, id column) but it gives me error.
Can anyone help?
For the third table, we can have two foreign keys:
Referencing to artist table (assuming we have an artist table with id and name).
Referencing to track table.
Syntax for foreign key should look like this (in create table script):
CONSTRAINT fk_contributed_track FOREIGN KEY
REFERENCS track(id)
Here is an example of a create table script with foreign key.
As far as primary key is concerned, it depends on business rules (i.e. whether one artist can have multiple roles for a track). However, for simple design, I would recommend having a numeric auto increment primary key.

Is it safe to add foreign key constraint on two columns, while one is not unique (MySQL)?

I have a users table and other tables such as services, orders, etc... that are I would like to turn into child tables of the users table.
So far it's simple, I just add Foreign Key Constraint between users(id) and orders(user_id). But what if I'd like to add a Boolean users(disabled) field, that would cascade the update to the orders(disabled) and services(disabled) fields in the rows that reference the respective row in users via (user_id) key?
Would it work if I create a reference in the child table to the parent table using 2 keys, one primary and one non unique?
You could have probably answered your question yourself if you'd have tried it. Basically, you can't create a foreign key relation on columns that are not part of a primary key on the foreign table (as the name implies).
So, unless the disabled column is part of the primary key on the users table, then, no, you won't be able to create a foreign key relation in another table that would include the disabled column.
All is not lost though. You could use triggers to trigger the disabling of orders and services when a user becomes disabled.

Is it necessary that the Foreign key of some table should be the candidate key of the same table?

Foreign key should necessarily be a candidate key for a table (say table1)? I know that Foreign key references primary key of some other table (say table2). But for the table1, is it necessary that it should be candidate key?
By definition a foreign key is required to reference a candidate key in the target table (table2 in your question). A foreign key does not have to be a candidate key in the referencing table or be part of a candidate key in that table.
No. You can have a 1:N relationship, the FK requirement just says that the field has to exist in the other table. Whether that field is unique or not, does not matter.
For reference:
a candidate key is an alternative to a PK, it can be one field or the combination of fields (as in a concatenated key)
all this establishes is that there is more than one way to uniquely identify a record of the table
a good alternative to an employee_id might be ssn (social security number)
a concatenated key is multiple fields that make up the uniqueness of a record, which can either be an alternative to a PK, or together, act as the PK
because RDBMSs follow at least 1NF, all the fields of the table could be used as the concatentated key
Note: this is a bad choice and only serves as an example
think of an employee_id field as the one PK of the table, but the combination of firstname,lastname, and startdate would probably uniquely identify everyone on your employees table
Note: this is an example, there would probably be better alternatives to this in practice

Does a Join table (association table) have a primary key ? many to many relationship

Does a Join table (association table) have a primary key ? many to many relationship. I've seen some Join tables with a primary key and some without can someone please explain when you would have a primary key in a join table and why?
Thank you in advance;-)
In a pure 'join' or junction table all the fields will be part of the primary key. For example let's consider the following tables:
CREATE TABLE USERS
(ID_USER NUMBER PRIMARY KEY,
FIRST_NAME VARCHAR2(32),
LAST_NAME VARCHAR2(32));
CREATE TABLE ATTRIBUTES
(ID_ATTRIBUTE NUMBER PRIMARY KEY,
ATTRIBUTE_NAME VARCHAR2(64));
A junction table between these to allow many users to have many attributes would be
CREATE TABLE USER_ATTRIBUTES
(ID_USER NUMBER REFERENCES USERS(ID_USER),
ID_ATTRIBUTE NUMBER REFERENCES ATTRIBUTES(ID_ATTRIBUTE),
PRIMARY KEY(ID_USER, ID_ATTRIBUTE));
Sometimes you'll find the need to add a non-primary column to a junction table but I find this is relatively rare.
Share and enjoy.
All tables should have a primary key. :-)
You can either use a compound foreign key, or a blind integer key.
You would use the compound foreign key when there are no other elements in your association table.
You could use the blind integer key when the association table has elements of its own. The compound foreign key would be defined with two additional indexes.
It depends on the records you are associating. You can create a composite primary key on the id's of the associated records as long as you don't need multiple records per association.
However, its far more important that you make sure both these columns are indexed and have referential integrity defined.
Relationship tables frequently have three candidate keys, one of which need not be enforced with a constraint, and the choice of which key (if any) should be 'primary' is arbitrary.
Consider this example from Joe Celko:
CREATE TABLE Couples
(boy_name INTEGER NOT NULL UNIQUE -- nested key
REFERENCES Boys (boy_name),
girl_name INTEGER NOT NULL UNIQUE -- nested key,
REFERENCES Girls(girl_name),
PRIMARY KEY(boy_name, girl_name)); -- compound key
The "Couples" table lets you insert
these rows from the original set:
('Joe Celko', 'Brooke Shields')
('Alec Baldwin', 'Kim Bassinger')
Think about this table for a minute.
The PRIMARY KEY is now redundant. If
each boy appears only once in the
table and each girl appears only once
in the table, then each (boy_name,
girl_name) pair can appear only once.
From a theoretical viewpoint, I could
drop the compound key and make either
boy_name or girl_name the new primary
key, or I could just leave them as
candidate keys.
SQL products and theory do not always
match. Many products make the
assumption that the PRIMARY KEY is in
some way special in the data model and
will be the way to access the table
most of the time.
...HOWEVER I suspect you question is implying something more like, "Assuming I'm the kind of person who shuns natural keys in favour of artificial identifiers, should I add an artificial identifier to a table that is composed entirely of artificial identifiers referenced from other tables?"