0

我們的應用程序已經過定製,可處理許多不同類型的客戶,其中某些設置僅適用於少數或一位客戶。我決定添加一個[Settings]表格來允許每個設置成爲一行,而不是連續向客戶表中添加可爲空的列, 。與不同數據類型的多對多關係

[dbo].[Settings] 
    [SettingID] [int] 
    [SettingCode] [nchar](4) 
    [SettingDescription] [nvarchar](255) 

,然後通過一個多到多表連接到[客戶]表

[dbo].[Customer_Settings] 
    [Customer_SettingsID] [int] 
    [CustomerID] [int] 
    [SettingID] [int] 

我的問題是如何處理的事實,許多這些設置需要一個額外的數據在[Customer_Settings]表格上鍵入。

例如,我們可以將一個設置設置爲需要時間數據類型的「最新傳送時間」,或另一個設置爲需要int的「分鐘至期滿」。

兩種方式我能想到的來處理,這是可空列添加到[Customer_Settings表所示:

[dbo].[Customer_Settings] 
    [Customer_SettingsID] [int] 
    [CustomerID] [int] 
    [SettingID] [int] 
    [ValueTime] [time] NULL 
    [ValueInt] [int] NULL 
    ... 

這似乎是糟糕的設計。

我能想到的另一種方法是子表添加到[Customer_Settings表所示:

[dbo].[Customer_Settings_Int] 
    [Customer_Settings_Int_ID] [int] 
    [Customer_SettingsID] [int] 
    [Value] [int] 

這似乎是它是標準化的,但也很麻煩。請讓我知道,如果其中之一顯然更好,或者如果有另一種選擇。謝謝!

+0

您正在進入可怕的Entity-Attribute-Value模式。 –

回答

0

您選擇的解決方案稱爲Entity-Attribute-Value (EAV.)最常用的方法是將所有值存儲爲字符串。有些人添加了一個驗證器列,其中包含一個正則表達式或類似的表達式,經過客戶端驗證或者t-sql函數更新值。

使用可爲空的列要簡潔得多。

+0

感謝您澄清/給出我正在處理的概念的名稱。 「使用可爲空的列要清潔得多。」這是推薦的第一種方法,其中每個數據類型都是可空的列? – FMUser

0

而不是單身屬性的列表,它看起來像你可能能夠將屬性集合到邏輯分組。你暗示「交付的東西」和「過期的東西」可能是兩個這樣的分組。在查找表中,看起來像這樣創建這些分組的列表:

ID Name   Description 
D Deliverable Something that is delivered 
E Expirable Something that expires 

然後創造一種交集表的客戶和分組(與分組類型)

create table CustGrouping(
    CustID int not null references Customer(ID), 
    GroupID int auto_generated, 
    GroupType char(1) not null references Groupings(ID), -- the table above 
    constraint PK_CustGrouping primary key(CustID, GroupID), 
    constraint UQ_Group_Type unique(GroupID, GroupType) 
); 

的PK將防止意外地將客戶與相同的分組進行多次配對。爲什麼當GroupID本身將是唯一的時,爲(GroupID,GroupType)創建唯一約束?所以它可以成爲外鍵的參考點。

對於每個分組,您都需要一個單獨的表格。這裏只是一個:

create table Deliverables(
    ID int not null primary key, 
    TypeID char(1) not null check(TypeID = 'D'), 
    DeliveryDate date not null, 
    ..., -- all other fields that are associated with deliverables 
    constraint FK_Deliverables_CustGrouping foreign key(ID, TypeID) 
    references CustGrouping(GroupID, GroupType) 
); 

檢查約束條件顯示只有可交付數據可寫入該表。

這裏是操作序列:

  1. 當爲客戶生成交付,插入到與CustGrouping客戶ID和分組標誌符(「d」)。這會生成此可交付物的ID。
  2. 使用生成的ID將可交付數據插入交付物表中。

相同的操作適用於其他分組。分組ID確保該組的FK只能引用正確類型的分組。它還可以讓你知道哪個表包含數據,這些數據對於每種分組都是完全不同的。它的可擴展性在於添加一種新的分組類型,將定義插入到分組表中,創建一個表來包含所需長度和格式的數據並從那裏開始。

我會進一步建議創建視圖來顯示每種分組的客戶數據。例如,視圖CustomerDeliverables顯示帶有交付物的客戶數據。因此,當應用程序的一部分只與可交付成果一起工作時,它不需要知道數據庫中存儲的細節。視圖上的觸發器可以輕鬆創建,刪除和操作分組數據。