这两种数据库设计方法中的哪一种更好?

时间:2018-01-18 11:52:02

标签: database database-design entity-relationship

我有以下实体,EntityA,EntityB,EntityC和EntityD:

+----------+    +----------+    +----------+    +----------+
|  EntityA |    |  EntityB |    |  EntityC |    |  EntityD |
+----------+    +----------+    +----------+    +----------+
|  FC1     |    |  FC1     |    |  FC1     |    |  FC1     |
|  FC2     |    |  FC2     |    |  FC2     |    |  FC2     |
|  FC3     |    |  FC3     |    |  FC3     |    |  FC3     |
|  FC4     |    |  FC4     |    |  FC4     |    |  FC4     |
|  EA1     |    |  EB1     |    |  EC1     |    |  ED1     |
|  EA2     |    |  EB2     |    |  EC2     |    |  ED2     |
|  EA3     |    |          |    |  EC3     |    |  ED3     |
|  EA4     |    |          |    |          |    |  ED4     |
+----------+    +----------+    +----------+    +----------+

每个实体都具有在所有实体中共同的属性FC1,FC2,FC3和FC4;某些属性特定于实体。此外,每个实体都引用域中的每个其他实体。实体之间存在多对多的关系。

以下哪种数据库设计更好?或者还有其他比下面描述的更好的方法吗?

1)

                              +-------------+
                              |    Link     |
                              +-------------+
                          +---|  id_T1(FK)  |
                          +---|  id_T2(FK)  |
    +---------------+     |   +-------------+
    |  TableCommon  |     |
    +---------------+     |
+-->|  id(PK)       |<----+-------+------------------+------------------+
|   |  FC1          |             |                  |                  |
|   |  FC2          |             |                  |                  |
|   |  FC3          |             |                  |                  |
|   |  FC4          |             |                  |                  |
|   +---------------+             |                  |                  |
|                                 |                  |                  |
|   +----------+    +----------+  |    +----------+  |    +----------+  |
|   |  TableA  |    |  TableB  |  |    |  TableC  |  |    |  TableD  |  |
|   +----------+    +----------+  |    +----------+  |    +----------+  |
+---|  id(FK)  |    |  id(FK)  |--+    |  id(FK)  |--+    |  id(FK)  |--+
    |  EA1     |    |  EB1     |       |  EC1     |       |  ED1     |
    |  EA2     |    |  EB2     |       |  EC2     |       |  ED2     |
    |  EA3     |    |          |       |  EC3     |       |  ED3     |
    |  EA4     |    |          |       |          |       |  ED4     |
    +----------+    +----------+       +----------+       +----------+

在此设计中,上述实体的公共属性存储在单独的表TableCommon中;这个表可以被认为是从中导出每个其他表的基表。上面的链接表将一个实体的引用存储到域中代表实体之间多对多关系的其他实体。

2)

+----------+          +----------+    +----------+    +----------+
|  TableA  |          |  TableB  |    |  TableC  |    |  TableD  |
+----------+          +----------+    +----------+    +----------+
|  id(PK)  |<--+  +-->|  id(PK)  |    |  id(PK)  |    |  id(PK)  |
|  FC1     |   |  |   |  FC1     |    |  FC1     |    |  FC1     |
|  FC2     |   |  |   |  FC2     |    |  FC2     |    |  FC2     |
|  FC3     |   |  |   |  FC3     |    |  FC3     |    |  FC3     |
|  FC4     |   |  |   |  FC4     |    |  FC4     |    |  FC4     |
|  EA1     |   |  |   |  EB1     |    |  EC1     |    |  ED1     |
|  EA2     |   |  |   |  EB2     |    |  EC2     |    |  ED2     |
|  EA3     |   |  |   |          |    |  EC3     |    |  ED3     |
|  EA4     |   |  |   |          |    |          |    |  ED4     |
+----------+   |  |   +----------+    +----------+    +----------+
               |  |
+----------+   |  |   +----------+    +----------+    +----------+
| TableAB  |   |  |   | TableAC  |    | TableAD  |    | TableBC  |
+----------+   |  |   +----------+    +----------+    +----------+
| id_1(FK) |---+  |   | id_1(FK) |    | id_1(FK) |    | id_1(FK) |  ...
| id_2(FK) |------+   | id_2(FK) |    | id_2(FK) |    | id_2(FK) |
+----------+          +----------+    +----------+    +----------+

在此设计中,每个实体都由它自己的表表示。实体的公共属性不会提取到单独的表中。但是创建单独的表来表示每个实体之间的多对多关系,例如, TableAB表示TableA和TableB之间的链接,类似地,TableBC表示TableB和TableC之间的链接,依此类推。在这种情况下,将有总共6个表,TableAB,TableAC,TableAD,TableBC,TableBD和TableCD,表示所有4个实体表TableA,TableB,TableC和TableD之间的多对多关系。

从以上两个设计中我可以想到每个设计的优点和缺点:

首先设计:

优点:

  1. 设计中创建的表格较少。
  2. 实体的公共属性的任何更改都必须只在一个表TableCommon中进行。
  3. 在设计中添加新实体很容易。
  4. 缺点:

    1. 所有添加,更新和删除都必须通过单个表TableCommon进行,以保持参照完整性。这可能是一个瓶颈。

    2. 在实体表中添加条目必须在两个表中完成。

    3. 第二次设计:

      优点:

      1. 每个实体都由一个单独的表表示,因此在添加,更新和删除时没有瓶颈。

      2. 在实体表中添加条目必须在一个表中完成。

      3. 缺点:

        1. 创建的表太多,无法在实体之间存储引用。

        2. 添加新实体非常麻烦。

        3. 必须在所有实体表中更改实体的公共属性。

        4. 上述哪种设计更好,还是有其他更好的方法?在性能,存储空间,维护和可扩展性方面更好。

1 个答案:

答案 0 :(得分:0)

我认为你很好地回答了很多问题。我只是通知其他一些观点。

注1 :关于TableCommon策略

我强烈建议您使用TableCommon来保存常用字段。它对您的评估参数(性能,冗余,可扩展性,维护等)没有太多副作用。


注意2 :约Link表策略 这里重要的参数:

  1. 实体A,B,C和D中的记录数
  2. 他们之间的多对多关系中的记录数
  3. 来自这些多对多关系的CRUD数量
  4. 如果你有很多记录并且你有很多 CRUD并且它们的性能至关重要,那么不应该使用Link表策略。

    但是,如果您有两个或更多个表(例如EntityAEntityB),这些表在多对多关系中有很多记录,那么可以对他们使用EntityAB策略 ,并为其他人使用Link表策略。


    注释3 :在实体A,B,C和D之间使用事实表

    我知道第一眼就是非常糟糕的设计
    但是,根据评估参数,在某些情况下可以有用

    使用这样的事实表:
    在一个表格中收集所有实体A,B,C和D的F.Ks。

    首先缺点:

    1. 如果多对多关系包含许多其他字段,我们无法使用此策略。
    2. 事实表中有许多不良 Nullification
    3. 优点:

      1. 您可以在一条记录中获取所有EntityA个关系。
      2. 减少实体数量。
      3. 减少记录数量。