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

时间:2013-09-21 07:28:53

标签: mysql sql database

我已阅读数据库系统概念,第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

在谷歌搜索外键约束后,我刚刚得知“外键约束”这个词表示表course中的外键列数据必须存在于表{{1}的主键列中}}。但是在插入数据时我应该遇到这个错误。

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

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

编辑:在dept_name中输入set foreign_key_checks=0无法解决错误。

mysql>

16 个答案:

答案 0 :(得分:64)

当您收到此模糊错误消息时,您可以通过运行

找出更具体的错误
SHOW ENGINE INNODB STATUS;

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

  • 引擎应该是相同的,例如。 InnoDB
  • 数据类型应该相同,长度相同 e.g。 VARCHAR(20)或INT(10)UNSIGNED
  • 整理应该相同。 e.g。 utf8
  • 唯一 - 外键应引用参考表中唯一(通常为私有)的字段。

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

答案 1 :(得分:46)

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

中找到更多信息

答案 2 :(得分:23)

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

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

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

答案 3 :(得分:6)

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。使用FOREIGN KEY约束

     

... [{1}}或CREATE TABLE语句中的外键约束定义的基本语法如下所示:

ALTER TABLE

答案 4 :(得分:4)

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

我做了一个ALTER TABLE并意外删除了列的主键状态,并得到了这个错误。

答案 5 :(得分:4)

  

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

还值得注意的是,当另一个版本中作为外键的列的类型未明确匹配正确表中的列时,会出现此错误。

例如:

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    |                |

id表中的student字段定义为:

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

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

答案 6 :(得分:2)

  

我不像你那样遇到问题。但是我收到了同样的错误消息。所以我在这里将其标记为其他人的便利。

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

ERROR 1215 (HY000): Cannot add foreign key constraint

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

答案 7 :(得分:1)

只需添加' unsigned'对于FOREIGN约束

`FK` int(11) unsigned DEFAULT NULL,

答案 8 :(得分:1)

以下代码为我工作

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

我没有看到任何人明确说明这一点,我有同样的错误消息,我的问题是我试图将一个外键添加到TEMPORARY表。这被禁止为noted in the manual

  

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

(强调我的)

答案 11 :(得分:0)

我也遇到了同样的问题。不知道为什么这有效但它确实有效: 尝试在创建查询后添加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;

答案 12 :(得分:0)

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

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

答案 13 :(得分:0)

在我的字符集中,所有类型的数据类型都是正确的。经过调查,我发现在父表中外键列上没有索引。一旦添加了问题就解决了。

enter image description here

答案 14 :(得分:0)

当我尝试从PhpAdminMySQL导出导入(在MysqlWorkbench中)时出现此错误。验证后,我使用以下命令禁用了唯一键和外键:

SET unique_checks=0;
SET foreign_key_checks = 0;

我仍然遇到相同的错误(MySQL:错误1215(HY000):无法添加外键约束)。该create语句发生错误。

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!

答案 15 :(得分:-1)

CONSTRAINT vendor_tbfk_1 FOREIGN KEY (V_CODE) REFERENCES vendor (V_CODE) ON UPDATE CASCADE

这是怎么回事......看一下引用列部分。 (V_code)