这两种数据库设计方法中哪一种更好?
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.
从以上两种设计中,我可以想到各自的优缺点:
第一个设计:
优点:
- 设计中创建的 table 较少。
- 实体公共属性的任何更改只能在一个 table 中进行,即 TableCommon。
- 在设计中添加新实体很容易。
缺点:
所有添加、更新和删除都必须通过单个 table、TableCommon 进行,以保持参照完整性。这可能是一个瓶颈。
将条目添加到实体 table 必须在两个 table 内完成。
第二次设计:
优点:
每个实体都由一个单独的table表示,因此在添加、更新和删除时没有瓶颈。
在实体 table 中添加条目必须在单个 table 中完成。
缺点:
为存储实体之间的引用创建了太多 table。
添加新实体很麻烦。
必须在所有实体 table 中更改实体的公共属性。
以上哪种设计更好,或者有其他更好的方法吗?这里更好的是性能、存储 space、维护和可伸缩性。
我认为你很好地回答了问题的很多部分。我只是通知其他几点。
注1:关于TableCommon
策略
我强烈推荐使用TableCommon
来保存常用字段。它对您的评估参数(性能、冗余、可扩展性、维护等)没有太多副作用。
注2:关于Link
table策略
这里重要的参数:
- 实体 A、B、C 和 D 中的记录数
- 多对多关系中的记录数
- 来自这些多对多关系的 CRUD 数量
如果你有很多条记录并且你有很多 CRUDs并且它们的性能是至关重要的,你不应 使用Link
table 策略。
但是,如果您 只有 两个或更多 table(例如 EntityA
和 EntityB
)有很多记录在多对多关系中,您可以对它们使用 EntityAB
策略 仅 ,对其他使用 Link
table 策略。
注释 3:在实体 A、B、C 和 D
之间使用事实 Table
我第一眼就知道非常糟糕的设计。
但是,根据评估参数,在某些情况下。
它可能有用
像这样使用 Fact Table:
将所有实体 A、B、C 和 D F.Ks 聚集在一个 table 中。
首先缺点:
- 如果多对多关系有很多其他字段,我们不能使用这种策略。
- 那个事实 Table.
有很多不好的 无效化
优点:
- 您可以在一条记录中获取所有
EntityA
个关系。
- 减少实体数量。
- 减少记录数。
我有以下实体,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.
从以上两种设计中,我可以想到各自的优缺点:
第一个设计:
优点:
- 设计中创建的 table 较少。
- 实体公共属性的任何更改只能在一个 table 中进行,即 TableCommon。
- 在设计中添加新实体很容易。
缺点:
所有添加、更新和删除都必须通过单个 table、TableCommon 进行,以保持参照完整性。这可能是一个瓶颈。
将条目添加到实体 table 必须在两个 table 内完成。
第二次设计:
优点:
每个实体都由一个单独的table表示,因此在添加、更新和删除时没有瓶颈。
在实体 table 中添加条目必须在单个 table 中完成。
缺点:
为存储实体之间的引用创建了太多 table。
添加新实体很麻烦。
必须在所有实体 table 中更改实体的公共属性。
以上哪种设计更好,或者有其他更好的方法吗?这里更好的是性能、存储 space、维护和可伸缩性。
我认为你很好地回答了问题的很多部分。我只是通知其他几点。
注1:关于TableCommon
策略
我强烈推荐使用TableCommon
来保存常用字段。它对您的评估参数(性能、冗余、可扩展性、维护等)没有太多副作用。
注2:关于Link
table策略
这里重要的参数:
- 实体 A、B、C 和 D 中的记录数
- 多对多关系中的记录数
- 来自这些多对多关系的 CRUD 数量
如果你有很多条记录并且你有很多 CRUDs并且它们的性能是至关重要的,你不应 使用Link
table 策略。
但是,如果您 只有 两个或更多 table(例如 EntityA
和 EntityB
)有很多记录在多对多关系中,您可以对它们使用 EntityAB
策略 仅 ,对其他使用 Link
table 策略。
注释 3:在实体 A、B、C 和 D
我第一眼就知道非常糟糕的设计。
但是,根据评估参数,在某些情况下。
像这样使用 Fact Table:
将所有实体 A、B、C 和 D F.Ks 聚集在一个 table 中。
首先缺点:
- 如果多对多关系有很多其他字段,我们不能使用这种策略。
- 那个事实 Table. 有很多不好的 无效化
优点:
- 您可以在一条记录中获取所有
EntityA
个关系。 - 减少实体数量。
- 减少记录数。