1

說我們有這樣的場景:數據庫設計:贊成抽象還是外鍵約束?

Artist ==< Album ==< Track 
//ie, One Artist can have many albums, and one album can have many tracks 

在這種情況下,所有3個實體具有基本相同的字段:

  • ID
  • 名稱
  • 的一對多關係的外國到相應的孩子(藝術家專輯和專輯跟蹤

對於提供的解決方案,一個典型的解決方案是三個表,在一對多關係字段中具有相同的字段(ArtistID,AlbumID等)和外鍵約束。

但是,我們可以在這種情況下,納入一種形式的繼承,以避免重複相同的領域?我說的那種東西:

Table: EntityType(EntityTypeID, EntityName) 
     This table would hold 3 entities (1. Artist, 2. Album, 3. Track) 

Table: Entities(EntityID, Name, RelField, EntityTypeID) 
     This table will hold the name of the entity (like the name of 
     an artist for example), the one-many field (foreign-key 
     of EntityID) and EntityTypeID holding 1 for Artist, 2 for Album 
     and so on. 

你覺得上面的設計是什麼?在這個DB場景中加入「OOP概念」是否有意義?

最後,你更喜歡有第一種場景的外鍵約束還是更通用的(具有將藝術家鏈接到Track的風險,例如,因爲沒有檢查來查看輸入的外鍵價值真的是一張專輯)的方法?

..btw,想一想,我想你實際上可以檢查一個藝術家的RelField的輸入值是否對應一個專輯,觸發器可能是什麼?

+0

難道不關你的專輯有多位藝術家?你的曲目中是否有多個藝術家?你也沒有錄製像樂隊(管絃樂隊)演奏音樂,獨奏者,指揮,作曲家,編曲者等等的東西。啊,這只是一個問題,但要小心過度簡化。 – 2009-04-08 03:19:14

回答

5

我最近看到這個抽象概念一致地實現,應用程序和它的數據庫變成了一個怪物來維護和排除故障。我會遠離這種技術。越簡單,越好,就是我的口頭禪。

2

在各個實體中不可避免地積累的附加字段將非常少有機會成爲必要條件。沒有以相當接近的方式反映現實,從而無法獲得。

我不認爲你甚至可能會混淆這些實體在你的常規OO設計中。

這讓我想起了一次嘗試在一個表(名爲「Entity」)中實現所有事情的嘗試(但名稱爲「Attributes」)以及它們之間的聯結表。

+1

這種抽象的最終目標是EAV模型(實體,屬性,值),其中絕對一切都可以塞進一個只有三列的表格。無論主題如何變化,模式都不會改變。這是一場噩夢。 – 2009-06-28 11:12:51

0

我同意樂dorfier,你可能會從基礎實體(ID,名稱)的概念中得到一些重用,但超出這一點的藝術家,專輯和曲目的概念將會發生分歧。

和更逼真的模型可能會不得不面對的事實,多位藝術家可能有助於專輯上的單軌...

1

通過stucking所有三個在一起,你讓你的查詢少readble(除非然後將這三個類別分解爲視圖),並且使搜​​索和索引更加困難。

另外,在某些時候,你會希望將屬性添加到一個類別,這是不爲其他屬性。將所有三者結合在一起給你沒有改變你的系統塊的空間。

不要讓你這麼聰明,讓自己絆倒。

1

我可以看到在你的OOP方式做的唯一好處是如果在未來的(即不是藝術家,專輯和曲目等)添加其他元素類型。在這種情況下,您不需要架構更改。

不過,我傾向於選擇非面向對象的方式,只是改變在這種情況下的模式。您使用OOP解決方案時遇到的一些問題有:

  • 如果要添加藝術家的生日日期,該怎麼辦?
  • 如果您想存儲專輯和曲目的持續時間,該怎麼辦?
  • 如果想存儲軌道類型,該怎麼辦?

基本上,如果你想存儲的東西僅僅是一種或兩種元素類型,那該怎麼辦?

1

如果您到這樣的事情的時候,再採取PostgreSQL看看錶繼承。

create table Artist (id integer not null primary key, name varchar(50)); 
create table Album (parent integer foreign key (id) references Artist) inherits (Artist); 
create table Track (parent integer foreign key (id) references Album) inherits (Artist);