InnoDB 表类型第一次为 MySQL 提供了外键约束以保证你的数据完整性。
InnoDB 中外键约束的定义语法如下所示:
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
REFERENCES table_name (index_col_name, ...)
[ON DELETE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
两个表必须为 InnoDB 类型,外键和被引用键(referenced key)必须是索引中的第一(FIRST)列。InnoDB 不会自动为外键和被引用键建立索引,必须明确创建它们。
外键与对应的被引用键在 InnoDB 内必须 有相似的内部数据类型,以便他们不需要一个类型转换就可以进行比较。 整型(Integer)字段的长度与有符号类型(signedness)必须一致。 字符型则不需要一致。如果指定了一个 SET NULL 动作,那你必须要确定 子表中的对应字段没有定义为 NOT NULL。
如果 CREATE TABLE 给出 1005 号错误,错误信息字符串提示错误号(errno) 150,那么就是因为外键约束未被正确建立而导致表创建失败。同样的,如果一条 ALTER TABLE 失败而返回错误号 150,那就意味着 altered table 未能正确定义一个外键。从 4.0.13 开始,你可以通过使用 SHOW INNODB STATUS 来查看服务器是最后一条 InnoDB 的外键错误的详细说明。
从 3.23.50 开始,InnoDB 不再在允许 NULL 值外键或被引用键上检查外键约束。
与 SQL 标准不一致: if in the parent table there are several rows which have the same referenced key value, then InnoDB acts in foreign key checks like the other parent rows with the same key value would not exist. For example, if you have defined a RESTRICT type constraint, and there is a child row with several parent rows, InnoDB does not allow the deletion of any of those parent rows.
从 3.23.50 开始,可能联合 ON DELETE CASCADE 或 ON DELETE SET NULL 子句与外键约束一同作用。相应的 ON UPDATE 选项将从 4.0.8 开始支持。如果 ON DELETE CASCADE 被指定,当主表中的记录行被删除时,InnoDB 将自动删除子表中被引用键值与主表中相对应的外键值相同的记录。如果 ON DELETE SET NULL 被指定,子表中的外键对应行将被设置为 NULL 值。
与 SQL 标准不一致: if ON UPDATE CASCADE or ON UPDATE SET NULL recurses to update the SAME TABLE it has already updated during the cascade, it acts like RESTRICT. This is to prevent infinite loops resulting from cascaded updates. A self-referential ON DELETE SET NULL, on the other hand, works starting from 4.0.13. A self-referential ON DELETE CASCADE has always worked.
示例:
CREATE TABLE parent(id INT NOT NULL,
PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE child(id INT, parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE CASCADE
) TYPE=INNODB;
从 3.23.50 开始,InnoDB 允许通过下面的方法给一个表添加一个外键约束:
ALTER TABLE yourtablename
ADD [CONSTRAINT symbol] FOREIGN KEY [id] (...)
REFERENCES table_name (index_col_name, ...)
[ON DELETE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
记住首先要建立必要的索引,尽管可以通过 ALTER TABLE 为一个表建立一个自参考(self-referential)的外键。
从 4.0.13 开始,InnoDB 支持 ALTER TABLE DROP FOREIGN KEY internally_generated_foreign_key_id
当你需要删除一个外键时可以使用 SHOW CREATE TABLE 来查看 internally generated foreign key id。
如果要导入表的几个转储(dump),而数据并没有按外键排序,从 3.23.52 和 4.0.3 开始,可以在导入时关闭外键检查: SET FOREIGN_KEY_CHECKS=0;
这就允许以任何顺序导入数据,同时提高导入速度。
从 3.23.50 开始,InnoDB 语法分析器(parser)允许你 backquotes around table 以及将列名放入 FOREIGN KEY ... REFERENCES ... 子句中。从 4.0.5 开始,InnoDB 语法分析器能处理 my.cnf 文件可能设置的 lower_case_table_names。
在小于 3.23.50 的版本中,InnoDB 任何 ALTER TABLE 或 CREATE INDEX 均不能在使用在有外键约束或被引用键约束的表上:任何 ALTER TABLE 都将删除表中定义的外键约束。不能再使用 ALTER TABLE 来任何一个表,只有通过 DROP TABLE 和 CREATE TABLE 来修改。当 MySQL 执行一个 ALTER TABLE 时,在内部处理上是通过 RENAME TABLE 来实现的,这将引起外键约束对表的引用混乱。同样 CREATE INDEX 语句也是作为 ALTER TABLE来处理的,也不能用于外键约束的表。
当 InnoDB 进行外键检查时会对主表与子表数据加行锁。nnoDB 会立即检查外键约束:检查不会等到事务提交。
InnoDB 允许你 drop 任何表,即使这样会打破外键,这样操作的结果就是约束也被 drop 了。
InnoDB 允许你撤消(drop)任何表,即使这样会打破被引用表的外键约束。 当你撤消一个表时约束也同时被撤销了。
如果重新创建一个被撤消的表,必须参考原有定义建立一致的外键约束。 必须有正确的列我与类型。必须在引用键上有索引。如果不符合上面的条件,MySQL 将返回1005 号错误,错误信息字符串提示错误号(errno) 150。
从 3.23.50 开始,通过下列指令可以使 InnoDB 返回表的外键约束定义 SHOW CREATE TABLE yourtablename
还可以通过 mysqldump 将表的完整定义转储到文件中,当然包括外键定义。
还可以通过下面的指令列出表 T 的外键约束: SHOW TABLE STATUS FROM yourdatabasename LIKE 'T'
外键约束将会在表注释中列出。
InnoDB 表类型第一次为 MySQL 提供了外键约束以保证你的数据完整性。
InnoDB 中外键约束的定义语法如下所示:
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
REFERENCES table_name (index_col_name, ...)
[ON DELETE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
两个表必须为 InnoDB 类型,外键和被引用键(referenced key)必须是索引中的第一(FIRST)列。InnoDB 不会自动为外键和被引用键建立索引,必须明确创建它们。
外键与对应的被引用键在 InnoDB 内必须 有相似的内部数据类型,以便他们不需要一个类型转换就可以进行比较。 整型(Integer)字段的长度与有符号类型(signedness)必须一致。 字符型则不需要一致。如果指定了一个 SET NULL 动作,那你必须要确定 子表中的对应字段没有定义为 NOT NULL。
如果 CREATE TABLE 给出 1005 号错误,错误信息字符串提示错误号(errno) 150,那么就是因为外键约束未被正确建立而导致表创建失败。同样的,如果一条 ALTER TABLE 失败而返回错误号 150,那就意味着 altered table 未能正确定义一个外键。从 4.0.13 开始,你可以通过使用 SHOW INNODB STATUS 来查看服务器是最后一条 InnoDB 的外键错误的详细说明。
从 3.23.50 开始,InnoDB 不再在允许 NULL 值外键或被引用键上检查外键约束。
与 SQL 标准不一致: if in the parent table there are several rows which have the same referenced key value, then InnoDB acts in foreign key checks like the other parent rows with the same key value would not exist. For example, if you have defined a RESTRICT type constraint, and there is a child row with several parent rows, InnoDB does not allow the deletion of any of those parent rows.
从 3.23.50 开始,可能联合 ON DELETE CASCADE 或 ON DELETE SET NULL 子句与外键约束一同作用。相应的 ON UPDATE 选项将从 4.0.8 开始支持。如果 ON DELETE CASCADE 被指定,当主表中的记录行被删除时,InnoDB 将自动删除子表中被引用键值与主表中相对应的外键值相同的记录。如果 ON DELETE SET NULL 被指定,子表中的外键对应行将被设置为 NULL 值。
与 SQL 标准不一致: if ON UPDATE CASCADE or ON UPDATE SET NULL recurses to update the SAME TABLE it has already updated during the cascade, it acts like RESTRICT. This is to prevent infinite loops resulting from cascaded updates. A self-referential ON DELETE SET NULL, on the other hand, works starting from 4.0.13. A self-referential ON DELETE CASCADE has always worked.
示例:
CREATE TABLE parent(id INT NOT NULL,
PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE child(id INT, parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE CASCADE
) TYPE=INNODB;
从 3.23.50 开始,InnoDB 允许通过下面的方法给一个表添加一个外键约束:
ALTER TABLE yourtablename
ADD [CONSTRAINT symbol] FOREIGN KEY [id] (...)
REFERENCES table_name (index_col_name, ...)
[ON DELETE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION
| RESTRICT}]
记住首先要建立必要的索引,尽管可以通过 ALTER TABLE 为一个表建立一个自参考(self-referential)的外键。
从 4.0.13 开始,InnoDB 支持 ALTER TABLE DROP FOREIGN KEY internally_generated_foreign_key_id
当你需要删除一个外键时可以使用 SHOW CREATE TABLE 来查看 internally generated foreign key id。
如果要导入表的几个转储(dump),而数据并没有按外键排序,从 3.23.52 和 4.0.3 开始,可以在导入时关闭外键检查: SET FOREIGN_KEY_CHECKS=0;
这就允许以任何顺序导入数据,同时提高导入速度。
从 3.23.50 开始,InnoDB 语法分析器(parser)允许你 backquotes around table 以及将列名放入 FOREIGN KEY ... REFERENCES ... 子句中。从 4.0.5 开始,InnoDB 语法分析器能处理 my.cnf 文件可能设置的 lower_case_table_names。
在小于 3.23.50 的版本中,InnoDB 任何 ALTER TABLE 或 CREATE INDEX 均不能在使用在有外键约束或被引用键约束的表上:任何 ALTER TABLE 都将删除表中定义的外键约束。不能再使用 ALTER TABLE 来任何一个表,只有通过 DROP TABLE 和 CREATE TABLE 来修改。当 MySQL 执行一个 ALTER TABLE 时,在内部处理上是通过 RENAME TABLE 来实现的,这将引起外键约束对表的引用混乱。同样 CREATE INDEX 语句也是作为 ALTER TABLE来处理的,也不能用于外键约束的表。
当 InnoDB 进行外键检查时会对主表与子表数据加行锁。nnoDB 会立即检查外键约束:检查不会等到事务提交。
InnoDB 允许你 drop 任何表,即使这样会打破外键,这样操作的结果就是约束也被 drop 了。
InnoDB 允许你撤消(drop)任何表,即使这样会打破被引用表的外键约束。 当你撤消一个表时约束也同时被撤销了。
如果重新创建一个被撤消的表,必须参考原有定义建立一致的外键约束。 必须有正确的列我与类型。必须在引用键上有索引。如果不符合上面的条件,MySQL 将返回1005 号错误,错误信息字符串提示错误号(errno) 150。
从 3.23.50 开始,通过下列指令可以使 InnoDB 返回表的外键约束定义 SHOW CREATE TABLE yourtablename
还可以通过 mysqldump 将表的完整定义转储到文件中,当然包括外键定义。
还可以通过下面的指令列出表 T 的外键约束: SHOW TABLE STATUS FROM yourdatabasename LIKE 'T'
外键约束将会在表注释中列出。