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

Which of these two DB design approaches is better?

我有以下实体,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     |
    +----------+    +----------+       +----------+       +----------+

在本设计中,上述实体的公共属性存储在单独的tableTableCommon中;这个 table 可以被认为是派生出所有其他 table 的基础 table。上面的 Link table 存储了域中一个实体对另一个实体的引用,表示实体之间的多对多关系。

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) |
+----------+          +----------+    +----------+    +----------+

在此设计中,每个实体都由它自己的 table 表示。实体的公共属性未提取到单独的 table 中。但是创建单独的 tables 来表示每个实体之间的多对多关系,例如TableAB代表TableA和TableB之间的link,类似TableBC代表TableB和TableC之间的link等等。在这种情况下,总共有 6 个 tables,TableAB、TableAC、TableAD、TableBC、TableBD 和 TableCD,代表所有 4 个实体 tables、TableA、TableB、TableC 之间的多对多关系和表 D.

从以上两种设计中,我可以想到各自的优缺点:

第一个设计:

优点:

  1. 设计中创建的 table 较少。
  2. 实体公共属性的任何更改只能在一个 table 中进行,即 TableCommon。
  3. 在设计中添加新实体很容易。

缺点:

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

  2. 将条目添加到实体 table 必须在两个 table 内完成。

第二次设计:

优点:

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

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

缺点:

  1. 为存储实体之间的引用创建了太多 table。

  2. 添加新实体很麻烦。

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

以上哪种设计更好,或者有其他更好的方法吗?这里更好的是性能、存储 space、维护和可伸缩性。

我认为你很好地回答了问题的很多部分。我只是通知其他几点。

注1:关于TableCommon策略

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


注2:关于Linktable策略 这里重要的参数:

  1. 实体 A、B、C 和 D 中的记录数
  2. 多对多关系中的记录数
  3. 来自这些多对多关系的 CRUD 数量

如果你有很多条记录并且你有很多 CRUDs并且它们的性能是至关重要的,你不应 使用Link table 策略。

但是,如果您 只有 两个或更多 table(例如 EntityAEntityB)有很多记录在多对多关系中,您可以对它们使用 EntityAB 策略 ,对其他使用 Link table 策略。


注释 3:在实体 A、B、C 和 D

之间使用事实 Table

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

它可能有用

像这样使用 Fact Table:
将所有实体 A、B、C 和 D F.Ks 聚集在一个 table 中。

首先缺点:

  1. 如果多对多关系有很多其他字段,我们不能使用这种策略。
  2. 那个事实 Table.
  3. 有很多不好的 无效化

优点:

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