多个外键

时间:2013-06-28 05:36:18

标签: sql database modeling database-performance

我在应用程序中有以下场景。

一个名为Structure的实体,另一个名为Customer的实体和另一个名为Organization的实体。所有这些实体都有可选的0-> N电话,因此,我创建了4个表

Structure 
ID_STRUCTURE (PK)
NAME VARCHAR

Customer
ID_CUSTOMER (PK)
RGI VARCHAR

Organization
ID_ORGANIZATION (PK)
ALIAS VARCHAR

Telephone
ID_TELEPHONE
NUMBER
ID_STRUCTURE (FK)
ID_CUSTOMER (FK)
ID_ORGANIZATION (FK)

三个foreigns中的一个key始终具有值,另外两个始终填充null。

注册示例:

ID_TELEPHONE NUMBER ID_STRUCTURE ID_COSTUMER ID_ORGANIZATION
      1       1234        1         null         null
      2       4322        null       1           null 
      3       4333        null      null         2
      4       4233        null      null         2    

我的DBA说这是一种错误的方法(并没有规范化)和sugest N:N表来避免这个nullables fk。但业务规则不允许N:N建议。但这次讨论是关于正常化的。

我错了,这种做法没有正常化?或者它是正确的,没有任何意外问题?

1 个答案:

答案 0 :(得分:2)

它没有标准化,因为ID_STRUCTURE ID_COSTUMER ID_ORGANIZATION的值取决于彼此的值。您必须确保3个属性中只有一个不为null。并且它浪费空间来存储空值。

您可以尝试这种方法

TelephoneOwner
ID_Owner (PK)

Telephone
ID_TELEPHONE
NUMBER
ID_Owner (FK)

Structure 
ID_STRUCTURE (PK)
ID_Owner (FK)

Customer
ID_CUSTOMER (PK)
ID_Owner (FK)

Organization
ID_ORGANIZATION (PK)
ID_Owner (FK)

添加新的talbe TelephoneOwner。所有实体Structure,Customer和Organization都是所有者,因此为它们添加ID_Owner字段。每个电话可以由一个所有者拥有,因此也添加一个ID_Owner字段。

添加新实体(例如Structure)时,添加新的TelephoneOwner和新结构。当实体获得电话时,将电话的ID_Owner设置为实体的ID_Owner。

如果没有关于所有权的其他特定信息(例如过期日期)放入TelephoneOwner表,您可以忽略TelephoneOwner表,并将实体的ID_Owner字段替换为ID_TELEPHONE。

Telephone
ID_TELEPHONE
NUMBER

Structure 
ID_STRUCTURE (PK)
ID_TELEPHONE (FK)

Customer
ID_CUSTOMER (PK)
ID_TELEPHONE (FK)

Organization
ID_ORGANIZATION (PK)
ID_TELEPHONE (FK)