You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:53:29