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,因为这是对原始问题的完整要求)。