引用主键仍提示无唯一约束?数据库外键报错问询
哎,这个问题我之前帮同事排查过好多次,明明主键自带唯一性,怎么还会报这个错?其实大概率是下面这几个场景之一,咱们一个个捋:
你引用的不是完整的主键(或者主键定义根本没生效)
最常见的情况是:你以为a和b是主键,但要么是主键约束没真的加上去,要么是你引用的时候只用到了主键的一部分。比如说你给表a设的是复合主键(a+b组合成主键),但你在另一个表的外键里只关联了a列——这时候数据库就懵了,因为单独的a列并没有唯一约束,只有a+b的组合才有。
赶紧查下表结构确认下:用DESCRIBE a;(MySQL)或者\d a(PostgreSQL)看看,a表的主键是不是真的包含你要引用的所有列,而且约束状态是正常的。你误引用了视图而非基表
如果你写的REFERENCES "a"里的a是个视图,那就算视图的基表有主键,视图本身是没有主键约束的。数据库找不到视图上的唯一约束,自然就报错了。先确认下你引用的到底是真实的表,还是一个视图。数据库的约束状态出了异常
这种情况比较少见,但偶尔会发生:比如数据库的系统表出了小问题,导致主键约束没被正确识别。比如在PostgreSQL里,你可以查pg_constraint表看看对应的主键约束是不是valid状态;MySQL里用SHOW CREATE TABLE a;确认主键约束的定义确实存在且生效。如果约束被标记为无效,得重新创建或者修复它。临时表的主键创建有问题
如果你引用的a是临时表,有些数据库对临时表的约束创建有特殊规则,可能你创建临时表的时候主键约束没成功生效。仔细检查下临时表的创建语句,确认主键是正确定义的。
举个典型的错误例子,一看就懂:
假设你建表
a的语句是:CREATE TABLE a (id1 INT, id2 INT, PRIMARY KEY (id1, id2));
然后你在表b里建外键的时候只引用了id1:CREATE TABLE b (a_id1 INT, FOREIGN KEY (a_id1) REFERENCES a(id1));
这时候必然会报错,因为a表的id1单独没有唯一约束,只有id1+id2的组合才是主键(具备唯一性)。正确的做法是外键同时引用id1和id2才行。
总的来说,先去确认你引用的表结构,看看主键是不是真的存在、是不是你引用的列(或组合列),再检查外键的引用是不是和主键的列完全匹配,基本就能定位问题了。
内容的提问来源于stack exchange,提问作者Human Cyborg Relations

