2013-07-25 145 views
0

我正在建模一個治療計劃軟件的三個實體的層次結構。一種療法基本上被理解爲幾天內給予患者的一些藥物。我希望能夠在任何特定日子以只寫方式取消治療(用於質量控制認證目的)。複合外鍵的雙重使用

下面是具體的問題:重新使用複合外鍵的一部分作爲另一個外鍵是否可行?在我的情況下,複合關鍵點從藥物表到日表,然後指向治療。治療ID包含在藥物表中的複合外鍵中,所以我可以將其用作外鍵,使查詢更容易?

表的定義應該是這樣的(模hickups在我原始的SQL技能,我平時經常使用某種ORM的):

CREATE TABLE therapy (
    "id" INTEGER NOT NULL, 
    "start" DATE NOT NULL, 
    PRIMARY KEY (id) 
); 

CREATE TABLE day (
    "therapy_id" INTEGER NOT NULL, 
    "day" INTEGER NOT NULL, 
    "revision" INTEGER NOT NULL, 
    "comment" TEXT; 
    "cancelled" BOOLEAN NOT NULL; 
    PRIMARY KEY (therapy_id, day, revision), 
FOREIGN KEY(therapy_id) REFERENCES therapy (id) 
); 

CREATE TABLE medication (
    "id" INTEGER NOT NULL, 
    "therapy_id" INTEGER NOT NULL, 
    "day" INTEGER NOT NULL, 
    "revision" INTEGER NOT NULL, 
    "substance" VARCHAR(100) NOT NULL, 
    "dosage" VARCHAR(50) NOT NULL, 
    PRIMARY KEY (id), 
FOREIGN KEY(therapy_id, day, revision) REFERENCES day (therapy_id, day, revision), 
-- wondering if this is ok 
    FOREIGN KEY(therapy_id) REFERENCES therapy (id) 
); 

請注意,從白天到藥物的關係是單一對多,例如在第3天,我想用布洛芬,撲熱息痛,阿司匹林,咖啡豆和傑傑邁斯特的一個很好的鏡頭致命混合石膏病人。

回答

1

這就是你開始。

CREATE TABLE medication (
    "id" INTEGER NOT NULL,    -- You don't need this. 
    "therapy_id" INTEGER NOT NULL, 
    "day" INTEGER NOT NULL, 
    "revision" INTEGER NOT NULL, 
    "substance" VARCHAR(100), 
    "dosage" VARCHAR(50), 
    PRIMARY KEY (id),     -- Drop this. 
    FOREIGN KEY(therapy_id, day, revision) 
     REFERENCES day (therapy_id, day, revision), -- Ok, but should be PK. 
    FOREIGN KEY(therapy_id) REFERENCES therapy (id) -- You don't need this. 
); 

列「ID」沒有用處,而且反而使你確信你不需要在真正密鑰的唯一約束:{therapy_id,日,修訂}。將「id」上的無用主鍵約束替換爲{therapy_id,day,revision}上的主鍵約束。刪除最後一個外鍵約束。您知道「therapy_id」將引用現有的行,因爲表「日」中的外鍵約束需要它。

這讓我們有了這個。

CREATE TABLE medication (
    "therapy_id" INTEGER NOT NULL, 
    "day" INTEGER NOT NULL, 
    "revision" INTEGER NOT NULL, 
    "substance" VARCHAR(100), 
    "dosage" VARCHAR(50), 
    PRIMARY KEY (therapy_id, day, revision), 
    FOREIGN KEY(therapy_id, day, revision) 
     REFERENCES day (therapy_id, day, revision) 
); 

麻煩我說「物質」和「劑量」是可以空的。想一想。

+0

我使有問題的列不能爲空。我沒有看到(therapy_id,day,revision)構成主鍵,因爲我可以有一天有多個藥物輸入。 但是你說得對,我不需要藥物治療的外鍵約束,因爲這將從藥物的外鍵約束「繼承」到一天。 性能方面,我仍然可以自由地創建一個關於therapy_id的索引,它應該給我我想要的。 – room2web

+0

然後,您需要添加另一列 - 而不是ID號 - 以製作真正的密鑰。也許是一個時間戳,顯示何時給藥?沒有辦法讓我從你發佈的內容中分辨出來。 –

+0

我可以認爲物質與(therapy_id,day,revision)一起構成一個自然的關鍵。但是,這將導致必須確保醫生不會每天開兩次相同的藥物,這在理論上可能是合理的,但實際上我們已經看到了醫生將紅prescription處方輸入系統的用例並有很好的理由這樣做。 在桌子上放置一個非自然的主鍵似乎是最簡單的,儘管不是最簡單的方式。 – room2web