为什么我不应该为多个关系使用一张表?

Tom*_*icz 14 database-design

假设我的数据库中有多个关系,例如 Store、Employee 和 Sale,并且我想用简单的二元关系连接对。我个人会使用由外键组成的自然键创建名为 Employee_Store 和 Employee_Sale 的表。

现在,我的同事坚持为多个关系创建一张表。对于上面的示例,可能有一个名为 EmployeeLinks 的表:

EmployeeLinks(
    IdLink int PK, 
    IdEmployee int FK null,
    IdStore int FK null,
    IdSale int FK null,
    LinkType int not null
)
Run Code Online (Sandbox Code Playgroud)

请帮助我说明为什么这不是一个好主意的充分理由。我有自己的论点,但我想将它们保密并听取您的公正意见。

编辑:

最初上表没有主键 (!)。因为外键允许为空,所以代理键是唯一的选择。

gbn*_*gbn 14

你的同事建议什么作为这个链接表的主键?
主键列当然不能为NULL:上表有可为空的。

在上面的示例中(IDENTITY 列不是主键)没有任何自然的行标识符(PK 是什么),因此它在任何建模过程中都失败了。甚至不要考虑在没有模型的情况下创建表(ERD、ORM、IDEF1X 等等)

您还需要 CHECK 约束以确保您没有 3 路链接。

最后,您误入了第 4 和第 5 范式领域,但出于错误的原因。

我在互联网上找不到任何例子:这表明这是多么愚蠢

  • +1 表示`我在互联网上找不到任何示例:这表明这是多么愚蠢` (4认同)

JNK*_*JNK 12

我能想到的第一个实际原因是性能。

在“传统”模型中,您可以Idemployee, Idstore在字段或任何字段上拥有唯一索引,并在查找时获得出色的性能。刀片也易于维护。唯一索引让你更频繁地合并连接,这可以使很多JOINs 非常快。

在您的示例模型中,为了获得不错的性能,您至少需要在表中的每个 FK 字段上都有一个单独的字段索引,理想情况下,所有将被引用的组合上都有一个覆盖索引,即:

  • 员工/商店
  • 员工/销售

我不确定链接类型是什么,但如果你引用它,它可能应该被索引。

无论是否填充该字段,都需要为表中的每一行维护这些索引。您可以添加一个过滤器,但如果有这么多组合,这也会变得很棘手。

它也会使您的逻辑复杂化。 您要么需要对employeeid 进行查找,找到具有空存储值的行,然后进行更新;或者,只是为每个新链接插入一个新行,这违背了合并字段的目的。

基本上,您将使用更多的磁盘空间,维护更多的索引,并且基本上毫无理由地使您的逻辑复杂化。唯一的“好处”是处理的表更少。