MySQL : ERROR 1215 (HY000): 无法添加外键约束

Posted

技术标签:

【中文标题】MySQL : ERROR 1215 (HY000): 无法添加外键约束【英文标题】:MySQL : ERROR 1215 (HY000): Cannot add foreign key constraint 【发布时间】:2013-09-26 15:03:56 【问题描述】:

我已阅读 数据库系统概念,第 6 版,Silberschatz。我将在 mysql 上的 OS X 上实现第 2 章中所示的大学数据库系统。但是我在创建表course 时遇到了麻烦。表department 看起来像

mysql> select * from department
    -> ;
+------------+----------+-----------+
| dept_name  | building | budget    |
+------------+----------+-----------+
| Biology    | Watson   |  90000.00 |
| Comp. Sci. | Taylor   | 100000.00 |
| Elec. Eng. | Taylor   |  85000.00 |
| Finance    | Painter  | 120000.00 |
| History    | Painter  |  50000.00 |
| Music      | Packard  |  80000.00 |
| Physics    | Watson   |  70000.00 |
+------------+----------+-----------+

mysql> show columns from department
    -> ;
+-----------+---------------+------+-----+---------+-------+
| Field     | Type          | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+-------+
| dept_name | varchar(20)   | NO   | PRI |         |       |
| building  | varchar(15)   | YES  |     | NULL    |       |
| budget    | decimal(12,2) | YES  |     | NULL    |       |
+-----------+---------------+------+-----+---------+-------+

创建表course会导致以下错误。

mysql> create table course
    -> (course_id varchar(7),
    -> title varchar (50),
    -> dept_name varchar(20),
    -> credits numeric(2,0),
    -> primary key(course_id),
    -> foreign key (dept_name) references department);
ERROR 1215 (HY000): Cannot add foreign key constraint

在google上搜索外键约束后,我才知道“外键约束”这个词表示表course中的外键列的数据必须存在于表department的主键列中。但是我应该在插入数据时遇到这个错误。

如果不是,为什么作者让我执行那个 SQL 语句?

如果我真的执行了错误的SQL语句,插入一些数据后是否必须在课程表中指定dept_name作为外键?

编辑:在mysql> 中输入set foreign_key_checks=0 并不能修复错误。

------------------------
LATEST FOREIGN KEY ERROR
------------------------
2013-09-21 16:02:20 132cbe000 Error in foreign key constraint of table university/course:
foreign key (dept_name) references department):
Syntax error close to:
)
mysql> set foreign_key_checks=0
    -> ;
Query OK, 0 rows affected (0.00 sec)
mysql> create table course
    -> (course_id varchar(7),
    -> title varchar(50),
    -> dept_name varchar(20),
    -> credits numeric(2,0),
    -> primary key(course_id),
    -> foreign key (dept_name) references department);
ERROR 1215 (HY000): Cannot add foreign key constraint

【问题讨论】:

***.com/a/15535110/242520 两个表中的所有 dept_name 都是 varchar(15)。我必须在哪里输入set foreign_key_checks=0 LATEST FOREIGN KEY ERROR 说什么? foreign key (dept_name) references department 是 ANSI 标准 SQL。也许作者没有使用 MySQL,而是使用了更符合标准的 DBMS。 @inherithandle:作者确实给了你正确的SQL,只是MySQL在这方面(以及许多其他)不符合ANSI标准 【参考方案1】:

当你得到这个模糊的错误信息时,你可以通过运行找出更具体的错误

SHOW ENGINE INNODB STATUS;

最常见的原因是创建外键时,被引用的字段和外键字段都需要匹配:

Engine 应该是相同的 e.g. InnoDB 数据类型应该相同,并且长度相同。例如VARCHAR(20) 或 INT(10) 无符号 排序规则应该相同。 例如utf8 唯一 - 外键应该引用引用表中唯一的字段(通常是私有的)

此错误的另一个原因是:尽管某些列被定义为 NOT NULL,但您已经定义了 SET NULL 条件。

【讨论】:

我刚刚被绊倒了,因为一个字段是 UNSIGNED 而另一个不是,所以只需编辑您的答案以包含该字段。希望没关系。 @SimonEast 为我指出正确的方向有同样的问题:) 这应该是已接受的答案,因为它对找到此页面并寻找问题解决方案的人最有帮助 遇到了同样的问题:如果使用ON DELETE SET NULL,所有列都必须看起来可以为空。 Here is another question. 我收到了这个错误,因为引用的表没有用ENGINE=InnoDB 标记 - 这在 very badly 格式的输出中也不明显SHOW ENGINE INNODB STATUS;【参考方案2】:

