外键约束:
一. InnoDB引擎类型
二. 两个表的列必须是数据类型相似
三. 外键的定义语法
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
REFERENCES tbl_name (index_col_name, ...)
[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
该语法可以在 CREATE TABLE 和 ALTER TABLE 时使用,如果不指定CONSTRAINT symbol,MYSQL会自动生成一个名字。
ON DELETE、ON UPDATE表示事件触发限制,可设参数:
RESTRICT(限制外表中的外键改动)
CASCADE(跟随外键改动)
SET NULL(设空值)
SET DEFAULT(设默认值)
NO ACTION(无动作,默认的)
注:
Cascade方式
在父表上update/delete记录时,同步update/delete掉子表的匹配记录
On delete cascade从mysql3.23.50开始可用; on update cascade从mysql4.0.8开始可用
Restrict方式
如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作
四. 举例
CREATE TABLE `product` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='产品表';
CREATE TABLE `product_attr` ( `id` int(11) NOT NULL AUTO_INCREMENT, `pid` int(11) DEFAULT NULL, `name` varchar(32) DEFAULT '', PRIMARY KEY (`id`), KEY `pid` (`pid`) USING BTREE, CONSTRAINT `product_attr_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `product` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='产品属性表';
INSERT INTO `product` (`name`) VALUES ('电视')
INSERT INTO `product_attr` (`pid`, `name`) VALUES ('2', '32寸')
在Restrict方式 下删除产品
DELETE FROM `product` WHERE (`id`='2')
提示1451 - Cannot delete or update a parent row: a foreign key constraint fails (`test`.`product_attr`, CONSTRAINT `product_attr_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `product` (`id`))
在Restrict方式 下添加产品属性
INSERT INTO `product_attr` (`pid`, `name`) VALUES ('3', 'LED')
提示1452 - Cannot add or update a child row: a foreign key constraint fails (`test`.`product_attr`, CONSTRAINT `product_attr_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `product` (`id`))
这个就是触发器在Restrict方式下限制动作
在看看Cascade方式
修改产品属性表结构
ALTER TABLE `product_attr` DROP FOREIGN KEY `product_attr_ibfk_1`;
ALTER TABLE `product_attr` ADD CONSTRAINT `product_attr_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `product` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
DELETE FROM `product` WHERE (`id`='2')
这就是Cascade方式下的同步改动。