mysql innodb 外键关联约束讲解
2013-03-28 21:52
218 查看
可通过查表信息查看外键的创建信息:Showcreate table tablename \G;
从mysql 3.23.44开始,innodb支持外键约束,跟Oracle基本相同,语法形式如下
[CONSTRAINTsymbol] FOREIGN KEY [id] (index_col_name, ...)
REFERENCEStbl_name (index_col_name, ...)
[ON DELETE{RESTRICT | CASCADE | SET NULL | NO ACTION}]
[ON UPDATE{RESTRICT | CASCADE | SET NULL | NO ACTION}]
ALTER TABLEyourtablename
ADD[CONSTRAINT symbol]FOREIGN KEY [id]
(index_col_name,...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE{RESTRICT | CASCADE | SET NULL | NO ACTION}]
[ON UPDATE{RESTRICT | CASCADE | SET NULL | NO ACTION}]
外键约束对子表的含义:
如果在父表中找不到该键的值,则不允许在子表上进行insert/update。
外键约束对父表的含义:
在父表上进行update/delete以更新或删除,在子表中有一条或多条对应匹配行的外键时,父表的行为取决于:在定义子表的外键时指定的onupdate/on delete子句, InnoDB支持5种方式, 分列如下
事件触发限制:
CASCADE: 从父表删除或更新且自动删除或更新子表中匹配的行。ONDELETE CASCADE和ON UPDATECASCADE都可用。在两个表之间,你不应定义若干在父表或子表中的同一列采取动作的ON
UPDATECASCADE子句。
SETNULL: 从父表删除或更新行,并设置子表中的外键列为NULL。如果外键列没有指定NOTNULL限定词,这就是唯一合法的。ON DELETE SET NULL和ON UPDATE SETNULL子句被支持。
NOACTION: 在ANSISQL-92标准中,NOACTION意味这不采取动作,就是如果有一个相关的外键值在被参考的表里,删除或更新主要键值的企图不被允许进行(Gruber,掌握SQL, 2000:181)。InnoDB拒绝对父表的删除或更新操作。
RESTRICT: 拒绝对父表的删除或更新操作。NOACTION和RESTRICT都一样,删除ON
DELETE或ON UPDATE子句。(一些数据库系统有延期检查,并且NOACTION是一个延期检查。在MySQL中,外键约束是被立即检查的,所以NOACTION和RESTRICT是同样的)。
SETDEFAULT: 这个动作被解析程序识别,但InnoDB拒绝包含ONDELETE SET DEFAULT或ON
UPDATE SET DEFAULT子句的表定义。
在已存在的表中创建外键
alter table 外键所在的表名 add constraint 外键名 foreign key(外键所在的列名)references 对应主键所在表名(主键所在列名);
alter table 外键所在的表名 add constraint 外键名 foreign key(外键所在的列名)references 对应主键所在表名(主键所在列名) ON DELETE CASCADE ONUPDATE NO ACTION;
删除外键
alter table tablename drop foreign keynamefk;
外键的作用:
保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。使两张表形成关联,外键只能引用外表中的列的值!
例如:
a b两个表
a表中存有客户号,客户名称
b表中存有每个客户的订单
有了外键后
你只能在确信b表中没有客户x的订单后,才可以在a表中删除客户x
建立外键的前提:本表的列必须与外键类型相同(外键必须是外表主键)。
指定主键关键字:foreign key(列名)
引用外键关键字:references 外键表名(外键列名)
例子:
products 和serial是一对多的关系
serial.pid字段是外键,products.id字段是外表对应的主键
--
-- 表的结构`products`
--
DROP TABLE IFEXISTS `products`;
CREATE TABLE IFNOT EXISTS `products` (
`id`int(11) NOT NULL auto_increment,
`name`varchar(55),
PRIMARYKEY (`id`),
KEY`name` (`name`)
)ENGINE=InnoDB;
--
-- 表的结构`serial`
--
DROP TABLE IFEXISTS `serial`;
CREATE TABLE IFNOT EXISTS `serial` (
`id`int(11) NOT NULL auto_increment,
`name`varchar(55) ,
`pid`int(11) default NULL,
PRIMARYKEY (`id`),
KEY`name` (`name`),
KEY`pid` (`pid`),
CONSTRAINT `pidfk` FOREIGN KEY (`pid`) REFERENCES `products`(`id`) ONDELETENOACTION ONUPDATE CASCADE
) ENGINE=InnoDB;
//可以修改表添加约束
mysql>alter table `serial` add constraint `keyname` foreign key(`pid`)references products(`id`) on delete cascade on updatecascade;
其它
1,mysqldump在dump数据时,会加入外键信息
2, 也可以用SHOWTABLE STATUS FROM db_name LIKE 'tbl_name';查看外键信息,在comment列中
3,注意innodb中如果设置了lower_case_table_names,对外键的影响
4,在创建外键时,可以加入backtricks(反引号),将外键名,列名包括起来
5,如果是在mysql3.23.50之前版本,注意如果表上有外键或者作为父表被refer,不要使用alter table , createindex命令
6,Innodb要进行外键check时,需要在父或子表上加共享行级锁(shared rowlock),不是事务级
7,从mysql4.1.1开始,为了使reloaddumpfile更容易进行,mysqldump生成的文件自动添加了FOREIGN_KEY_CHECKS=0选项以禁止外键约束检查
对于早期版本,可以用下面方法达到同样目的
mysql> SET FOREIGN_KEY_CHECKS =0;
mysql> SOURCEdump_file_name
mysql> SET FOREIGN_KEY_CHECKS =1;
8, 在altertable或load data时,可能也需要进行上述设置以临时禁止外键约束检查
9,除非设置了FOREIGN_KEY_CHECKS = 0,Innodb禁止drop父表(被子表外键引用的表)
10,当设置FOREIGN_KEY_CHECKS =0后drop一个父子.
下次重新创建这个父表时,必须跟drop之前一样(正确的列/数据类型/被参照的列上必须有索引),否则系统会报1005 refer to errno150 (这一点前述测试中没有发现报错
从mysql 3.23.44开始,innodb支持外键约束,跟Oracle基本相同,语法形式如下
[CONSTRAINTsymbol] FOREIGN KEY [id] (index_col_name, ...)
REFERENCEStbl_name (index_col_name, ...)
[ON DELETE{RESTRICT | CASCADE | SET NULL | NO ACTION}]
[ON UPDATE{RESTRICT | CASCADE | SET NULL | NO ACTION}]
ALTER TABLEyourtablename
ADD[CONSTRAINT symbol]FOREIGN KEY [id]
(index_col_name,...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE{RESTRICT | CASCADE | SET NULL | NO ACTION}]
[ON UPDATE{RESTRICT | CASCADE | SET NULL | NO ACTION}]
外键约束对子表的含义:
如果在父表中找不到该键的值,则不允许在子表上进行insert/update。
外键约束对父表的含义:
在父表上进行update/delete以更新或删除,在子表中有一条或多条对应匹配行的外键时,父表的行为取决于:在定义子表的外键时指定的onupdate/on delete子句, InnoDB支持5种方式, 分列如下
事件触发限制:
CASCADE: 从父表删除或更新且自动删除或更新子表中匹配的行。ONDELETE CASCADE和ON UPDATECASCADE都可用。在两个表之间,你不应定义若干在父表或子表中的同一列采取动作的ON
UPDATECASCADE子句。
SETNULL: 从父表删除或更新行,并设置子表中的外键列为NULL。如果外键列没有指定NOTNULL限定词,这就是唯一合法的。ON DELETE SET NULL和ON UPDATE SETNULL子句被支持。
NOACTION: 在ANSISQL-92标准中,NOACTION意味这不采取动作,就是如果有一个相关的外键值在被参考的表里,删除或更新主要键值的企图不被允许进行(Gruber,掌握SQL, 2000:181)。InnoDB拒绝对父表的删除或更新操作。
RESTRICT: 拒绝对父表的删除或更新操作。NOACTION和RESTRICT都一样,删除ON
DELETE或ON UPDATE子句。(一些数据库系统有延期检查,并且NOACTION是一个延期检查。在MySQL中,外键约束是被立即检查的,所以NOACTION和RESTRICT是同样的)。
SETDEFAULT: 这个动作被解析程序识别,但InnoDB拒绝包含ONDELETE SET DEFAULT或ON
UPDATE SET DEFAULT子句的表定义。
在已存在的表中创建外键
alter table 外键所在的表名 add constraint 外键名 foreign key(外键所在的列名)references 对应主键所在表名(主键所在列名);
alter table 外键所在的表名 add constraint 外键名 foreign key(外键所在的列名)references 对应主键所在表名(主键所在列名) ON DELETE CASCADE ONUPDATE NO ACTION;
删除外键
alter table tablename drop foreign keynamefk;
外键的作用:
保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。使两张表形成关联,外键只能引用外表中的列的值!
例如:
a b两个表
a表中存有客户号,客户名称
b表中存有每个客户的订单
有了外键后
你只能在确信b表中没有客户x的订单后,才可以在a表中删除客户x
建立外键的前提:本表的列必须与外键类型相同(外键必须是外表主键)。
指定主键关键字:foreign key(列名)
引用外键关键字:references 外键表名(外键列名)
例子:
products 和serial是一对多的关系
serial.pid字段是外键,products.id字段是外表对应的主键
--
-- 表的结构`products`
--
DROP TABLE IFEXISTS `products`;
CREATE TABLE IFNOT EXISTS `products` (
`id`int(11) NOT NULL auto_increment,
`name`varchar(55),
PRIMARYKEY (`id`),
KEY`name` (`name`)
)ENGINE=InnoDB;
--
-- 表的结构`serial`
--
DROP TABLE IFEXISTS `serial`;
CREATE TABLE IFNOT EXISTS `serial` (
`id`int(11) NOT NULL auto_increment,
`name`varchar(55) ,
`pid`int(11) default NULL,
PRIMARYKEY (`id`),
KEY`name` (`name`),
KEY`pid` (`pid`),
CONSTRAINT `pidfk` FOREIGN KEY (`pid`) REFERENCES `products`(`id`) ONDELETENOACTION ONUPDATE CASCADE
) ENGINE=InnoDB;
//可以修改表添加约束
mysql>alter table `serial` add constraint `keyname` foreign key(`pid`)references products(`id`) on delete cascade on updatecascade;
其它
1,mysqldump在dump数据时,会加入外键信息
2, 也可以用SHOWTABLE STATUS FROM db_name LIKE 'tbl_name';查看外键信息,在comment列中
3,注意innodb中如果设置了lower_case_table_names,对外键的影响
4,在创建外键时,可以加入backtricks(反引号),将外键名,列名包括起来
5,如果是在mysql3.23.50之前版本,注意如果表上有外键或者作为父表被refer,不要使用alter table , createindex命令
6,Innodb要进行外键check时,需要在父或子表上加共享行级锁(shared rowlock),不是事务级
7,从mysql4.1.1开始,为了使reloaddumpfile更容易进行,mysqldump生成的文件自动添加了FOREIGN_KEY_CHECKS=0选项以禁止外键约束检查
对于早期版本,可以用下面方法达到同样目的
mysql> SET FOREIGN_KEY_CHECKS =0;
mysql> SOURCEdump_file_name
mysql> SET FOREIGN_KEY_CHECKS =1;
8, 在altertable或load data时,可能也需要进行上述设置以临时禁止外键约束检查
9,除非设置了FOREIGN_KEY_CHECKS = 0,Innodb禁止drop父表(被子表外键引用的表)
10,当设置FOREIGN_KEY_CHECKS =0后drop一个父子.
下次重新创建这个父表时,必须跟drop之前一样(正确的列/数据类型/被参照的列上必须有索引),否则系统会报1005 refer to errno150 (这一点前述测试中没有发现报错
相关文章推荐
- mysql innodb 外键关联约束实例
- plsql找外键约束关联的表的方法
- hibernate 外键关联 不生成外键约束
- 讲解SQL与Oracle外键约束中的级联删除-PLSQL
- 力所能及之hibernate 外键关联 不生成外键约束
- oracle禁用外键关联约束
- 设计实现在一条记录中外键关联到另一个表的两条记录功能的SQL查询
- 浅谈SQL之主键、外键约束
- 某表,多字段关联,多种约束,如何做(触发器实现代码)?
- SQL Server-- 外键约束方式
- Hiberante学习08---基于Annotation配置的一对一单向外键关联
- Hibernate一对一外键关联映射(单向)
- hibernate反向工程(外键约束)
- hibernate学习(7)——一对一双向外键关联
- EA(Enterprise Architect)建立数据模型间外键约束
- SET FOREIGN_KEY_CHECKS=0;在Mysql中取消外键约束
- 清除oracl中有主外键关联的表中的部分数据。
- Oracle PL/SQL之Flashback Table与外键约束
- SQL的主键和外键约束
- sql语句增加表单字段ALTER TABLE ADD 增加多个字段 外键约束