2014-03-27 42 views
0

我有十一個表。SQL 2012計算列外鍵獨有或與其他十個表

呼叫其中一個父表,和其他十名是子表,也許ChildA,ChildB等通過ChildJ

考慮父表被抽象了一塊電子。每一件電子產品都有一些共同的欄目,如名稱,但每種不同類型的電子設備都具有廣泛的不同特性。代表電視機所需的列與手機有很大不同。

父級可能有一個且只有一個孩子存在於其中一個Child表中,但不會與多個孩子關聯。

如果父母有一個ChildA,它將不會有ChildB到ChildJ。

我目前實施的方式是通過一個「ChildType」列,一個「ChildId」字段和十個持久計算列。

例如,我分配(任意地)的值1爲ChildA的ChildType,2 ChildB等(有上ChildType CHECK約束)

我然後使用CASE,得到創建持久列通過使用類型列來爲父表格ChildAId,ChildBId等。

就是

ChildAId AS CASE WHEN ChildType=1 THEN ItemId END PERSISTED, 
ChildBId AS CASE WHEN ChildType=2 THEN ItemId END PERSISTED, 

....等

這些計算列持久化,因爲我需要在FOREIGN KEY限制使用它們。

各種子表的內容非常不同以至於彼此完全無關。

就這樣,我已經有效管理的SQL來表示一個變體類型我曾考慮

其他的想法,所以我拒絕了他們:

  1. 在使用父表的ID ChildX表。被拒絕,因爲它允許每個父母不止一個孩子。

  2. Parent和各種ChildX表之間的xref表。因爲它也會允許每個父母有多個孩子(更重要的是,每個孩子有多個父母)

  3. 創建一堆代表所有子類型所需數據的超集。拒絕,因爲它是愚蠢的(也是,我這是在更換做了工藝系統是什麼,以及我試圖避免的事情之一)

我們實際的問題:

雖然這是一個好主意,但只有兩種類型的孩子,當我突然跳到10時,我開始擔心。雖然這可能不會達到50,但在我們之前可能會有25種不同的孩子類型'重做。

而且,這個作品真的很好,當通過實體框架放倒成C#:

有效地與一個ChildA行父行associatd成爲父對象。這真的是一件美麗的事情,也是我選擇我選擇的主要原因之一。

是否有這種類型的(基本上是一個變體)的數據獲取SQL於通過約束控制,並允許我進行查詢,並與東西像實體框架使用它的方式來表示一個更加規範的方式?是增加了許多領域的(所有,但其中一個將永遠是NULL)的我如何做這個權衡成本是多少?我沒有看到我應該看到的紅旗嗎?

回答

1

我認爲處理這類案件很常見的方式是
1)在ChildX表有輕微的修改

即使它引入了冗餘使用父表的ID,它是一個由發動機執行的清晰模型可接受的成本。例如,

ParentTable(parentTableId, childType, UNIQUE(parentTableId,childType) , 
PK(parentTableId), CHECK(childType IN (1,2,3,4,5,...))); 
ChildTable1(parentTableId, childType, other attributes, 
    FK(parentTableId, childType), PK(parentTableId, childType), CHECK(childType=1)); 
ChildTable2(parentTableId, childType, other attributes, 
    FK(parentTableId, childType), PK(parentTableId, childType), CHECK(childType=2)); 

如果孩子類型的數量非常少,說2-3,這是確定有父表檢查約束就像上面的例子;如果你有或期望更多,我寧願創建一個小查找表,ChildType並使用外鍵(這種方式添加一個新的子類型將不需要更改父表中的檢查約束)...

1

你所描述的看起來像繼承。有3層常見的方法來模擬它,你形容是專門類似於表每類型(TPT)

TPT通常與您的選項1模型,即與父表的派生表分享PK:

Base(PK id, [type], attr1, attr2) 
Derived1(PK/FK id, attr10, attr11) 
Derived2(PF/FK id, attr20, attr21) 

基表類型屬性是不是真的需要,但可以極大地幫助,因爲它使您無需對所有派生表進行試探性連接即可知道實際的行數。

是的,這個模型,你能夠在多個派生表插入行。人們通常不會打擾。你會發現,你不能在一個數據庫模型執行一切。 a1ex07的答案向你展示了以複合PK的價格,如果你真的想要的話,你可以強制執行此操作。

既然你提到EF,你會很高興知道,它已經內置了對TPT繼承支持。