PostgreSQL引用复合主键表报错:创建ftotal表失败的技术问询
解决PostgreSQL中外键引用复合主键的问题
你碰到的这个错误其实很好理解——PostgreSQL要求外键必须指向被参照表的唯一约束(或者主键),而你的cur表用的是(cur_code, con_code)复合主键,这意味着单独的cur_code在cur表里并不是唯一的(只有和con_code组合起来才唯一),所以你在ftotal里只把cur字段(对应cur_code)作为外键引用,数据库自然会报错。
正确的解决方案:使用组合外键
既然cur表的主键是两个字段的组合,那ftotal的外键也必须用对应的两个字段组合来引用。修改后的SQL如下:
CREATE TABLE con ( con_code CHAR (3) PRIMARY KEY NOT NULL, con_name VARCHAR (100) NOT NULL ); CREATE TABLE cur ( cur_code CHAR (3) NOT NULL, cur_name VARCHAR (100) NOT NULL, con_code CHAR (3) NOT NULL, PRIMARY KEY (cur_code, con_code), FOREIGN KEY (con_code) REFERENCES con (con_code) ); CREATE TABLE ftotal ( eff_date DATE NOT NULL, con CHAR(3) NOT NULL, cur CHAR(3) NOT NULL, PRIMARY KEY (eff_date,con,cur), FOREIGN KEY (con) REFERENCES con (con_code), -- 组合外键:同时匹配cur表的两个主键字段 FOREIGN KEY (con, cur) REFERENCES cur (con_code, cur_code) );
这里的关键修改是把原本单独引用cur的外键,改成了(con, cur)组合外键,对应cur表的(con_code, cur_code)复合主键,这样就满足了外键必须指向唯一约束的要求。
另一种可选方案:给cur_code单独加唯一约束
如果你的业务逻辑里,cur_code本身是全局唯一的(不需要和con_code组合也能唯一标识一条记录),那也可以给cur表的cur_code单独添加一个唯一约束,这样就能单独引用它作为外键了:
CREATE TABLE cur ( cur_code CHAR (3) NOT NULL UNIQUE, -- 新增单独的唯一约束 cur_name VARCHAR (100) NOT NULL, con_code CHAR (3) NOT NULL, PRIMARY KEY (cur_code, con_code), FOREIGN KEY (con_code) REFERENCES con (con_code) ); -- 这时候ftotal的原外键写法就可以正常工作了 CREATE TABLE ftotal ( eff_date DATE NOT NULL, con CHAR(3) NOT NULL, cur CHAR(3) NOT NULL, PRIMARY KEY (eff_date,con,cur), FOREIGN KEY (con) REFERENCES con (con_code), FOREIGN KEY (cur) REFERENCES cur (cur_code) );
不过这种方式要谨慎使用,必须确保业务上cur_code确实是唯一的,否则会导致数据不一致的问题。
内容的提问来源于stack exchange,提问作者as - if
相关产品推荐
相关产品推荐

