如何实现从一个table到两个table的一对一关系?
how to implement one to one relationship from one table to two tables?
我的 Mysql 数据库有两个 table:
一个是 payments_by_check 的 table 另一个是 payments_by_credit_card.
有一个选项可以取消所有人,所以我创建了一个新的 table 用于取消。
每笔支票付款或信用卡付款可能有取消记录table,也可能没有。
我不知道正确的构建方式是什么,选项是:
- 在每个付款中添加取消 ID 列 table。
- 在取消中添加 table 一列用于通过支票 ID 付款,以及
另一个通过信用卡 ID 支付,每条记录都会
有一个是空的。
付款 table 非常大,所以我宁愿避免向 table 添加列。
我的问题是:
选择第二个选项是否正确?
对性能有影响吗?
付款 table 很大。取消 table 小得多,对吗?也就是说,Cancellations
将只有 行 用于取消,而不是未取消的付款。
Cancellations
有一列 JOINing
到 Payments
,对吗?因此,它实际上并不需要包含 payment_type 或数量。只是 cancellation_date
和一些管理内容。
有了两个 table,LEFT JOIN
或 UNION
可以在您需要查看两个信息位时将它们放在一起。所以,这不是 'real' 问题,只是编码麻烦。
支票付款和信用卡付款是所谓的经典案例"generalization/specialization"。这大致相当于对象建模中的 类 和 sub类。您可以通过搜索网络找到一些关于如何在 ER 模型中包含 gen-spec 的好文章。
当您使用关系 table 实现此设计时,事情会变得有趣。有两种广泛使用的方法:Single-table-inheritance 和 Class-table-inheritance。 Whosebug 中有两个具有这些名称的选项卡。如果您查看这些选项卡下的信息,您将获得一个概览。您也可以在网上查找这些内容。我特别喜欢 Martin Fowler 的治疗方法。每种选择都有其优点和缺点。
在您的情况下,我会使用单一 Table 继承方法,两种类型都只有一个付款 table。您必须有一个列来说明每笔付款的类型,加上一些仅与信用卡付款有关的列,以及一些仅与支票付款有关的列。
但这是你的决定。如果您决定改用 Class-table-inheritance,并且您使用 Shared-Primary-Key 在所有三个 table 之间共享 ID,您会发现效果很好,也是。
正如@Walter Mitty 所提到的,问题的正常解决方案类似于:
如果这种重组不可用,则:
Is it correct to take the second option?
1和2都会有一些问题,但是可以根据自己的需要来应用。
解决方案 1: 将取消 ID 列添加到付款 tables
设计问题:
- 取消记录可以存在,没有相关记录
付款 tables.
- 一条取消记录可以存在,相关的不止一条
付款记录 tables.
性能问题:
创建取消记录将需要在取消中插入一项,并在相关付款记录中进行一项更新。
解决方案二: 在 Cancellation 中有付款 FK table.
有两个可为空的外键列,但必须填充一个,只需要一个检查约束即可实现。
设计问题:
性能问题:
检测付款记录是否被取消将需要查询表单付款加入取消 table.
如果读取性能第一优先。
在数据一致性+写性能的情况下优先考虑No.2
我更喜欢的另一种混合解决方案是使用 2 号解决方案加上一个名为 is-cancelled in payment tables 的列(以克服读取性能)
我的 Mysql 数据库有两个 table:
一个是 payments_by_check 的 table 另一个是 payments_by_credit_card.
有一个选项可以取消所有人,所以我创建了一个新的 table 用于取消。
每笔支票付款或信用卡付款可能有取消记录table,也可能没有。
我不知道正确的构建方式是什么,选项是:
- 在每个付款中添加取消 ID 列 table。
- 在取消中添加 table 一列用于通过支票 ID 付款,以及 另一个通过信用卡 ID 支付,每条记录都会 有一个是空的。
付款 table 非常大,所以我宁愿避免向 table 添加列。
我的问题是:
选择第二个选项是否正确?
对性能有影响吗?
付款 table 很大。取消 table 小得多,对吗?也就是说,Cancellations
将只有 行 用于取消,而不是未取消的付款。
Cancellations
有一列 JOINing
到 Payments
,对吗?因此,它实际上并不需要包含 payment_type 或数量。只是 cancellation_date
和一些管理内容。
有了两个 table,LEFT JOIN
或 UNION
可以在您需要查看两个信息位时将它们放在一起。所以,这不是 'real' 问题,只是编码麻烦。
支票付款和信用卡付款是所谓的经典案例"generalization/specialization"。这大致相当于对象建模中的 类 和 sub类。您可以通过搜索网络找到一些关于如何在 ER 模型中包含 gen-spec 的好文章。
当您使用关系 table 实现此设计时,事情会变得有趣。有两种广泛使用的方法:Single-table-inheritance 和 Class-table-inheritance。 Whosebug 中有两个具有这些名称的选项卡。如果您查看这些选项卡下的信息,您将获得一个概览。您也可以在网上查找这些内容。我特别喜欢 Martin Fowler 的治疗方法。每种选择都有其优点和缺点。
在您的情况下,我会使用单一 Table 继承方法,两种类型都只有一个付款 table。您必须有一个列来说明每笔付款的类型,加上一些仅与信用卡付款有关的列,以及一些仅与支票付款有关的列。
但这是你的决定。如果您决定改用 Class-table-inheritance,并且您使用 Shared-Primary-Key 在所有三个 table 之间共享 ID,您会发现效果很好,也是。
正如@Walter Mitty 所提到的,问题的正常解决方案类似于:
如果这种重组不可用,则:
Is it correct to take the second option?
1和2都会有一些问题,但是可以根据自己的需要来应用。
解决方案 1: 将取消 ID 列添加到付款 tables
设计问题:
- 取消记录可以存在,没有相关记录 付款 tables.
- 一条取消记录可以存在,相关的不止一条 付款记录 tables.
性能问题:
创建取消记录将需要在取消中插入一项,并在相关付款记录中进行一项更新。
解决方案二: 在 Cancellation 中有付款 FK table.
有两个可为空的外键列,但必须填充一个,只需要一个检查约束即可实现。
设计问题:
性能问题:
检测付款记录是否被取消将需要查询表单付款加入取消 table.
如果读取性能第一优先。
在数据一致性+写性能的情况下优先考虑No.2
我更喜欢的另一种混合解决方案是使用 2 号解决方案加上一个名为 is-cancelled in payment tables 的列(以克服读取性能)