1

Database Schema如何處理可選列

我的問題是有關ServiceASpecificFieldServiceBSpecificField。我覺得這兩個字段放置不當,因爲SubscriberServiceMap表中所有用戶的service A的所有記錄中,ServiceBSpecificField將具有空值,反之亦然。

如果我在Subscribers表中移動這兩個字段,那麼我會遇到另一個問題。所有那些僅利用service A的訂戶將在Subscribers.ServiceBSpecificField中爲空值。

那麼理想情況下應該做什麼?

+0

這將是也很大,如果有人可以給我建議的具體標題這個問題,因爲我不知道該怎麼總之把這個問題做。這會促使其他人回答,否則目前的標題是非常通用的,以至於很多人可能不願意打開這篇文章。 – IsmailS 2010-12-24 12:36:52

+1

的問題應該是「如何處理可選列」 – PerformanceDBA 2010-12-25 03:34:10

+0

@PerformanceDBA,謝謝,我已經更新了標題。 – IsmailS 2011-01-06 12:36:17

回答

1

一個簡單的方法來做到這一點是要問自己:難道這些列的值會根據認購SubscriberServiceMap表)或服務

如果「服務A」的每個用戶具有ServiceASpecificField的相同值,那麼只有您必須將其移至Services表中。

您預計會有多少這樣的字段? ServiceASpecificField,ServiceBSpecificField,C,D ...等等?如果這個數字很大,你可以去EAV model,這將涉及到另一個表的創建。在Service_A and _B表像

-1

如果ServiceSpecificField的值取決於服務和訂閱者以及所有訂閱服務對,則字段的類型是相同的(正如我在示例中看到的 - varchar(50)適用於這兩個字段),則I將僅更新SubscriberSerivceMap表:這種表的

table SubscriberSerivceMap: 
Id 
SubscriberId 
ServiceId 
SpecificField 

例子:

Id    SubscriberId  Service Id  SpecifiedField 
1     1     1    sub1_serv1 
2     1     2    sub1_serv2 
3     2     1    sub2_serv1 
4     2     2    sub2_serv2 
+0

由於每個訂閱者的值不同,因此無法將其移動到「服務」表。 – IsmailS 2010-12-23 06:21:16

3

alt text

地方檢查約束:

alter table Service_A add constraint chk_A check (ServiceID = 1); 
alter table Service_B add constraint chk_B check (ServiceID = 2); 

那麼柔可以加入像

select * 
from SubscriberService as x 
left join Service_A as a on (a.SubscriberID = x.SubscriberID and a.ServiceID = x.ServiceID) 
left join Service_B as b on (b.SubscriberID = x.SubscriberID and b.ServiceID = x.ServiceID) 
2

這是一個簡單的超型亞型的問題,你可以在5NF解決,您不需要EAV或改進的EAV或6NF(完整和最終的正確EAV)。由於ServiceAColumn的值取決於特定訂戶對該服務的訂閱,因此它必須位於關聯表中。

▶Normalised Data Model◀(內嵌鏈接不上某些瀏覽器/版本。)

讀者誰是不熟悉的關係建模標準可能會發現▶IDEF1X Notation◀有用。

  • 這是一個普通的關係超型亞型結構。這一個是獨家:一個Service是一個子類型。

  • 在這個模型中的關係和子類型比其他答案更明確和更受控制。例如。FK關係特定於Service子類型,而不是Service超類型。

  • 鑑別器,用於標識任何超類型行是亞型,是ServiceTypeServiceType不需要在子類型中重複,我們知道子類型表是哪個子類型。

  • 除非你有百萬Services,短代碼是不是沒有意義的數字更合適的PK。

其他

  • 可以在SubscriberService失去了Id列,因爲它是100%的冗餘,並沒有任何用處。

  • SubscriberService的PK是(SubscriberId, ServiceId),除非你想要重複的行。

  • 請更改列名:Subscriber.IdSubscriberId; Service.IdServiceId。切勿使用Id作爲列名稱。對於PK和FK,一直使用完整的列名稱。當你開始編碼時,相關性將變得很清楚。

第六範式或EAV

添加列和表將具有新的屬性,是很好,需要在關係數據庫中新的服務時,你保留了大量的控制和完整性。

如果您不想「爲每個新服務添加新表」,那麼請使用EAV或6NF,但要確保關係數據庫中具有常規控件(類型安全)和數據和參照完整性。 EAV常常沒有適當的關係控制和完整性,導致許多問題。這是關於該主題的question/answer。如果確實如此,並且該問題中的數據模型不夠明確,請告訴我,我將爲您提供一個特定於您的需求的數據模型(我上面提供的DM是純5NF,因爲這是對原始問題的完整要求)。