Can the same column have primary key & foreign key constraint to another column?
Table1: ID - Primary column, foreign key constraint for Table2 ID
Table2
There should be no problem with that. Consider the following example:
CREATE TABLE table2 (
id int PRIMARY KEY,
name varchar(20)
) ENGINE=INNODB;
CREATE TABLE table1 (
id int PRIMARY KEY,
t2_id int,
FOREIGN KEY (t2_id) REFERENCES table2 (id)
) ENGINE=INNODB;
INSERT INTO table2 VALUES (1, 'First Row');
INSERT INTO table2 VALUES (2, 'Second Row');
INSERT INTO table1 VALUES (1, 1);
INSERT INTO table1 VALUES (2, 1);
INSERT INTO table1 VALUES (3, 1);
INSERT INTO table1 VALUES (4, 2);
The tables now contain:
SELECT * FROM table1;
+----+-------+
| id | t2_id |
+----+-------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
+----+-------+
4 rows in set (0.00 sec)
SELECT * FROM table2;
+----+------------+
| id | name |
+----+------------+
| 1 | First Row |
| 2 | Second Row |
+----+------------+
2 rows in set (0.00 sec)
Now we can successfully delete rows like this:
DELETE FROM table1 WHERE id = 1;
Query OK, 1 row affected (0.00 sec)
DELETE FROM table1 WHERE t2_id = 2;
Query OK, 1 row affected (0.00 sec)
However we won't be able to delete the following:
DELETE FROM table2 WHERE id = 1;
ERROR 1451 (23000): A foreign key constraint fails
If we had defined the foreign key on table1
with the CASCADE option, we would have been able to delete the parent, and all the children would get deleted automatically:
CREATE TABLE table2 (
id int PRIMARY KEY,
name varchar(20)
) ENGINE=INNODB;
CREATE TABLE table1 (
id int PRIMARY KEY,
t2_id int,
FOREIGN KEY (t2_id) REFERENCES table2 (id) ON DELETE CASCADE
) ENGINE=INNODB;
INSERT INTO table2 VALUES (1, 'First Row');
INSERT INTO table2 VALUES (2, 'Second Row');
INSERT INTO table1 VALUES (1, 1);
INSERT INTO table1 VALUES (2, 1);
INSERT INTO table1 VALUES (3, 1);
INSERT INTO table1 VALUES (4, 2);
If we were to repeat the previously failed DELETE
, the children rows in table1
will be deleted as well as the parent row in table2
:
DELETE FROM table2 WHERE id = 1;
Query OK, 1 row affected (0.00 sec)
SELECT * FROM table1;
+----+-------+
| id | t2_id |
+----+-------+
| 4 | 2 |
+----+-------+
1 row in set (0.00 sec)
SELECT * FROM table2;
+----+------------+
| id | name |
+----+------------+
| 2 | Second Row |
+----+------------+
1 row in set (0.00 sec)