【问题标题】:Postgres FK referencing composite PKPostgres FK 引用复合 PK
【发布时间】:2012-04-02 21:21:22
【问题描述】:

考虑

CREATE TABLE foo (
    id SERIAL,
    foo_created_on ABSTIME,
    foo_deactivated_on ABSTIME,
    PRIMARY KEY (id, foo_created_on)
);

CREATE TABLE bar (
    id SERIAL,
    bar_created_on ABSTIME,
    bar_deactivated_on ABSTIME,
    foo_id REFERENCES ( .. what goes here? ..),
    PRIMARY KEY (id, bar_created_on)
);

如何在“bar”中创建一个引用“foo”中的 PK 的 FK?

【问题讨论】:

  • 顺便说一句:不支持“ABSTIME”数据类型。您应该改用 DATE 或 TIMESTAMP。

标签: postgresql


【解决方案1】:

如何在“bar”中创建一个引用“foo”中的 PK 的 FK?

以你目前的结构,你不能。

外键引用的目标必须声明为 PRIMARY KEY 或 UNIQUE。所以要么这个

CREATE TABLE foo (
    id SERIAL PRIMARY KEY,
    foo_created_on ABSTIME,
    foo_deactivated_on ABSTIME,
    UNIQUE (id, foo_created_on)
);

或者这个

CREATE TABLE foo (
    id SERIAL,
    foo_created_on ABSTIME,
    foo_deactivated_on ABSTIME,
    PRIMARY KEY (id, foo_created_on),
    UNIQUE (id)
);

可以作为 bar.foo_id 的目标。那么 bar 会有一个简单的参考。

CREATE TABLE bar (
    id SERIAL,
    bar_created_on ABSTIME,
    bar_deactivated_on ABSTIME,
    foo_id REFERENCES foo (id),
    PRIMARY KEY (id, bar_created_on)
);

如果要引用最初在 foo 中声明的主键,则必须将该主键存储在 bar 中。您必须存储所有内容,而不是其中的一部分。所以不用修改 foo,就可以像这样构建 bar。

CREATE TABLE bar (
    id SERIAL,
    bar_created_on ABSTIME,
    bar_deactivated_on ABSTIME,
    foo_id INTEGER NOT NULL,
    foo_created_on ABSTIME NOT NULL,
    FOREIGN KEY (foo_id, foo_created_on) REFERENCES foo (id, foo_created_on),
    PRIMARY KEY (id, bar_created_on)
);

【讨论】:

    【解决方案2】:

    您必须创建单独的外键:

    CREATE TABLE bar (
      id SERIAL,
      bar_created_on ABSTIME,
      bar_deactivated_on ABSTIME,
      foo_id INT,
      FOREIGN KEY (foo_id, created_on) REFERENCES foo (id, created_on),
      PRIMARY KEY (id, bar_created_on)
    );
    

    【讨论】:

    • 对不起,不清楚...(我应该给“created_on”列独特的名称来消除歧义...现在查看更新的问题)。上面的咒语是“bar”模式吗?请记住,bar 的 created_on 轨道 created_on 用于 bar 条目,而不是 foo 条目。
    • 我更新了答案。我不知道你的 foo_id 是做什么用的,所以我只是把它变成了一个 int。参考很容易,但也许我不明白你的意思。
    猜你喜欢
    • 1970-01-01
    • 2021-10-09
    • 2013-07-29
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多