一尘不染

将主键更改为复合主键

sql

我一直在为我的一张桌子使用“普通”(非复合)主键。现在,我想将其更改为复合主键。我的表看起来像这样:

-- Table 1
CREATE TABLE foo (
    id SERIAL PRIMARY KEY,
    id2 INT,
    ...
)

-- Table 2
CREATE TABLE bar (
    id SERIAL PRIMARY KEY,
    id_foo INT REFERENCES foo (id)
)

这里的问题是psql不想删除旧的主键,因为其他表引用了它。

有什么办法可以解决这个问题而又不会删除整个数据库?


阅读 180

收藏
2021-05-16

共1个答案

一尘不染

您可以添加冗余UNIQUE约束id你放下之前PRIMARY KEY的约束。这满足了FK约束的要求。每个文档:

外键必须引用作为主键或形成唯一 约束的列

大胆强调我的。

显然,FK约束与它在中显式创建的PK约束绑定pg_depend。因此,您需要删除并稍后重新创建所有引用的FK约束或将系统表弄乱(不建议这样做!)。最好的 一项事务
是保持参照完整性完整:

BEGIN;
ALTER TABLE bar DROP CONSTRAINT bar_id_foo_fkey;

ALTER TABLE foo 
    DROP CONSTRAINT foo_pkey
  , ADD CONSTRAINT foo_uni_id UNIQUE (id)
  , ADD PRIMARY KEY (id, id2);

ALTER TABLE bar ADD CONSTRAINT bar_id_foo_fkey
  FOREIGN KEY (id) REFERENCES foo (id);

COMMIT;

SQL提琴。 (通过查询显示提供其他名称的目录条目。)

手册中的ALTER TABLE详细信息。

这仅作为中间状态才有意义。如果id停留UNIQUE NOT NULL,则可能是PK。

2021-05-16