2017-12-03 154 views
2

我正在嘗試基於這兩個函數依賴關係創建一個模式。2單個表中的函數依賴關係

A - > B,C,d

乙 - > d

我試圖建立一個單一的表既包括這些的FD與以下約束的:

  • 一對元組(B,D)可以重複,但遵循FD的定義(每當有兩個B值相同,則D值也相同)。

    CREATE TABLE one(
        B INT PRIMARY KEY, 
        D INT NOT NULL, 
        UNIQUE (B, D) 
    ); 
    
    CREATE TABLE two(
        A INT PRIMARY KEY, 
        B INT NOT NULL, 
        C INT NOT NULL, 
        D INT NOT NULL, 
        FOREIGN KEY(B, D) REFERENCES one(B, D) 
    ); 
    

    我只是想知道如果有一個方法可以讓我在短短一個表結合這2桌,而無需使用TRIGGERS:現在

,我在2個表如下實施本在Postgresql中?

編輯:

示例數據:

enter image description here

+2

你說的'在短短一個table'結合這兩個表是什麼意思?你能舉出你想要的例子嗎,最好包括例子數據? *(我相信我理解你描述的約束條件,我只是不明白最後一點...)* – MatBailie

+0

@MatBailie我的意思是,不是創建2個單獨的表,我只是想創建一個包含所有這些屬性的表。我用一個例子編輯了這篇文章。 –

+0

好吧,我想你的意思是'我只是想創建一個包含所有這些屬性的表格,並且強制執行所有這些約束而不需要第二個表格...... – MatBailie

回答

1

我必須學習它自己,但我認爲這是你想要的...

CREATE EXTENSION btree_gist; 

CREATE TABLE fd (
    a INT PRIMARY KEY, 
    b INT NOT NULL, 
    c INT NOT NULL, 
    d INT NOT NULL, 
    EXCLUDE USING gist (b WITH =, d WITH <>) 
); 

一個排除約束互相檢查所有行,就像UNIQUE約束檢查所有行。但它更廣泛。

如果所有支票(b WITH =, d WITH <>)都是TRUE則該行被拒絕。

(相反地,這意味着行是唯一可以接受的,如果至少一個檢查是FALSE。)

因此,如果兩行具有相同的b但不同dINSERTUPDATE正被運行將失敗。

http://dbfiddle.uk/?rdbms=postgres_10&fiddle=5fc308eaaedef4d3d2232ec3d70f3de6

+0

這就是我正在尋找的。可以肯定的是,在Postgresql中只使用外鍵/唯一約束或檢查約束是不可能的? –

+1

@jeeva_v如果你只想要一張桌子,那就不行了......你已經展示瞭如何用外鍵來做......唯一的選擇是觸發器等,它們都有競爭條件問題。 – MatBailie

+1

另外,請注意'EXCLUDE' ***實際上是一種'CHECK'約束。只是一個非常靈活的。 – MatBailie