FOREIGN KEY 对应 CREATE TABLE 的语法结构如下:

FOREIGN KEY (index_col_name)
        REFERENCES table_name (index_col_name,...)

所以你的 MySQL DDL 应该是:

 create table course (
        course_id varchar(7),
        title varchar(50),
        dept_name varchar(20),
        credits numeric(2 , 0 ),
        primary key (course_id),
        FOREIGN KEY (dept_name)
            REFERENCES department (dept_name)
    );

另外,在department 表中dept_name 应该是VARCHAR(20)

更多信息可以在MySQL documentation找到

【讨论】:

我很乐意为您详细解释该语句是什么。我从未见过CONSTRAINT 的声明。 CONSTRAINT link_dept_course 给这种关系一个符号。它是可选的。如果没有给出子句,或者 CONSTRAINT 关键字后面没有包含符号,则会自动创建约束名称。仅供参考:dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html 约束部分是可选的,但是PK列的列表不是。所以references departmentreferences department (dept_name) 确实修复了它。我不知道 MySQL 不支持“速记”表示法(由 SQL 标准定义) 我还发现如果你的表有多个主键列,外键约束将无法添加。【参考方案3】:

也许您的dept_name 列有不同的字符集。

您可以尝试更改其中一个或两个:

ALTER TABLE department MODIFY dept_name VARCHAR(20) CHARACTER SET utf8;
ALTER TABLE course MODIFY dept_name VARCHAR(20) CHARACTER SET utf8;

【讨论】:

那个很棘手。我有一个表使用明确的 UTF8,而不是另一个。迁移到不使用 UTF8 作为默认值的服务器时,工作模式停止工作。这救了我! 感谢您的回答,在我的情况下,主键是 utf8_bin,而“wannabe-foreign”是 utf8_general_ci。这也救了我!【参考方案4】:
foreign key (dept_name) references department

此语法对 MySQL 无效。它应该是:

foreign key (dept_name) references department(dept_name)

MySQL requires dept_name to be used twice。一次定义外部列,一次定义主列。

13.1.17.2。使用外键约束

...CREATE TABLEALTER TABLE 语句中外键约束定义的基本语法如下所示:

[CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name, ...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]

reference_option:
    RESTRICT | CASCADE | SET NULL | NO ACTION

【讨论】:

【参考方案5】:

如果外键不是自己表中的主键,也可能出现此错误。

我做了一个 ALTER TABLE 并且不小心删除了一个列的主键状态,并得到了这个错误。

【讨论】:

【参考方案6】:

ERROR 1215 (HY000): 无法添加外键约束

还值得注意的是,当另一个able 中作为外键的列的type 与正确表中的列不显式匹配时,您会收到此错误。

例如:

alter table schoolPersons
         add index FKEF5AB5E532C8FBFA (student_id),
         add constraint FKEF5AB5E532C8FBFA
         foreign key (student_id)
         references student (id);
ERROR 1215 (HY000): Cannot add foreign key constraint

这是因为student_id 字段被定义为:

mysql> desc schoolPersons;
+--------------------+------------+------+-----+---------+----------------+
| Field              | Type       | Null | Key | Default | Extra          |
+--------------------+------------+------+-----+---------+----------------+
| student_id         | bigint(20) | YES  |     | NULL    |                |

student 表中的id 字段定义为:

mysql> desc persons;
+--------------+----------------------+------+-----+-------------------+-----------------+
| Field        | Type                 | Null | Key | Default           | Extra           |
+--------------+----------------------+------+-----+-------------------+-----------------+
| id           | int(10) unsigned     | NO   | PRI | NULL              | auto_increment  |

bigint(20)(由 java long 通过 hibernate 生成)与 int(10) unsigned(Java int)不兼容。

【讨论】:

【参考方案7】:

只需为 FOREIGN 约束添加“无符号”

`FK` int(11) unsigned DEFAULT NULL,

【讨论】:

【参考方案8】:

我不像你那样遇到问题。但我收到相同的错误消息。所以我把它标记在这里以方便其他人。

如果列类型为charvarchar,请检查两个表的字符集。我使用charset=gbk,但我创建了一个默认为charset=utf8 的新表。所以字符集不一样。

ERROR 1215 (HY000): Cannot add foreign key constraint

要解决它是使用相同的字符集。例如utf8

【讨论】:

【参考方案9】:

值得注意的是,如果您在 REFERENCES 部分中使用的目标表或列根本不存在,也会发生此错误。

