mySQL:是啥阻止了我的外键约束?

Posted

技术标签:

【中文标题】mySQL:是啥阻止了我的外键约束?【英文标题】:mySQL: What is preventing my foreign key constraint?mySQL:是什么阻止了我的外键约束? 【发布时间】:2016-12-09 09:31:48 【问题描述】:

我已经尝试了所有我能想到的方法,但在创建表格时仍然遇到问题。

我有一个主键为username的用户表

+---------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------+-------------+------+-----+---------+-------+ | created_at | datetime | YES | | NULL | | | updated_at | datetime | YES | | NULL | | | username | varchar(50) | NO | PRI | NULL | | | administrator | tinyint(1) | YES | | NULL | | | fullname | text | YES | | NULL | | | description | text | YES | | NULL | | | password | varchar(60) | NO | | NULL | | +---------------+-------------+------+-----+---------+-------+

我想创建一个这样的新表:

CREATE TABLE sessions ( created_at DATETIME, updated_at DATETIME, token VARCHAR(50) NOT NULL, username VARCHAR(50), PRIMARY KEY (token), FOREIGN KEY(username) REFERENCES users (username) );

但我得到一个严重的错误:

ERROR 1215 (HY000): Cannot add foreign key constraint

我通常发现这个错误是由 pk/fk 对的数据类型不匹配引起的,但这次两者显然都是 varchar(50),所以看起来问题出在其他地方。

我也试过这个以防万一:

CREATE TABLE sessions ( created_at DATETIME, updated_at DATETIME, token VARCHAR(50) NOT NULL, username varchar(50) NOT NULL, #<- ***added not null*** PRIMARY KEY (token), FOREIGN KEY(username) REFERENCES users (username) );

mysql&gt;SHOW ENGINE INNODB STATUS

最新的外键错误

2016-08-03 15:13:23 a46fcb70 表 savesdev/sessions 的外键约束错误: FOREIGN KEY(username) REFERENCES users (username)): 在引用的表中找不到索引 引用的列显示为第一列或列类型 表中和引用表中的约束不匹配。 注意 ENUM 和 SET 的内部存储类型在 使用 >= InnoDB-4.1.12 创建的表,以及旧表中的此类列 不能被新表中的此类列引用。 见http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html 正确的外键定义。

似乎在两种情况下会引发错误:

1)当有不匹配时(我已经排除了)

表中的列类型与被引用表中的约束不匹配。

2) 当被引用的列上没有合适的索引时

在引用的列作为第一列出现的引用表中找不到索引

我认为这两个都涵盖了,所以有什么关系?

谁能发现我的错误?

【问题讨论】:

show engine innodb status。大约 1/2 通过转储将是“最后一个外键错误”部分,其中包含详细信息。很可能您的字段定义不匹配。 FK 关系必须相同,例如varchar(49) -&gt; varchar(50) 是不允许的,但 varchar(50)-&gt;varchar(50) 是。或者您使用的是较旧的 mysql,它不会在 FK 字段上自动创建索引,并且您没有在用户名上手动添加键。 也许你的列用户名有不同的字符集你可以试试这个:ALTER TABLE sessions MODIFY username VARCHAR(50) CHARACTER SET utf8; ALTER TABLE users MODIFY username VARCHAR(50) CHARACTER SET utf8; 这是一个很好的观点@elkorchianas,我会看看.. 是的,正确!你能补充一个答案吗?引用这个***.com/a/4805510/1083707 或者我可以。 它类似于this problem,也许我的Describe all Tables有时也可以提供帮助 【参考方案1】:

也许你的列用户名有不同的字符集你可以试试这个:

ALTER TABLE sessions MODIFY username VARCHAR(50) CHARACTER SET utf8; 
ALTER TABLE users MODIFY username VARCHAR(50) CHARACTER SET utf8;

正如@Graeme Stuart 所建议的,这里有一个链接,可以查看我们如何检查数据库/表或列的租船人集:How do I see what character set a MySQL database / table / column is?

【讨论】:

是的,这些字段都是 VARCHAR(50) 但现有表有一个 utf8_general_ci 排序规则,这使得它们不兼容。我的实际解决方案是使用 utf8_general_ci 排序规则为外键列创建新表。

以上是关于mySQL:是啥阻止了我的外键约束?的主要内容,如果未能解决你的问题,请参考以下文章

Mysql的外键约束内外连接查询以及锁

mysql的常见的外键约束

MySQL 中的外键约束错误 1452 - Magento 导入

mysql的外键约束

补12.关于mysql的外键约束

truncate table时存在外键约束的解决办法