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

inh*_*dle 56 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    |       |
+-----------+---------------+------+-----+---------+-------+
Run Code Online (Sandbox Code Playgroud)

创建表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
Run Code Online (Sandbox Code Playgroud)

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

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

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

编辑:输入set foreign_key_checks=0mysql>不修复错误.

------------------------
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
Run Code Online (Sandbox Code Playgroud)

am0*_*0wa 71

当您收到这个模糊的错误消息时,您可以通过运行找出更具体的错误

SHOW ENGINE INNODB STATUS;
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 我刚刚被绊倒,因为一个字段是"未签名"而另一个字段不是,所以只需编辑你的答案就可以包含它.希望没关系. (4认同)
  • 遇到了同样的问题:如果使用`ON DELETE SET NULL`,则所有列似乎都可以为空.[这是另一个问题](http://stackoverflow.com/q/33735266/57091). (2认同)
  • 我收到这个错误是因为引用的表没有用 `ENGINE=InnoDB` 标记 - 这从 `SHOW ENGINE INNODB STATUS;` 的 ***非常糟糕*** 格式化的输出中也不明显 (2认同)

Str*_*k3r 47

FOREIGN KEYfor 的语法CREATE TABLE结构如下:

FOREIGN KEY (index_col_name)
        REFERENCES table_name (index_col_name,...)
Run Code Online (Sandbox Code Playgroud)

所以你的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)
    );
Run Code Online (Sandbox Code Playgroud)

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

可以在MySQL文档中找到更多信息


小智 24

也许你的dept_name专栏有不同的字符集.

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

ALTER TABLE department MODIFY dept_name VARCHAR(20) CHARACTER SET utf8;
ALTER TABLE course MODIFY dept_name VARCHAR(20) CHARACTER SET utf8;
Run Code Online (Sandbox Code Playgroud)


ta.*_*.is 6

foreign key (dept_name) references department
Run Code Online (Sandbox Code Playgroud)

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

foreign key (dept_name) references department(dept_name)
Run Code Online (Sandbox Code Playgroud)

MySQL需要dept_name使用两次.一旦定义外来列,一次定义主列.

13.1.17.2.使用FOREIGN KEY约束

... [在]在一个外键约束定义必要的语法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
Run Code Online (Sandbox Code Playgroud)


Jac*_*son 5

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

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


Gra*_*ray 5

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
Run Code Online (Sandbox Code Playgroud)

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

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

而表中的id字段student定义为:

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

bigint(20)(从Java产生long的休眠)不兼容int(10) unsigned(Java int)。