【讨论】:

【参考方案10】:

以下代码对我有用

set @@foreign_key_checks=0;
ALTER TABLE  `table1` ADD CONSTRAINT `table1_fk1` FOREIGN KEY (`coloumn`) REFERENCES `table2` (`id`) ON DELETE CASCADE;

【讨论】:

【参考方案11】:

在我的情况下,父表和子表之间的引擎是不同的。使引擎相等是有效的

问题: 父表 'engine' => 'MyISAM', 子表 'engine' => 'innoDB',

更正: 父表 'engine' => 'MyISAM', 子表 'engine' => 'MyISAM',

【讨论】:

这并不能真正回答问题。如果您有其他问题,可以点击 进行提问。要在此问题有新答案时收到通知,您可以follow this question。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review【参考方案12】:

我没有看到任何人明确说明这一点,并且我收到了同样的错误消息,我的问题是我试图将外键添加到 TEMPORARY 表中。不允许使用noted in the manual

外键关系涉及一个包含中心数据值的父表,以及一个具有相同值的子表指向其父表。 FOREIGN KEY 子句在子表中指定。父表和子表必须使用相同的存储引擎。 它们不能是 TEMPORARY 表。

(强调我的)

【讨论】:

【参考方案13】:

我也遇到了同样的问题。不知道为什么这是有效的,但它确实有效: 尝试在创建查询后添加 ENGINE INNODB。

mysql> create table course
-> (course_id varchar(7),
-> title varchar (50),
-> dept_name varchar(20),
-> credits numeric(2,0),
-> primary key(course_id),
-> foreign key (dept_name) references department) ENGINE INNODB;

【讨论】:

【参考方案14】:

即使这与您的情况没有直接联系,它也可能有助于进一步的读者注意,如果您不遵守创建数据库表的顺序,您在键入show engine innodb mstatus 时会得到完全相同的错误输出;这意味着您不能添加引用尚不存在的表的外部约束。引用表必须在指向它的表之前存在。

当遵守表创建顺序但不遵守外键约束中涉及的列时也是如此。

【讨论】:

【参考方案15】:

在我的例子中,charset 中的数据类型都是正确的。经过调查,我发现在父表中,外键列上没有索引。一旦添加的问题得到解决。

【讨论】:

【参考方案16】:

当我尝试从 phpAdminMySQL 导出中导入(在 MysqlWorkbench 中)时,我遇到了这个错误。验证后我已禁用唯一键和外键:

SET unique_checks=0;
SET foreign_key_checks = 0;

我仍然遇到同样的错误(MySQL : ERROR 1215 (HY000): Cannot add foreign key constraint)。此创建语句发生错误。

DROP TABLE IF EXISTS `f1_pool`;
CREATE TABLE `f1_pool` (
 `id` int(11) NOT NULL,
 `name` varchar(45) NOT NULL,
 `description` varchar(45) DEFAULT NULL COMMENT 'Optional',
 `ownerId` int(11) NOT NULL,
 `lastmodified` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

没有外键或唯一索引,那么这里出了什么问题? 最后(令人费解的 90 分钟后)我决定重新启动 MySQL 并通过一项修改再次进行导入:我在导入之前删除了所有表。 并且没有错误,所有功能正常,表和视图恢复。 所以我的建议,如果一切正常,首先尝试重启 MySQL!

【讨论】:

【参考方案17】:

请注意,它可以是几种不同的东西。

在我的情况下,它是表/字段排序规则:

FK 目标:CHARSET=utf8 COLLATE=utf8_unicode_ci FK 源字段:CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

【讨论】:

【参考方案18】:
CONSTRAINT vendor_tbfk_1 FOREIGN KEY (V_CODE) REFERENCES vendor (V_CODE) ON UPDATE CASCADE

可能是这样...查看引用列部分。 (V_code)

【讨论】:

以上是关于MySQL : ERROR 1215 (HY000): 无法添加外键约束的主要内容,如果未能解决你的问题,请参考以下文章

mysql ERROR 1215 (HY000): Cannot add foreign key constraint

mysql执行带外键的sql文件时出现mysql ERROR 1215 (HY000): Cannot add foreign key constraint的解决

ERROR 1215 (HY000): Cannot add foreign key constraint

我无法将我的 SQL 表从 Adminer 导入 MySQL Workbench 而不会出现错误:第 9 行的错误 1215 (HY000):无法添加外键约束

MySQL 错误 [1215] [HY000] - 无法添加外键 [重复]

MySQL ERROR 1356 (HY000)