Is it advisable to have table A having two foreign keys from table B? My thinking is that if one of the foreign key in table A is a primary key, then there is no need to add additional foreign key in table A.
I could see it possibly being valid. If table B has a foreign key to A's Primary key, you are saying every B must point to some A. but you could also have a foreign key to a nullable field in A, meaning A must exist and have data for the second field in your key.
Related
As far as I'm aware, you can only assign primary keys and unique columns to foreign keys... yet I have a table that has a primary key between two columns:
alter table NAME add constraint PK primary key(VALUE1, VALUE2)
I'm trying to make Value1 a foreign key in another table, but it's not recognizing it as a primary key or unique - obviously because the primary key is shared between two values... So what do I do from here? I'm pretty new to SQL syntax...
You are correct that you can only assign primary keys and unique columns to foreign keys. I am not much aware of the business requirement here but ideally, you should be having a third table which has the VALUE1 as a primary key. If not you should create one.
The main idea is that you can't link a foreign key to a value that can hold duplicates on the referenced table. So if your main table has a compound key (more than 1 column), linking the foreign key to one (or many but not all) of it's columns would be linking the table to more than one row (since that column might have duplicates by itself).
If you really need to establish the link between the two then you have a problem, either:
Your primary key isn't really 2 or more columns. You can read about normalizing your database (in standard normal forms) to solve this.
Your relationship between the tables isn't 1 to N (it's N to M). You can't add a foreign key, you will have to create a 3rd table with both primary keys to link them.
In this database, key1 & key2 make up the composite primary key of table4, but i'm able to add a foreign key to table3 that comprise just key1.
Why MySQL allows this? Does the above database design make no sense at all?
This answer takes the question's "add a foreign key to table3" to mean that a FK (foreign key) was added in table3 referencing one of the columns of the composite PK (primary key) of table4. In standard SQL a FK can reference a proper/smaller subset of a PK.
This other answer presumably takes "add a foreign key to table3" to mean that a FK was added in table4 with one of the columns of the PK referencing table3. A FK column set in a table is independent of any PK or UNIQUE declarations in it.
In standard SQL a FK can reference a proper/smaller subset of a PK.
The referenced column list must be declared PRIMARY KEY or UNIQUE. (PRIMARY KEY creates a UNIQUE NOT NULL constraint.) (The constraint has to be explicit, even though any set of NOT NULL columns containing a set that is UNIQUE has to be unique.)
Unfortunately MySQL lets you declare a FK referencing a column list that is not UNIQUE. Even though such a FK or one referencing non-NULL columns (OK in standard SQL) is not implemented properly, and the documentation itself advises not doing it:
The handling of foreign key references to non-unique 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 keys that are both UNIQUE (or PRIMARY) and NOT NULL.
(You can ponder just what are and are not the well-defined operations, since the documentation doesn't actually clarify.)
1.8.2.3 Foreign Key Differences
13.1.18 CREATE TABLE Syntax
13.1.18.6 Using FOREIGN KEY Constraints
PS Re relational vs SQL
In the relational model a FK references a CK (candidate key). A superkey is a unique column set. A CK is a superkey containing no smaller superkey. One CK can be called the PK (primary key). When a column set's values must appear elsewhere we say there is an IND (inclusion dependency). A FK is an IND to a CK. When an IND is to a superkey we could call that a "foreign superkey".
An SQL PK or UNIQUE NOT NULL declares a superkey. It is a CK when it does not contain a smaller column set declared as SQL PK or UNIQUE NOT NULL. SQL FK declares a foreign superkey. So an SQL PK might actually be a relational PK (hence CK) and a UNIQUE NOT NULL might actually be a CK. An SQL FK to one of these actually is a relational FK.
Foreign keys are not dependent of primary keys at all. In fact, they have nothing to do with primary keys.
A primary keys single purpose is to identify a row uniquely.
A foreign keys purpose is to make sure that for each entry in the referencing table (the child table) there must be an entry in the referenced table (the parent table). It's only a technical requirement in MySQL that there must be an index (not necessarily a primary key or a unique key, a simple index suffices) on the referenced column.
Therefore your design makes sense, yes.
Suppose I have two tables in mysql
1.Child(name,father_name)
2.Father(name,contact)
The table Father has a composite key (name,contact).Father_name in Child table references name in father . Thus a foreign key references a part of primary key.This is allowed by mysql.
However consider the following situation:
Table father has the following tuples:
(kishan,9906011111)
(kishan,9990601234)
Now suppose I insert a row in child
(xyz,kishan)
How would I know which kishan in the father table is the child xyz related to ?
This situation could have been avoided if mysql does not allow a foreign key to refer a part of the primary key .
Please answer what's the benefit of this scheme allowed by mysql ?
This is a peculiarity of MySQL. In my opinion, foreign keys should only be to unique keys or primary keys. There should not be a mapping to "sets" of values using a foreign key relationship.
Clearly, the designers of MySQL disagree (both with me and other database implementors). They allow foreign key relationships to any columns that are indexed -- in MySQL parlance, are defined as a "key". If you have a composite primary key, then the initial column(s) are such a key.
To prevent problems and make your tables unambiguous and easy to use, I would recommend:
All tables have an auto-incremented primary key.
All foreign key relationships are only to primary keys (not to unique keys or other types of key).
The primary key be named the singular of the entity followed by id (example: things would have thingId as a primary key).
The foreign key have the same name as the primary key (except when this is not possible because there are multiple foreign key relationships to the same table).
Let's say table B is dependent on table A.
Table B has a unique primary key B.B_ID and a foreign key B.A_ID
which references the parent table A's primary key.
Since B has a unique key, is B.A_ID, the foreign key, a non key (non-key)
in B?
Thank you.
In the context of discussing the 2nd normal form, "non-key columns" are all the columns that are not part of a candidate key.
You may certainly have foreign key columns in a table that are not part of that table's primary key.
Suppose you have a table Person that has a primary key PersonName because that is the column you use to identify each person uniquely.
You can also have a column in that table such as CountryOfCitizenship that is a foreign key referencing another table Country. This foreign key column is not part of the primary key in the Person table; it is not the way we identify each row in that table.
Re your comment:
The second normal form requires that non-key columns have a functional dependency on the whole primary key. This is different from first normal form only if your primary key has multiple columns.
Functional dependency means that the attribute column unambiguously relates to the primary key, and therefore the value in the attribute column belongs on the same row with that primary key.
So if a column like CountryOfCitizenship always contains the country name that is the country of citizenship for the person who is named in that same row's primary key, then the attribute satisfies 1NF and since the table has a single-column primary key, it's automatically in 2NF as well.
In MySQL terminology, "key" usually refers to an explicit key which has an index on it. If you use this definition, then a primary key is a key. And a unique key is a key. And an index key is a key. But a foreign key is not necessarily a key.
When you declare a foreign key constraint, MySQL does not necessarily build an index on the referring table (it does in innodb). Of course, you can declare the foreign key to also be a key and guarantee that an index is built.
A FOREIGN KEY constraint does not have to be linked only to a PRIMARY KEY constraint in another table; it can also be defined to reference the columns of a UNIQUE constraint in another table.
You can find more information here https://stackoverflow.com/a/18435114/7667467
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.