MySQL无法创建外键约束


84

我在为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列设置为非null,但这并不能解决问题),所以我想问题一定是该类型Cannot find an index in the referenced table where the referenced columns appear as the first columns。但是我不太确定这意味着什么,或者如何检查/修复它。有没有人有什么建议?那是什么意思first columns


11
在任何答案或问题中,我都找不到因字符集不同而发生此错误的地方。谢谢。。干杯!
proprius

3
另外,请仔细检查您的列排序规则。您的表可以是utf8mb4,但列可以具有不同的排序规则!
沃森

在我的案例中,@ Watson字符集,但您因我的思考而受到支持。
user2910265

Answers:


153

只是将其混入可能的原因中,当引用表列具有相同的“类型”但没有相同的签名时,我就遇到了这种情况。

在我的情况下,被引用的表列是TINYINT UNSIGNED,而我的引用表列是TINYINT SIGNED。对齐两列即可解决此问题。


1
@ austen-hoogen建议的解决方案已解决我的问题。但是由于信誉评分低,我无法对其解决方案进行投票和评论。在我的情况下,主键是整数,自动递增和无符号。但是外键(引用表的列)是带符号的类型。我将其更改为未签名,并能够成功创建关系。
Bal Singh

是的,经历了同样的问题。我的主键是BIGINT(20),而我在另一个表中引用的键是INT(10)无符号。我们要确保它们都匹配。即。BIGINT(20),并且在引用的表中也应为BIGINT(20)
Manjunath Reddy '18

谢谢!这个解决方案也解决了我的问题!我曾int计划在第二张表中设置外键和bigint。
Aleksej_Shherbak

36

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


3
设置后的字符集latin中引用的表,然后我3小时后重新开始呼吸。
Abhishek Kamal

24

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

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

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

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

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

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


19

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


2
谢谢!我在INT(11)和INT(11)中使用INT(11)时遇到了类似的问题,但其中一个是主键,因此未签名,而另一个已签名!
迈克尔·斯科特·库斯伯特

@MichaelScottCuthbert Same
Germa Vinsmoke


6

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

  • 首先,我在引用表上运行查询以获取其归类类型
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)
);

2

主键的确切顺序也需要匹配,中间没有多余的列。

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

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

我不得不对主键列进行重新排序,以便不仅以相同的方式对其进行排序,而且中间没有多余的列:

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


2

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

但是我发现不将其定义为唯一并不会在每种情况下造成问题。我还无法弄清楚情况。可能与可为空的定义有关。


您是否已阅读FK简介或手册?FK引用UNIQUE;PK表示UNIQUE NOT NULL。
philipxy

2

在我的情况下,使用id作为整数创建的,并且引用表默认情况下使用bigint创建外键。

由于迁移失败,但是这实际上是在数据库中创建的,所以这在我的Rails应用程序中造成了巨大的噩梦,因此这些字段显示在数据库中,而不是在Rails应用程序的架构中。


1

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


1

我也有这个错误。没有一个答案与我有关。就我而言,我的GUI自动创建一个表,其主要唯一标识符为“ unssigned”。当我尝试创建外键并给出完全相同的错误时,此操作将失败。我的主键需要分配。

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

希望这可以帮助其他人。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.