2010-01-19 108 views
2

我有一張桌子包含某種items,以及這些項目所屬的兩個桌子(ab)。參考一張桌子或另一張桌子的桌子排

一個項目是指一排a一排b。一個ab可以有多個項目。

難道還有比以下(使用Oracle 10)一個更好的設計?

任何需要注意的缺陷?

id a_id(fk) b_id(fk) 
1   1  NULL 
2   1  NULL 
3  NULL   1 
4   2  NULL 

回答

4

這是對一些罪名的相當不錯的設計:

  • 隨着A_ID你執行的鏈接表A.
  • 與B_ID你執行的鏈接表的外鍵的外鍵B.
  • 1:很多關係(項目和表A之間,以及項目和表B之間)都正確存儲。

唯一的障礙是,這個數據庫結構本身並不檢查一個項目是隻鏈接到A或B(而不是兩個)之一。檢查Items表上的約束將完成這項工作。

僞代碼示例:

CONSTRAINT a_eor_b CHECK 
    (
    NOT (a_id IS NULL AND b_id IS NULL) 
    AND NOT (a_id IS NOT NULL AND b_id IS NOT NULL) 
) 
0

AB是一個更一般類型的不相交的子類型。

我們稱之爲refs

CREATE TABLE refs (type CHAR(1) NOT NULL, id INT NOT NULL, PRIMARY KEY (type, id), CHECK (type IN ('A', 'B'))) 

CREATE TABLE a (type CHAR(1) NOT NULL, id INT NOT NULL PRIMARY KEY, FOREIGN KEY (type, id) REFERENCES refs (type, id) ON DELETE CASCADE, CHECK (type = 'A')) 

CREATE TABLE b (type CHAR(1) NOT NULL, id INT NOT NULL PRIMARY KEY, FOREIGN KEY (type, id) REFERENCES refs (type, id) ON DELETE CASCADE, CHECK (type = 'B')) 

CREATE TABLE items (id INT NOT NULL, type CHAR(1) NOT NULL, ref INT NOT NULL, FOREIGN KEY (type, id) REFERENCES refs) 

採用這種設計,請不要刪除從AB直接:從父表refs刪除代替。

2

我建議的補充,強制ID字段是空的,至少(或精確地可能)一個檢查約束。

另外對於值NVL(A_ID,B_ID)的圖和/或基於功能指標可能是有用的。使用Oracle11,您可以使用虛擬列。

0

Mapping Inheritance Structures,有沒有提到4項技術,

  • 映射整個類層次結構一個表
  • 每個具體類映射到它自己的表
  • 每個類映射到自己的表
  • 地圖類爲通用表結構

,看看「2.6的COM削減策略「的專業人士&缺點。

+1

對不起,您能否解釋一下這與我的問題有關? – 2010-01-19 13:17:42

相關問題