2012-11-07 17 views
7

因此,由於多種原因,多形關聯被認爲是不好的數據庫設計,例如,您不能在多態ID列上擁有外鍵,因此參照完整性消失。使用什麼來代替多態協會?

而且,STI也被認爲是不好的除非子類型只在行爲上有所不同。

所以我的問題是爲Rails/ActiveRecord的什麼是兩害取其輕於以下情形:

我需要讓我的用戶創建多個類型的實體的手有序集合。

使用多態關聯的模式會是這個樣子:

-- collections 
id, name, ... 

-- exhibits 
id, collection_id, exhibitable_type, exhibitable_id, position 

-- photographs 
id, ... 

-- films 
id, ... 

-- paintings 
id, ... 

-- songs 
id, ... 

-- sculptures 
id, ... 

我可以使用STI和有這樣的事情:

-- collections 
id, name, ... 

-- exhibits 
id, collection_id, artwork_id, position 

-- artworks 
id, type, <photograph columns>, <film columns>, <painting columns>, etc. 

但是,因爲我的作品上的數據有所不同(而不是隻是行爲),我現在在藝術品表格上都有NULL。我還向我的對象介紹了一個繼承層次結構,這些對象以前不在那裏,我一般都很謹慎,特別是當它的唯一目的是服務於數據庫設計時。

STI似乎至少會更簡單地查詢和編碼。

那麼哪個更小的邪惡呢?

然後,另一種選擇是多表繼承:

-- collections 
id, name, ... 

-- exhibits 
id, collection_id, artwork_id, position 

-- artworks 
id 

-- photographs 
artwork_id, <photograph columns> 

-- films 
artwork_id, <film columns> 

這將擺脫STI的NULL問題,也保持桌面尺寸下降。我們仍然有對象層次結構,我認爲這是絕對必要的。但我眼中最大的問題是:Rails不支持它。 CITIER寶石看起來非常好,它有近期的提交,但它並沒有被廣泛使用,所以我謹慎的使用它在我的應用程序的基礎。我想我也可以看看使用Sequel或其他具有CTI支持的ORM。

說實話我覺得我喜歡的多表繼承解決方案的最佳

如果我並不需要的位置專欄中,我會簡單地使用單獨的連接表像collections_photographscollections_paintingscollections_films等,但我確實需要手動訂購。

因此,似乎有三種選擇:

  • PA:參照完整性的損失(它在實踐中的問題,如果總是使用ActiveRecord的數據庫訪問?)
  • STI:大表有很多空的
  • CTI/MTI:依託的寶石,沒有被廣泛使用

這是兩害取其輕以及是否有任何其他選項?我正在使用Postgres。

回答

1

另一種選擇是完全標準化您的數據庫結構並將視圖轉換爲更適合查詢的表單。我不確定這對於不同的ORM有效,因此你的里程可能會有所不同。一般來說,我發現最好將您的數據模型建立在數據真正結構化的基礎上,因爲這樣可以使維護變得簡單。在數據正確建模之後,您可以創建視圖和存儲過程來方便地訪問和操作數據。

0

如果您在Postgres中使用partitioned table,則可以同時實現多態主義和外鍵,因爲表示不同分區的表可以分別代表不同的子類型,並且可以各自具有不同的約束集。