您的位置:首页 > 数据库 > MySQL

MySQL中的级联约束

2016-02-15 21:22 651 查看
在MySQL中,如果一个表a的外键(a1)映射了另一个表b上的一个字段(b1),那么这么表b就是表a的父表,如果在建立约束关系的时候没有指定级联更新或者删除那么,当更新子表a中字段a1的时候如果a1中的值的范围包含父表b1字段上的值,那么会因为有外键约束而更新失败。更新父表b中的b1字段是,如果被更新的值已经在子表a中的a1字段被引用,那么也会更新失败。如果更新想避免后者的话,需要设置cascade关联关系,如下实例(以):

两个表的ddl如下:

create table product_type
(product_type_cd varchar(10) not null,
name varchar(50) not null,
constraint pk_product_type primary key (product_type_cd)
);

create table product
(product_cd varchar(10) not null,
name varchar(50) not null,
product_type_cd varchar(10) not null,
date_offered date,
date_retired date,
constraint fk_product_type_cd foreign key (product_type_cd)
references product_type (product_type_cd),
constraint pk_product primary key (product_cd)
);


演示如下

mysql> select * from product;
+------------+-------------------------+-----------------+--------------+--------------+
| product_cd | name                    | product_type_cd | date_offered | date_retired |
+------------+-------------------------+-----------------+--------------+--------------+
| AUT        | auto loan               | LOAN            | 2004-01-01   | NULL         |
| BUS        | business line of credit | LOAN            | 2004-01-01   | NULL         |
| CD         | certificate of deposit  | ACCOUNT         | 2004-01-01   | NULL         |
| CHK        | checking account        | ACCOUNT         | 2004-01-01   | NULL         |
| MM         | money market account    | ACCOUNT         | 2004-01-01   | NULL         |
| MRT        | home mortgage           | LOAN            | 2004-01-01   | NULL         |
| SAV        | savings account         | ACCOUNT         | 2004-01-01   | NULL         |
| SBL        | small business loan     | LOAN            | 2004-01-01   | NULL         |
+------------+-------------------------+-----------------+--------------+--------------+
8 rows in set (0.00 sec)

mysql> select * from product_type;
+-----------------+-------------------------------+
| product_type_cd | name                          |
+-----------------+-------------------------------+
| ACCOUNT         | Customer Accounts             |
| INSURANCE       | Insurance Offerings           |
| LOAN            | Individual and Business Loans |
+-----------------+-------------------------------+
3 rows in set (0.00 sec)

--更新的范围包含级联关系也不会成功
mysql> update product set product_type_cd='1234'
-> ;
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`product`, CONSTRAINT `fk_product_type_cd`
FOREIGN KEY (`product_type_cd`) REFERENCES `product_type` (`product_type_cd`))

--直接更新有级联关系的
mysql> update product_type set product_type_cd='1234' where product_type_cd='LOAN';
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`product`, CONSTRAINT `fk_product_type_
cd` FOREIGN KEY (`product_type_cd`) REFERENCES `product_type` (`product_type_cd`))

--更新有没有级联关系的
mysql> update product_type set product_type_cd='1234' where product_type_cd='INSURANCE';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

--查询下成功了
mysql> select * from product_type;
+-----------------+-------------------------------+
| product_type_cd | name                          |
+-----------------+-------------------------------+
| 1234            | Insurance Offerings           |
| ACCOUNT         | Customer Accounts             |
| LOAN            | Individual and Business Loans |
+-----------------+-------------------------------+
3 rows in set (0.00 sec)

--再恢复到原样
mysql> update product_type set product_type_cd='INSURANCE' where product_type_cd='1234';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

--看下product表上的索引
mysql> show index from product \G
*************************** 1. row ***************************
Table: product
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: product_cd
Collation: A
Cardinality: 8
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 2. row ***************************
Table: product
Non_unique: 1
Key_name: fk_product_type_cd
Seq_in_index: 1
Column_name: product_type_cd
Collation: A
Cardinality: 4
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
2 rows in set (0.00 sec)

--删除一个约束
mysql> alter table product
-> drop foreign key fk_product_type_cd;
Query OK, 8 rows affected (0.05 sec)
Records: 8  Duplicates: 0  Warnings: 0

--新增一个约束,比之前删除的约束加入了级联删除的关系
mysql> alter table product add constraint fk_product_type_cd foreign key (product_type_cd) references product_type (product_type_cd)
->  on update cascade;
Query OK, 8 rows affected (0.03 sec)
Records: 8  Duplicates: 0  Warnings: 0

--重新更新product_type表
mysql> update product_type set product_type_cd='1234' where product_type_cd='LOAN';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

--发现已经product表中级联更新过来了
mysql> select * from product ;
+------------+-------------------------+-----------------+--------------+--------------+
| product_cd | name                    | product_type_cd | date_offered | date_retired |
+------------+-------------------------+-----------------+--------------+--------------+
| AUT        | auto loan               | 1234            | 2004-01-01   | NULL         |
| BUS        | business line of credit | 1234            | 2004-01-01   | NULL         |
| CD         | certificate of deposit  | ACCOUNT         | 2004-01-01   | NULL         |
| CHK        | checking account        | ACCOUNT         | 2004-01-01   | NULL         |
| MM         | money market account    | ACCOUNT         | 2004-01-01   | NULL         |
| MRT        | home mortgage           | 1234            | 2004-01-01   | NULL         |
| SAV        | savings account         | ACCOUNT         | 2004-01-01   | NULL         |
| SBL        | small business loan     | 1234            | 2004-01-01   | NULL         |
+------------+-------------------------+-----------------+--------------+--------------+
8 rows in set (0.00 sec)

mysql> update product set product_type_cd='LOAN' WHERE product_type_cd='1234';
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`product`, CONSTRAINT `fk_product_type_cd`
FOREIGN KEY (`product_type_cd`) REFERENCES `product_type` (`product_type_cd`) ON UPDATE CASCADE)
mysql>

--级联更新的和级联删除的都加上
mysql> alter table product
-> drop foreign key fk_product_type_cd;
Query OK, 8 rows affected (0.03 sec)
Records: 8  Duplicates: 0  Warnings: 0

mysql> alter table product
-> add constraint  fk_product_type_cd foreign key (product_type_cd)
-> references product_type (product_type_cd)
-> on update cascade
-> on delete cascade;
Query OK, 8 rows affected (0.03 sec)
Records: 8  Duplicates: 0  Warnings: 0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: