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显示带有交付物的客户数据。因此,当应用程序的一部分只与可交付成果一起工作时,它不需要知道数据库中存储的细节。视图上的触发器可以轻松创建,删除和操作分组数据。