MySQL无法创建外键约束

问题描述 投票:48回答:9

我在创建mysql数据库中现有表的外键时遇到了一些问题。

我有桌子exp

+-------------+------------------+------+-----+---------+-------+
| Field       | Type             | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| EID         | varchar(45)      | NO   | PRI | NULL    |       |
| Comment     | text             | YES  |     | NULL    |       |
| Initials    | varchar(255)     | NO   |     | NULL    |       |
| ExpDate     | date             | NO   |     | NULL    |       |
| InsertDate  | date             | NO   |     | NULL    |       |
| inserted_by | int(11) unsigned | YES  | MUL | NULL    |       |
+-------------+------------------+------+-----+---------+-------+

我不想使用以下内容创建一个名为sample_df的新表引用它:

CREATE TABLE sample_df (
df_id mediumint(5) unsigned AUTO_INCREMENT primary key,
sample_type mediumint(5) unsigned NOT NULL,
df_10 BOOLEAN NOT NULL,
df_100 BOOLEAN NOT NULL,
df_1000 BOOLEAN NOT NULL,
df_above_1000 BOOLEAN NOT NULL,
target INT(11) unsigned NOT NULL,
assay MEDIUMINT(5) unsigned zerofill NOT NULL,
insert_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
inserted_by INT(11) unsigned NOT NULL,
initials varchar(255),
experiment VARCHAR(45),
CONSTRAINT FOREIGN KEY (inserted_by) REFERENCES user (iduser),
CONSTRAINT FOREIGN KEY (target) REFERENCES protein (PID),
CONSTRAINT FOREIGN KEY (sample_type) REFERENCES sample_type (ID),
CONSTRAINT FOREIGN KEY (assay) REFERENCES assays (AID),
CONSTRAINT FOREIGN KEY (experiment) REFERENCES exp (EID)
);

但我得到错误:

ERROR 1215 (HY000): Cannot add foreign key constraint

为了获得更多信息,我做了:

SHOW ENGINE INNODB STATUS\G

我得到了:

FOREIGN KEY (experiment) REFERENCES exp (EID)
):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.

对我来说,列类型似乎匹配,因为它们都是varchar(45)。(我也尝试将experiment列设置为not null,但这并没有解决它)所以我想问题必须是Cannot find an index in the referenced table where the referenced columns appear as the first columns。但我不太清楚这意味着什么,或者如何检查/修复它。有没有人有什么建议?什么是first columns的意思?

mysql indexing foreign-keys
9个回答
96
投票

只是把它扔进可能原因的混合中,当参考表列具有相同的“类型”但没有相同的签名时,我遇到了这个问题。

在我的例子中,引用的表列是TINYINT UNSIGNED,我的引用表列是TINYINT SIGNED。对齐两列都解决了这个问题。


0
投票

在某些情况下,我必须在将引用字段定义为主键时使其唯一。

但我发现,不将其定义为唯一不会在每种情况下都产生问题。但我还是无法弄清楚这些情景。可能与可空定义有关。


19
投票

根据http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html

MySQL需要外键和引用键的索引,以便外键检查可以快速,不需要表扫描。在引用表中,必须有一个索引,其中外键列以相同的顺序列为第一列。

InnoDB允许外键引用任何索引列或列组。但是,在引用的表中,必须有一个索引,其中引用的列被列为相同顺序的第一列。

因此,如果引用表中的索引存在且它由多个列组成,并且所需的列不是第一个,则应该发生错误。

我们错误的原因是由于违反了以下规则:

外键和引用键中的相应列必须具有相似的数据类型。整数类型的大小和符号必须相同。字符串类型的长度不必相同。对于非二进制(字符)字符串列,字符集和排序规则必须相同。


10
投票

正如@Anton所提到的,这可能是因为数据类型不同。在我的情况下,我有主键BIGINT(20)并尝试设置INT(10)的前键


10
投票

如果引用表和当前表不具有相同的字符集,也会发生此错误。


5
投票

在我的例子中,事实证明引用的列未声明为主要或唯一。

https://stackoverflow.com/a/18435114/1763217


1
投票

主键的确切顺序也需要匹配,中间不需要额外的列。

我有一个主键设置,其中列顺序实际匹配,但问题是主键有一个额外的列,它不是引用表的外键的一部分

例如)表2,列(a,b,c) - >表1,列(a,b,d,c) - 此失败

我不得不重新排序主键列,这样不仅它们以相同的方式排序,而且中间没有额外的列:

例如)表2,列(a,b,c) - >表1,列(a,b,c,d) - 本次成功


0
投票

在同一约束中多次引用同一列也会产生此Cannot find an index in the referenced table错误,但很难在大型表上发现。拆分约束,它将按预期工作。


0
投票

我也有这个错误。没有一个答案与我有关。在我的例子中,我的GUI自动创建一个主要唯一标识符为“未分配”的表。当我尝试创建外键并给出完全相同的错误时,这会失败。我的主键需要分配。

如果你像这样编写SQL本身id int unique auto_increment然后你没有这个问题,但由于某种原因我的GUI这样做而不是id int unassigned unique auto_increment

希望这可以帮助其他人。


0
投票

我是引用表和要创建的表之间的排序规则问题,因此我必须显式设置我引用的键的排序规则类型。

  • 首先,我在引用的表上运行查询以获取其排序规则类型
show table STATUS like '<table_name_here>';
  • 然后我复制了排序规则类型,并在创建查询中明确声明了employee_id的排序规则类型。就我而言,它是utf8_general_ci
CREATE TABLE dbo.sample_db
(
  id INT PRIMARY KEY AUTO_INCREMENT,
  event_id INT SIGNED NOT NULL,
  employee_id varchar(45) COLLATE utf8_general_ci NOT NULL,
  event_date_time DATETIME,
  CONSTRAINT sample_db_event_event_id_fk FOREIGN KEY (event_id) REFERENCES event (event_id),
  CONSTRAINT sample_db_employee_employee_id_fk FOREIGN KEY (employee_id) REFERENCES employee (employee_id)
);
© www.soinside.com 2019 - 2024. All rights reserved.