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>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) -> varchar(50)
是不允许的,但 varchar(50)->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:是啥阻止了我的外键约束?的主要内容,如果未能解决你的问题,请参考以下文章