外鍵


表結構1:

CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `createtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

表結構2:

 CREATE TABLE `t2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_id` int(11) DEFAULT NULL,
  `createtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `t_id_fk` (`t_id`),
  CONSTRAINT `t_id_fk` FOREIGN KEY (`t_id`) REFERENCES `t1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 設置了主鍵和外鍵的字段,默認會創建該字段的索引

show index from t2;

 執行結果

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| t2    |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| t2    |          1 | t_id_fk  |            1 | t_id        | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

 

為t1插入數據

+----+------+---------------------+
| id | name | createtime          |
+----+------+---------------------+
|  1 | a    | 2018-06-27 10:51:36 |
|  2 | b    | 2018-06-27 10:51:36 |
|  3 | c    | 2018-06-27 10:51:36 |
|  4 | d    | 2018-06-27 10:51:36 |
+----+------+---------------------+

 

為t2插入數據,由於外鍵約束的存在,t2(t_id)列的數據必須都來自於t1(id)列

insert into t2 (t_id) values (5);

 執行結果

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`pmx`.`t2`, CONSTRAINT `t_id_fk` FOREIGN KEY (`t_id`) REFERENCES `t1` (`id`))

 

insert into t2 (t_id) values (3),(2),(4),(3),(1),(4);

 執行結果

+----+------+---------------------+
| id | t_id | createtime          |
+----+------+---------------------+
|  2 |    3 | 2018-06-27 10:55:29 |
|  3 |    2 | 2018-06-27 10:55:29 |
|  4 |    4 | 2018-06-27 10:55:29 |
|  5 |    3 | 2018-06-27 10:55:29 |
|  6 |    1 | 2018-06-27 10:55:29 |
|  7 |    4 | 2018-06-27 10:55:29 |
+----+------+---------------------+

t2.t_id字段的數據必須來自於t1.id,不能出現t1.id中沒有的數據。id號從2開始,因為第一次插入5時失敗了,但是auto_increment仍然從1變為了2。

t_id字段的更新受外鍵的約束,取值范圍只能來自於t1的id字段值。

t2的刪除操作不受外鍵的約束

update t2 set t_id = 3 where id = 7;
delete from t2 where id = 4;

 執行結果

+----+------+---------------------+
| id | t_id | createtime          |
+----+------+---------------------+
|  2 |    3 | 2018-06-27 10:55:29 |
|  3 |    2 | 2018-06-27 10:55:29 |
|  5 |    3 | 2018-06-27 10:55:29 |
|  6 |    1 | 2018-06-27 10:55:29 |
|  7 |    3 | 2018-06-27 10:55:29 |
+----+------+---------------------+

 

對主表t1執行刪除操作時,如果刪除的主鍵值在子表t2中出現,那么就刪除失敗

delete from t1 where id = 4;

執行結果

+----+------+---------------------+
| id | name | createtime          |
+----+------+---------------------+
|  1 | a    | 2018-06-27 10:51:36 |
|  2 | b    | 2018-06-27 10:51:36 |
|  3 | c    | 2018-06-27 10:51:36 |
+----+------+---------------------+

刪除成功

 

delete from t1 where id = 3;

執行結果

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`pmx`.`t2`, CONSTRAINT `t_id_fk` FOREIGN KEY (`t_id`) REFERENCES `t1` (`id`)) 

刪除失敗

 

來看更新操作

insert into t1 (name) values ('d'); 

 執行結果

+----+------+---------------------+
| id | name | createtime          |
+----+------+---------------------+
|  1 | a    | 2018-06-27 10:51:36 |
|  2 | b    | 2018-06-27 10:51:36 |
|  3 | c    | 2018-06-27 10:51:36 |
|  5 | d    | 2018-06-27 11:06:24 |
+----+------+---------------------+

受auto_increment的特性影響,id變成了5

 

update t1 set id = 7 where id = 5;

執行結果

+----+------+---------------------+
| id | name | createtime          |
+----+------+---------------------+
|  1 | a    | 2018-06-27 10:51:36 |
|  2 | b    | 2018-06-27 10:51:36 |
|  3 | c    | 2018-06-27 10:51:36 |
|  7 | d    | 2018-06-27 11:06:24 |
+----+------+---------------------+

 更新成功。5和7並未在t2中出現

 

update t1 set id = 8 where id =1;

執行結果

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`pmx`.`t2`, CONSTRAINT `t_id_fk` FOREIGN KEY (`t_id`) REFERENCES `t1` (`id`)

更新失敗

所以更新操作和刪除操作一樣,如果操作的值在子表中出現,那么就會操作失敗

 

truncate table t2;

成功清空

truncate table t1;
ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint (`pmx`.`t2`, CONSTRAINT `t_id_fk` FOREIGN KEY (`t_id`) REFERENCES `pmx`.`t1` (`id`))

為了能清空t1,我們只能先刪除t2的外鍵再清空t1

alter table t2 drop foreign key t_id_fk;
alter table t2 drop key t_id_fk;
truncate table t1;
Query OK, 0 rows affected (0.02 sec)

外鍵定制三種約束模式

  restrict和no action:父表更新或者刪除時,子表有匹配記錄,則禁止父表的更新和刪除。默認選項

  cascade:父表更新或者刪除時,子表有匹配記錄,則父表操作成功,同時更新或刪除子表匹配項

  set null:父表更新或者刪除時,子表有匹配記錄,則父表操作成功,同時將子表的匹配項設置為null值(前提能設置為null) 

alter table t2 add constraint c_fk foreign key t_id references t1(id) [on {delete | update} { restrict | no action | cascade | set null}];

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM