SQL外键匹配错误:创建表结构插入数据遇foreign key mismatch问题
问题原因及解决方法
错误原因
表b的主键是复合主键(Field1, Field2),而表c中定义的外键FOREIGN KEY("Field2") REFERENCES "b"("Field1")仅引用了b的单个列Field1。
SQLite的外键约束要求:外键必须引用被引用表的主键,或者被引用列上存在唯一约束。由于b的Field1没有单独的唯一约束(它只是复合主键的一部分,单独的Field1可以重复),因此无法作为外键的合法引用目标,导致插入时触发foreign key mismatch错误。
解决思路
根据业务需求,有两种可行的修正方案:
方案1:给表b的Field1添加唯一约束
如果业务逻辑中b.Field1本身应该是唯一的,可给该列添加UNIQUE约束,使其能被外键引用:
DROP TABLE IF EXISTS c; DROP TABLE IF EXISTS b; DROP TABLE IF EXISTS a; CREATE TABLE a ( "Field1" INTEGER PRIMARY KEY ); CREATE TABLE b ( "Field1" INTEGER UNIQUE, -- 添加唯一约束 "Field2" INTEGER, FOREIGN KEY("Field2") REFERENCES "a"("Field1"), PRIMARY KEY("Field1","Field2") ); CREATE TABLE c ( "Field1" INTEGER PRIMARY KEY, "Field2" INTEGER, "Field3" INTEGER, FOREIGN KEY("Field2") REFERENCES "b"("Field1"), FOREIGN KEY("Field3") REFERENCES "a"("Field1") ); insert into a values(1); insert into b values(2,1); insert into c values(3,2,1); -- 此时可正常执行
方案2:修改外键以匹配b的复合主键
如果c需要关联b的完整复合主键,需调整c的表结构,添加对应列匹配复合主键的所有字段:
DROP TABLE IF EXISTS c; DROP TABLE IF EXISTS b; DROP TABLE IF EXISTS a; CREATE TABLE a ( "Field1" INTEGER PRIMARY KEY ); CREATE TABLE b ( "Field1" INTEGER, "Field2" INTEGER, FOREIGN KEY("Field2") REFERENCES "a"("Field1"), PRIMARY KEY("Field1","Field2") ); CREATE TABLE c ( "Field1" INTEGER PRIMARY KEY, "b_Field1" INTEGER, -- 对应b的Field1 "b_Field2" INTEGER, -- 对应b的Field2 "Field3" INTEGER, FOREIGN KEY("b_Field1", "b_Field2") REFERENCES "b"("Field1", "Field2"), -- 引用复合主键 FOREIGN KEY("Field3") REFERENCES "a"("Field1") ); insert into a values(1); insert into b values(2,1); insert into c values(3,2,1,1); -- 插入时需提供完整的复合主键值
内容的提问来源于stack exchange,提问作者user1042365
相关产品推荐
相关产品推荐

