2012-04-02 74 views
11

考虑Postgres的FK引用复合PK

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) 
); 

如何在引用中的 “富” 的PK “栏中的” 创建FK?

+2

Btw:“ABSTIME”数据类型是不支持的。您应该使用DATE或TIMESTAMP。 – 2012-04-02 22:36:02

回答

8

你必须创建单独的外键:

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) 
); 
+0

对不起,不清楚...(我应该给“created_on”列的独特名称以消除歧义......现在查看更新后的问题)。上面的“酒吧”模式咒语?请记住,bar的created_on跟踪条目条目的created_on,而不是foo条目。 – punkish 2012-04-02 21:31:52

+0

我更新了答案。我不知道你的foo_id是什么,因此我只是把它作为int。参考文献很容易,但也许我不明白你的意思。 – 2012-04-02 22:11:57

18

如何在引用中的“富”的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目标。然后吧有一个简单的参考。

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,你可以像这样建立条形图。

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 (foo_id, foo_created_on), 
    PRIMARY KEY (id, bar_created_on) 
);