MySQL supports foreign keys, which permit cross-referencing related data across tables, and foreign key constraints, which help keep the related data consistent.MySQL支持外键(允许跨表交叉引用相关数据)和外键约束(有助于保持相关数据的一致性)。
A foreign key relationship involves a parent table that holds the initial column values, and a child table with column values that reference the parent column values. 外键关系涉及一个包含初始列值的父表,以及一个包含引用父列值的列值的子表。A foreign key constraint is defined on the child table.在子表上定义了外键约束。
The essential syntax for a defining a foreign key constraint in a 在CREATE TABLE
or ALTER TABLE
statement includes the following:CREATE TABLE
或ALTER TABLE
语句中定义外键约束的基本语法包括:
[CONSTRAINT [symbol
]] FOREIGN KEY [index_name
] (col_name
, ...) REFERENCEStbl_name
(col_name
,...) [ON DELETEreference_option
] [ON UPDATEreference_option
]reference_option
: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
Foreign key constraint usage is described under the following topics in this section:外键约束的使用在本节的以下主题下进行了说明:
Foreign key constraint naming is governed by the following rules:外键约束命名受以下规则管辖:
The 将使用CONSTRAINT
symbol
value is used, if defined.CONSTRAINT symbol值
(如果已定义)。
If the 如果未定义CONSTRAINT
symbol
clause is not defined, or a symbol is not included following the CONSTRAINT
keyword, a constraint name name is generated automatically.CONSTRAINT symbol
子句,或者CONSTRAINT
关键字后面未包含符号,则会自动生成约束名称。
Prior to MySQL 8.0.16, if the 在MySQL 8.0.16之前,如果未定义CONSTRAINT
symbol
clause was not defined, or a symbol was not included following the CONSTRAINT
keyword, both InnoDB
and NDB
storage engines would use the FOREIGN_KEY
if defined. index_name
CONSTRAINT symbol
子句,或者CONSTRAINT
关键字后面未包含符号,InnoDB
和NDB
存储引擎都将使用FOREIGN_KEY index_name
(如果已定义)。In MySQL 8.0.16 and higher, the 在MySQL 8.0.16及更高版本中,FOREIGN_KEY
is ignored.index_name
FOREIGN_KEY index_name
被忽略。
The CONSTRAINT
value, if defined, must be unique in the database. symbol
CONSTRAINT symbol
值(如果已定义)在数据库中必须是唯一的。A duplicate 重复symbol
results in an error similar to: ERROR 1005 (HY000): Can't create table 'test.fk1' (errno: 121).symbol
会导致类似以下情况的错误:ERROR 1005 (HY000): Can't create table 'test.fk1' (errno: 121)。
NDB Cluster stores foreign names using the same lettercase with which they are created. NDB Cluster使用创建外来名称时使用的同一个大写字母存储外来名称。Prior to version 8.0.20, when processing 在版本8.0.20之前,当处理SELECT
and other SQL statements, NDB
compared the names of foreign keys in such statements with the names as stored in a case-sensitive fashion when lower_case_table_names
was equal to 0. SELECT
和其他SQL语句时,NDB
将此类语句中外键的名称与lower_case_table_names
等于0时以区分大小写的方式存储的名称进行比较。In NDB 8.0.20 and later, this value no longer has any effect on how such comparisons are made, and they are always done without regard to lettercase. 在NDB 8.0.20及更高版本中,该值不再对如何进行此类比较产生任何影响,并且始终不考虑字母大小写。(Bug #30512043)
Table and column identifiers in a FOREIGN KEY ... REFERENCES
clause can be quoted within backticks (`
). FOREIGN KEY ... REFERENCES
子句中的表和列标识符可以在反点符号(`
)中引用。Alternatively, double quotation marks (或者,如果启用了"
) can be used if the ANSI_QUOTES
SQL mode is enabled. ANSI_QUOTES
SQL模式,则可以使用双引号("
)。The 还考虑了lower_case_table_names
system variable setting is also taken into account.lower_case_table_names
系统变量设置。
Foreign key constraints are subject to the following conditions and restrictions:外键约束受以下条件和限制的约束:
Parent and child tables must use the same storage engine, and they cannot be defined as temporary tables.父表和子表必须使用相同的存储引擎,并且不能将它们定义为临时表。
Creating a foreign key constraint requires the 创建外键约束需要父表上的REFERENCES
privilege on the parent table.REFERENCES
权限。
Corresponding columns in the foreign key and the referenced key must have similar data types. 外键和引用键中的相应列必须具有相似的数据类型。The size and sign of fixed precision types such as INTEGER
and DECIMAL
must be the same. INTEGER
和DECIMAL
等固定精度类型的大小和符号必须相同。The length of string types need not be the same. 字符串类型的长度不必相同。For nonbinary (character) string columns, the character set and collation must be the same.对于非二进制(字符)字符串列,字符集和排序规则必须相同。
MySQL supports foreign key references between one column and another within a table. MySQL支持表中一列和另一列之间的外键引用。(A column cannot have a foreign key reference to itself.) (列本身不能有外键引用。)In these cases, a “child table record” refers to a dependent record within the same table.在这些情况下,“子表记录”是指同一表中的从属记录。
MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. MySQL需要外键和引用键的索引,这样外键检查可以很快,而不需要扫描表。In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order. 在引用表中,必须有一个索引,其中外键列按相同顺序列为第一列。Such an index is created on the referencing table automatically if it does not exist. 如果引用表不存在,则会自动在引用表上创建这样的索引。This index might be silently dropped later if you create another index that can be used to enforce the foreign key constraint. 如果您创建了另一个可用于强制外键约束的索引,则该索引可能会在以后以静默方式删除。index_name
, if given, is used as described previously.index_name
(如果给定)如前所述使用。
InnoDB
permits a foreign key to reference any index column or group of columns. InnoDB
允许外键引用任何索引列或列组。However, in the referenced table, there must be an index where the referenced columns are the first columns in the same order. 但是,在引用的表中,必须有一个索引,其中引用的列是相同顺序的第一列。Hidden columns that InnoDB
adds to an index are also considered (see Section 15.6.2.1, “Clustered and Secondary Indexes”).InnoDB
添加到索引中的隐藏列也会被考虑(请参阅第15.6.2.1节,“聚集索引和二级索引”)。
NDB
requires an explicit unique key (or primary key) on any column referenced as a foreign key. NDB
要求在作为外键引用的任何列上有一个明确的唯一键(或主键)。InnoDB
does not, which is an extension of standard SQL.InnoDB
没有,它是标准SQL的扩展。
Index prefixes on foreign key columns are not supported. 外键列上的索引前缀不受支持。Consequently, 因此,BLOB
and TEXT
columns cannot be included in a foreign key because indexes on those columns must always include a prefix length.BLOB
和TEXT
列不能包含在外键中,因为这些列上的索引必须始终包含前缀长度。
InnoDB
does not currently support foreign keys for tables with user-defined partitioning. InnoDB
目前不支持具有用户定义分区的表的外键。This includes both parent and child tables.这包括父表和子表。
This restriction does not apply for 此限制不适用于按NDB
tables that are partitioned by KEY
or LINEAR KEY
(the only user partitioning types supported by the NDB
storage engine); these may have foreign key references or be the targets of such references.KEY
或LINEAR KEY
分区的NDB
表(NDB
存储引擎支持的唯一用户分区类型);这些可能有外键引用或是此类引用的目标。
A table in a foreign key relationship cannot be altered to use another storage engine. 外键关系中的表不能更改为使用其他存储引擎。To change the storage engine, you must drop any foreign key constraints first.要更改存储引擎,必须先删除任何外键约束。
A foreign key constraint cannot reference a virtual generated column.外键约束无法引用虚拟生成的列。
For information about how the MySQL implementation of foreign key constraints differs from the SQL standard, see Section 1.7.2.3, “FOREIGN KEY Constraint Differences”.有关外键约束的MySQL实现如何不同于SQL标准的信息,请参阅第1.7.2.3节,“外键约束差异”。
When an 当UPDATE
or DELETE
operation affects a key value in the parent table that has matching rows in the child table, the result depends on the referential action specified by ON UPDATE
and ON DELETE
subclauses of the FOREIGN KEY
clause. UPDATE
操作或DELETE
操作影响父表中具有子表中匹配行的键值时,结果取决于FOREIGN KEY
子句的ON UPDATE
和ON DELETE
子类指定的引用操作。Referential actions include:引用操作包括:
CASCADE
: Delete or update the row from the parent table and automatically delete or update the matching rows in the child table. :从父表中删除或更新行,并自动删除或更新子表中的匹配行。Both ON DELETE CASCADE
and ON UPDATE CASCADE
are supported. ON DELETE CASCADE
和ON UPDATE CASCADE
这两者都受支持。Between two tables, do not define several 在两个表之间,不要定义多个作用于父表或子表中同一列的ON UPDATE CASCADE
clauses that act on the same column in the parent table or in the child table.ON UPDATE CASCADE
子句。
If a 如果在外键关系中的两个表上都定义了FOREIGN KEY
clause is defined on both tables in a foreign key relationship, making both tables a parent and child, an ON UPDATE CASCADE
or ON DELETE CASCADE
subclause defined for one FOREIGN KEY
clause must be defined for the other in order for cascading operations to succeed. FOREIGN KEY
子句,使两个表都成为父表和子表,则必须为另一个定义为一个FOREIGN KEY
子句定义的ON UPDATE CASCADE
或ON DELETE CASCADE
子项,以便级联操作成功。If an 如果只为一个ON UPDATE CASCADE
or ON DELETE CASCADE
subclause is only defined for one FOREIGN KEY
clause, cascading operations fail with an error.FOREIGN KEY
子句定义了ON UPDATE CASCADE
或ON DELETE CASCADE
子类,则级联操作将失败并出错。
Cascaded foreign key actions do not activate triggers.级联外键操作不会激活触发器。
SET NULL
: Delete or update the row from the parent table and set the foreign key column or columns in the child table to :删除或更新父表中的行,并将子表中的外键列设置为NULL
. NULL
。Both ON DELETE SET NULL
and ON UPDATE SET NULL
clauses are supported.ON DELETE SET NULL
和ON UPDATE SET NULL
这两个子句都受支持。
If you specify a 如果指定SET NULL
action, make sure that you have not declared the columns in the child table as NOT NULL
.SET NULL
操作,请确保未将子表中的列声明为NOT NULL
。
RESTRICT
: Rejects the delete or update operation for the parent table. :拒绝父表的删除或更新操作。Specifying 指定RESTRICT
(or NO ACTION
) is the same as omitting the ON DELETE
or ON UPDATE
clause.RESTRICT
(或NO ACTION
)与省略ON DELETE
或ON UPDATE
子句相同。
NO ACTION
: A keyword from standard SQL. :标准SQL中的关键字。In MySQL, equivalent to 在MySQL中,相当于RESTRICT
. RESTRICT
。The MySQL Server rejects the delete or update operation for the parent table if there is a related foreign key value in the referenced table. 如果引用的表中存在相关的外键值,MySQL服务器将拒绝父表的删除或更新操作。Some database systems have deferred checks, and 有些数据库系统有延迟检查,则NO ACTION
is a deferred check. NO ACTION
是延迟检查。In MySQL, foreign key constraints are checked immediately, so 在MySQL中,会立即检查外键约束,因此NO ACTION
is the same as RESTRICT
.NO ACTION
与RESTRICT
相同。
SET DEFAULT
: This action is recognized by the MySQL parser, but both :MySQL解析器可以识别此操作,但InnoDB
and NDB
reject table definitions containing ON DELETE SET DEFAULT
or ON UPDATE SET DEFAULT
clauses.InnoDB
和NDB
都拒绝包含ON DELETE SET DEFAULT
子句或ON UPDATE SET DEFAULT
子句的表定义。
For storage engines that support foreign keys, MySQL rejects any 对于支持外键的存储引擎,如果父表中没有匹配的候选键值,MySQL将拒绝尝试在子表中创建外键值的任何INSERT
or UPDATE
operation that attempts to create a foreign key value in a child table if there is no matching candidate key value in the parent table.INSERT
或UPDATE
操作。
For an 对于未指定的ON DELETE
or ON UPDATE
that is not specified, the default action is always NO ACTION
.ON DELETE
或ON UPDATE
,默认操作始终为NO ACTION
。
As the default, an 默认情况下,显式指定的ON DELETE NO ACTION
or ON UPDATE NO ACTION
clause that is specified explicitly does not appear in SHOW CREATE TABLE
output or in tables dumped with mysqldump. ON DELETE NO ACTION
或ON UPDATE NO ACTION
子句不会出现在SHOW CREATE TABLE
输出中或使用mysqldump
转储的表中。RESTRICT
, which is an equivalent non-default keyword, appears in SHOW CREATE TABLE
output and in tables dumped with mysqldump.RESTRICT
是一个等效的非默认关键字,出现在SHOW CREATE TABLE
输出中和使用mysqldump
转储的表中。
For 对于NDB
tables, ON UPDATE CASCADE
is not supported where the reference is to the parent table's primary key.NDB
表,如果引用是父表的主键,则不支持ON UPDATE CASCADE
。
As of NDB 8.0.16: For 从NDB 8.0.16开始:对于NDB
tables, ON DELETE CASCADE
is not supported where the child table contains one or more columns of any of the TEXT
or BLOB
types. NDB
表,如果子表包含任何TEXT
或BLOB
类型的一列或多列,则不支持ON DELETE CASCADE
。(Bug #89511, Bug #27484882)
InnoDB
performs cascading operations using a depth-first search algorithm on the records of the index that corresponds to the foreign key constraint.InnoDB
使用深度优先搜索算法对与外键约束对应的索引记录执行级联操作。
A foreign key constraint on a stored generated column cannot use 存储的生成列上的外键约束不能在更新引用操作上使用CASCADE
, SET NULL
, or SET DEFAULT
as ON UPDATE
referential actions, nor can it use SET NULL
or SET DEFAULT
as ON DELETE
referential actions.CASCADE
、SET NULL
或SET DEFAULT
,也不能在删除引用操作上使用SET NULL
或SET DEFAULT
。
A foreign key constraint on the base column of a stored generated column cannot use 存储的生成列的基列上的外键约束不能在CASCADE
, SET NULL
, or SET DEFAULT
as ON UPDATE
or ON DELETE
referential actions.ON UPDATE
或ON DELETE
引用操作时使用CASCADE
、SET NULL
或SET DEFAULT
。
This simple example relates 此简单示例通过单列外键关联parent
and child
tables through a single-column foreign key:parent
表和child
表:
CREATE TABLE parent ( id INT NOT NULL, PRIMARY KEY (id) ) ENGINE=INNODB; CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ) ENGINE=INNODB;
This is a more complex example in which a 这是一个更复杂的示例,其中一个product_order
table has foreign keys for two other tables. product_order
表具有另外两个表的外键。One foreign key references a two-column index in the 一个外键引用product
table. product
表中的两列索引。The other references a single-column index in the 另一个引用customer
table:customer
表中的单列索引:
CREATE TABLE product ( category INT NOT NULL, id INT NOT NULL, price DECIMAL, PRIMARY KEY(category, id) ) ENGINE=INNODB; CREATE TABLE customer ( id INT NOT NULL, PRIMARY KEY (id) ) ENGINE=INNODB; CREATE TABLE product_order ( no INT NOT NULL AUTO_INCREMENT, product_category INT NOT NULL, product_id INT NOT NULL, customer_id INT NOT NULL, PRIMARY KEY(no), INDEX (product_category, product_id), INDEX (customer_id), FOREIGN KEY (product_category, product_id) REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, FOREIGN KEY (customer_id) REFERENCES customer(id) ) ENGINE=INNODB;
You can add a foreign key constraint to an existing table using the following 可以使用以下ALTER TABLE
syntax:ALTER TABLE
语法将外键约束添加到现有表中:
ALTER TABLEtbl_name
ADD [CONSTRAINT [symbol
]] FOREIGN KEY [index_name
] (col_name
, ...) REFERENCEStbl_name
(col_name
,...) [ON DELETEreference_option
] [ON UPDATEreference_option
]
The foreign key can be self referential (referring to the same table). 外键可以是自引用的(引用同一个表)。When you add a foreign key constraint to a table using 使用ALTER TABLE
, remember to first create an index on the column(s) referenced by the foreign key.ALTER TABLE
向表中添加外键约束时,请记住首先在外键引用的列上创建索引。
You can drop a foreign key constraint using the following 可以使用以下ALTER TABLE语法删除外键约束:ALTER TABLE
syntax:
ALTER TABLEtbl_name
DROP FOREIGN KEYfk_symbol
;
If the 如果在创建约束时FOREIGN KEY
clause defined a CONSTRAINT
name when you created the constraint, you can refer to that name to drop the foreign key constraint. FOREIGN KEY
子句定义了CONSTRAINT
名称,则可以引用该名称来删除外键约束。Otherwise, a constraint name was generated internally, and you must use that value. 否则,将在内部生成约束名称,您必须使用该值。To determine the foreign key constraint name, use 要确定外键约束名称,请使用SHOW CREATE TABLE
:SHOW CREATE TABLE
:
mysql>SHOW CREATE TABLE child\G
*************************** 1. row *************************** Table: child Create Table: CREATE TABLE `child` ( `id` int DEFAULT NULL, `parent_id` int DEFAULT NULL, KEY `par_ind` (`parent_id`), CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci mysql>ALTER TABLE child DROP FOREIGN KEY `child_ibfk_1`;
Adding and dropping a foreign key in the same ALTER TABLE
statement is supported for ALTER TABLE ... ALGORITHM=INPLACE
. ALTER TABLE ... ALGORITHM=INPLACE
支持在同一ALTER TABLE
语句中添加和删除外键。It is not supported for ALTER TABLE ... ALGORITHM=COPY
.ALTER TABLE ... ALGORITHM=COPY
不支持它。
Foreign key checking is controlled by the 外键检查由默认启用的foreign_key_checks
variable, which is enabled by default. foreign_key_checks
变量控制。Typically, you leave this variable enabled during normal operation to enforce referential integrity. 通常,您会在正常操作期间启用此变量以强制引用完整性。The foreign_key_checks
variable has the same effect on NDB
tables as it does for InnoDB
tables.foreign_key_checks
变量对NDB
表的作用与对InnoDB
表的作用相同。
The foreign_key_checks
variable is dynamic and supports both global and session scopes. foreign_key_checks
变量是动态的,同时支持全局范围和会话范围。For information about using system variables, see Section 5.1.9, “Using System Variables”.有关使用系统变量的信息,请参阅第5.1.9节,“使用系统变量”。
Disabling foreign key checking is useful when:在以下情况下禁用外键检查很有用:
Dropping a table that is referenced by a foreign key constraint. 删除外键约束引用的表。A referenced table can only be dropped after 只有在禁用foreign_key_checks
is disabled. foreign_key_checks
后,才能删除引用的表。When you drop a table, constraints defined on the table are also dropped.删除表时,也会删除表上定义的约束。
Reloading tables in different order than required by their foreign key relationships. 按与其外键关系不同的顺序重新加载表。For example, mysqldump produces correct definitions of tables in the dump file, including foreign key constraints for child tables. 例如,mysqldump
在转储文件中生成正确的表定义,包括子表的外键约束。To make it easier to reload dump files for tables with foreign key relationships, mysqldump automatically includes a statement in the dump output that disables 为了更容易地为具有外键关系的表重新加载转储文件,foreign_key_checks
. mysqldump
在转储输出中自动包含一条语句,该语句禁用foreign_key_checks
。This enables you to import the tables in any order in case the dump file contains tables that are not correctly ordered for foreign keys. 这使您能够在转储文件包含外键顺序不正确的表的情况下以任何顺序导入表。Disabling 禁用foreign_key_checks
also speeds up the import operation by avoiding foreign key checks.foreign_key_checks
也可以通过避免外键检查来加快导入操作。
Executing 执行LOAD DATA
operations, to avoid foreign key checking.LOAD DATA
操作,以避免外键检查。
Performing an 对具有外键关系的表执行ALTER TABLE
operation on a table that has a foreign key relationship.ALTER TABLE
操作。
When 禁用foreign_key_checks
is disabled, foreign key constraints are ignored, with the following exceptions:foreign_key_checks
时,将忽略外键约束,但以下情况除外:
Recreating a table that was previously dropped returns an error if the table definition does not conform to the foreign key constraints that reference the table. 如果表定义不符合引用该表的外键约束,则重新创建以前删除的表将返回错误。The table must have the correct column names and types. 表必须具有正确的列名和类型。It must also have indexes on the referenced keys. 它还必须在引用的键上具有索引。If these requirements are not satisfied, MySQL returns Error 1005 that refers to errno: 150 in the error message, which means that a foreign key constraint was not correctly formed.如果不满足这些要求,MySQL将返回错误1005,该错误消息中引用了errno:150,这意味着外键约束的格式不正确。
Altering a table returns an error (errno: 150) if a foreign key definition is incorrectly formed for the altered table.如果更改表的外键定义格式不正确,则更改表将返回错误(errno:150)。
Dropping an index required by a foreign key constraint. 删除外键约束所需的索引。The foreign key constraint must be removed before dropping the index.在删除索引之前,必须删除外键约束。
Creating a foreign key constraint where a column references a nonmatching column type.创建列引用不匹配列类型的外键约束。
Disabling 禁用foreign_key_checks
has these additional implications:foreign_key_checks
会产生以下额外影响:
It is permitted to drop a database that contains tables with foreign keys that are referenced by tables outside the database.允许删除包含由数据库外部的表引用的外键表的数据库。
It is permitted to drop a table with foreign keys referenced by other tables.允许删除包含其他表引用的外键的表。
Enabling 启用foreign_key_checks
does not trigger a scan of table data, which means that rows added to a table while foreign_key_checks
is disabled are not checked for consistency when foreign_key_checks
is re-enabled.foreign_key_checks
不会触发表数据扫描,这意味着在禁用foreign_key_checks
时添加到表中的行在重新启用foreign_key_checks
时不会检查一致性。
MySQL extends metadata locks, as necessary, to tables that are related by a foreign key constraint. MySQL根据需要将元数据锁扩展到与外键约束相关的表。Extending metadata locks prevents conflicting DML and DDL operations from executing concurrently on related tables. 扩展元数据锁可防止冲突的DML和DDL操作在相关表上并发执行。This feature also enables updates to foreign key metadata when a parent table is modified. 此功能还允许在修改父表时更新外键元数据。In earlier MySQL releases, foreign key metadata, which is owned by the child table, could not be updated safely.在早期的MySQL版本中,子表拥有的外键元数据无法安全更新。
If a table is locked explicitly with 如果表被LOCK TABLES
, any tables related by a foreign key constraint are opened and locked implicitly. LOCK TABLES
显式锁定,则与外键约束相关的任何表都将被打开并隐式锁定。For foreign key checks, a shared read-only lock (对于外键检查,在相关表上使用共享只读锁(LOCK TABLES READ
) is taken on related tables. LOCK TABLES READ
)。For cascading updates, a shared-nothing write lock (对于级联更新,对操作中涉及的相关表执行无共享写锁(LOCK TABLES WRITE
) is taken on related tables that are involved in the operation.LOCK TABLES WRITE
)。
To view a foreign key definition, use 要查看外键定义,请使用SHOW CREATE TABLE
:SHOW CREATE TABLE
:
mysql> SHOW CREATE TABLE child\G
*************************** 1. row ***************************
Table: child
Create Table: CREATE TABLE `child` (
`id` int DEFAULT NULL,
`parent_id` int DEFAULT NULL,
KEY `par_ind` (`parent_id`),
CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`)
REFERENCES `parent` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
You can obtain information about foreign keys from the 您可以从INFORMATION_SCHEMA.KEY_COLUMN_USAGE
table. INFORMATION_SCHEMA.KEY_COLUMN_USAGE
表中获取有关外键的信息。An example of a query against this table is shown here:针对该表的查询示例如下所示:
mysql>SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_SCHEMA IS NOT NULL;
+--------------+------------+-------------+-----------------+ | TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | +--------------+------------+-------------+-----------------+ | test | child | parent_id | child_ibfk_1 | +--------------+------------+-------------+-----------------+
You can obtain information specific to 您可以从InnoDB
foreign keys from the INNODB_FOREIGN
and INNODB_FOREIGN_COLS
tables. INNODB_FOREIGN
和INNODB_FOREIGN_COLS
表中获取特定于InnoDB
外键的信息。Example queries are show here:示例查询如下所示:
mysql>SELECT * FROM INFORMATION_SCHEMA.INNODB_FOREIGN \G
*************************** 1. row *************************** ID: test/child_ibfk_1 FOR_NAME: test/child REF_NAME: test/parent N_COLS: 1 TYPE: 1 mysql>SELECT * FROM INFORMATION_SCHEMA.INNODB_FOREIGN_COLS \G
*************************** 1. row *************************** ID: test/child_ibfk_1 FOR_COL_NAME: parent_id REF_COL_NAME: id POS: 0
In the event of a foreign key error involving 如果出现涉及InnoDB
tables (usually Error 150 in the MySQL Server), information about the latest foreign key error can be obtained by checking SHOW ENGINE INNODB STATUS
output.InnoDB
表的外键错误(MySQL服务器中通常为错误150),可以通过检查SHOW ENGINE INNODB STATUS
输出来获取有关最新外键错误的信息。
mysql> SHOW ENGINE INNODB STATUS\G ... ------------------------ LATEST FOREIGN KEY ERROR ------------------------ 2018-04-12 14:57:24 0x7f97a9c91700 Transaction: TRANSACTION 7717, ACTIVE 0 sec inserting mysql tables in use 1, locked 1 4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 3 MySQL thread id 8, OS thread handle 140289365317376, query id 14 localhost root update INSERT INTO child VALUES (NULL, 1), (NULL, 2), (NULL, 3), (NULL, 4), (NULL, 5), (NULL, 6) Foreign key constraint fails for table `test`.`child`: , CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) ON DELETE CASCADE ON UPDATE CASCADE Trying to add in child table, in index par_ind tuple: DATA TUPLE: 2 fields; 0: len 4; hex 80000003; asc ;; 1: len 4; hex 80000003; asc ;; But in parent table `test`.`parent`, in index PRIMARY, the closest match we can find is record: PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000004; asc ;; 1: len 6; hex 000000001e19; asc ;; 2: len 7; hex 81000001110137; asc 7;; ...
If a user has table-level privileges for all parent tables, 如果用户对所有父表都具有表级权限,则外键操作的ER_NO_REFERENCED_ROW_2
and ER_ROW_IS_REFERENCED_2
error messages for foreign key operations expose information about parent tables. ER_NO_REFERENCED_ROW_2
和ER_ROW_IS_REFERENCED_2
错误消息将公开有关父表的信息。If a user does not have table-level privileges for all parent tables, more generic error messages are displayed instead (如果用户不具有所有父表的表级权限,则会显示更一般的错误消息(ER_NO_REFERENCED_ROW
and ER_ROW_IS_REFERENCED
).ER_NO_REFERENCED_ROW
和ER_ROW_IS_REFERENCED
)。
An exception is that, for stored programs defined to execute with 例外情况是,对于定义为使用DEFINER
privileges, the user against which privileges are assessed is the user in the program DEFINER
clause, not the invoking user. DEFINER
权限执行的存储程序,评估权限的用户是程序DEFINER
子句中的用户,而不是调用用户。If that user has table-level parent table privileges, parent table information is still displayed. 如果该用户具有表级父表权限,则仍会显示父表信息。In this case, it is the responsibility of the stored program creator to hide the information by including appropriate condition handlers.在这种情况下,存储程序创建者有责任通过包含适当的条件处理程序来隐藏信息。