postgresql 如何定义一对多关系的主记录?

6za6bjd0  于 2023-02-15  发布在  PostgreSQL
关注(0)|答案(1)|浏览(157)

我正在创建一个带有account表和profile表的服务。一个帐户可以拥有多个配置文件,但帐户总是有一个主配置文件。这最初是注册时与帐户一起创建的第一个配置文件,但用户可以添加配置文件,并在以后将其中一个设置为主配置文件。
我尝试了以下设置:

create table account (
    id                   uuid          primary key,
    email                text          unique,
    phone                text          unique,
    created_at           timestamptz,
    primary_profile_id   uuid          references profile on delete restrict,
);

create table profile (
    id           uuid          primary key,
    account_id   uuid          references account on delete cascade,
    username     text          unique,
    about        text,
    created_at   timestamptz
);

这不起作用,因为:

  • 您甚至不能运行该命令来创建表,因为它们都依赖于预先存在的另一个表。一个解决方法是创建没有primary_profile_id的帐户表,然后在创建profile表之后修改该表以添加该列,但是...
  • 即使可以创建表,也不能向其中添加记录,因为需要先存在另一个表才能引用它。如果将primary_profile_id保留为NULL,并在创建配置文件后更改它,在技术上是可行的,但列不应该为空,因此这并不理想。

对此有什么好的解决方案吗?我也考虑过在profile表中使用一个primary布尔值,但是在数据库端没有任何东西可以阻止在一个帐户下使用多个profile。
感谢您的帮助:)

wz3gfoph

wz3gfoph1#

您使用外键强制执行要求的想法很好。
创建表没有问题;你可以简单地运行

create table account (
    id                   uuid          primary key,
    email                text          unique,
    phone                text          unique,
    created_at           timestamptz,
    primary_profile_id   uuid,
);

create table profile (
    id           uuid          primary key,
    account_id   uuid          references account on delete cascade,
    username     text          unique,
    about        text,
    created_at   timestamptz
);

ALTER TABLE account
   ADD FOREIGN KEY (primary_profile_id) REFERENCES profile
      DEFERRABLE INITIALLY DEFERRED;

像这样的延迟外键约束不是在插入行时检查,而是在事务结束时检查。因此,您可以先添加account,然后添加匹配的profile,只要在同一事务中插入这两个约束即可。
我建议尽可能在列定义中使用NOT NULL

相关问题