So I understand how to create foreign keys and I know what is the purpose of the FK. But I have a problem in understanding How to use them. I asked a question regarding Foreign keys HERE(Click link)
Here is what I made:
CREATE TABLE user(
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(20) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE items(
i_id INT(11) NOT NULL AUTO_INCREMENT,
name TINYTEXT NOT NULL,
price DECIMAL(8,2) NOT NULL,
PRIMARY KEY (i_id)
);
CREATE TABLE user_purchase(
i_id INT(11) NOT NULL,
name TINYTEXT NOT NULL,
id INT(11) NOT NULL,
FOREIGN KEY (i_id) REFERENCES items(i_id),
FOREIGN KEY (name) REFERENCES items(name),
FOREIGN KEY (id) REFERENCES user(id)
);
Now my question is how do I make the most out of this using PHP? From the link above, people have suggested that it's good to use only one foreign key in the user_purchase table, but what if I want several columns? Why don't we use several foreign keys for different columns of the same table?
I am using mysql and php. I would appreciate it if you could show some examples of how you use PHP with the tables which have foreign keys to get get information using MYSQL commands. I really need a thorough explanation.
I also need to understand the terms Normalization and Denormalization. I would appreciate if you could give some links which explain these terms in great detail with examples or if you have any suggestion for some great books for beginners in database design, implementation, etc, I would really appreciate.
Thanks a lot.
So I understand how to create foreign keys and I know what is the purpose of the FK. But I have a problem in understanding How to use them.
Assuming you are referring to the foreign key constraints, the short answer would be you just don't use them.
And here comes the long one:
We are accustomed to refer to columns being foreign keys to other tables. Especially during the normalization process, phrases like "user_purchase.i_id
is a foreign key to the items
table" would be very common. While that's a perfectly valid way to describe the relationship, it can get a little fuzzy when we reach the implementation phase.
Suppose you have created your tables without the FOREIGN KEY
clauses:
CREATE TABLE user(
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(20) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE items(
i_id INT(11) NOT NULL AUTO_INCREMENT,
name TINYTEXT NOT NULL,
price DECIMAL(8,2) NOT NULL,
PRIMARY KEY (i_id)
);
CREATE TABLE user_purchase(
i_id INT(11) NOT NULL,
name TINYTEXT NOT NULL,
id INT(11) NOT NULL,
);
Notice that, relation-wise, the foreign key columns are still implemented. There's a column that references the user
table (id
) and another one that references the items
table (i_id
) -- let's put the name
column aside for a moment. Consider the following data:
user user_purchase items
| id username | | id i_id | | i_id name price |
| 23 john | | 55 10 | | 10 chocolate bar 3.42 |
| 55 mary | | 70 10 | | 33 mobile phone 82.11 |
| 70 fred | | 70 33 | | 54 toothpaste 8.67 |
| 55 10 | | 26 toy car 6.00 |
| 70 26 |
The relation is there. It is implemented by means of the user_purchase
table, which holds information as to who bought what. If we were to query the database for a relevant report, we would do:
select * from user_purchase p
join user u on (p.id=u.id)
join items i on (p.i_id=i.i_id)
And that's how we use the relation and the foreign key columns involved.
Now, what if we do:
insert into user_purchase (id,i_id) values (23,99)
Apparently, this is an invalid entry. Although there is a user with id=23
, there's no item with i_id=99
. The RDBMS would allow that to happen, because it doesn't know any better. Yet.
That's where foreign key constraints come into play. By specifying FOREIGN KEY (i_id) REFERENCES items(i_id)
in the user_purchase
table definition, we essentially give the RDBMS a rule to follow: entries with i_id
values that are not contained in the items.i_id
column are not acceptable. In other words, while a foreign key column implements the reference, a foreign key constraint enforces the referential integrity.
Note, however, that the above select
wouldn't change, just because you defined a FK constraint. Thus, you don't use FK constraints, the RDBMS does, in order to protect your data.
...what if I want several columns? Why don't we use several foreign keys for different columns of the same table?
Ask yourself: Why would you want that? If the two foreign keys are to serve the same purpose, the redundancy will eventually get you in trouble. Consider the following data:
user_purchase items
| id i_id name | | i_id name price |
| 55 10 chocolate bar | | 10 chocolate bar 3.42 |
| 70 10 chocolate bar | | 33 mobile phone 82.11 |
| 70 33 mobile phone | | 54 toothpaste 8.67 |
| 55 10 toothpaste | | 26 toy car 6.00 |
| 70 26 toy car |
What's wrong with this picture? Did user 55
buy two chocolate bars, or a chocolate bar and a toothpaste? This kind of ambiguity can lead to a lot of effort to keep data in-sync, which would be unnecessary if we just kept one of the foreign keys. In fact, why not drop the name
column altogether, since it is implied by the relation.
Of course, we could resolve this by implementing a composite foreign key, by setting PRIMARY KEY(i_id,name)
for the items
table (or defining an extra UNIQUE(i_id,name)
index, it doesn't realy matter) and then setting a FOREIGN KEY(i_id,name) REFERENCES items(i_id,name)
. This way, only (i_id,name) couples that exist in the items
table would be valid for user_purchases
. Apart from the fact that you would still have one foreign key, this approach is totally unnecessary, provided that the i_id
column is already enough to identify an item (can't say the same for the name
column...).
However, there's no rule against using multiple foreign keys to a table. In fact, there are circumstances that demand such an approach. Consider a person(id,name)
table and a parent(person,father,mother)
one, with the following data:
person parent
| id name | | person father mother |
| 14 John | | 21 14 59 |
| 43 Jane | | 14 76 43 |
| 21 Mike |
| 76 Frank |
| 59 Mary |
Obviously, all three columns of the parent
table are foreign keys to person
. Not for the same relation, though, but for three different ones: Since a person's parents are persons too, the two corresponding columns must reference the same table person
does. Note, however, that the three fields not only can but also have to refer different person
s in the same parent
row, since noone is his own parent and noone's father is his mother as well.