如何实现从一个表到两个表的一对一关系?

时间:2015-06-29 07:53:54

标签: mysql database-design relationship one-to-one

我有两个表的Mysql数据库:
一个是payments_by_check表,另一个是payments_by_credit_card。

有一个选项可以取消所有人,所以我创建了一个新的取消表 每张支票付款或信用卡付款都可能在取消表中记录,可能没有。

我不知道构建它的正确方法是什么,选项是:

  1. 在付款表的每个人中添加取消ID列。
  2. 通过支票ID添加取消表一列付款,以及 另一个用信用卡ID付款,每个记录都会 其中一个是空的。
  3. 付款表非常大,所以我宁愿避免在这些表中添加列。

    我的问题是:
    采取第二种选择是否正确?
    它对表演有什么影响吗?

3 个答案:

答案 0 :(得分:1)

支票付款和信用卡付款是所谓“概括/专业化”的典型案例。这大致相当于对象建模中的类和子类。您可以通过搜索网络找到一些关于如何在ER模型中包含gen-spec的好文章。

当您使用关系表实现此设计时,事情变得有趣。有两种广泛使用的方法:单表继承和类表继承。 StackOverflow中有两个带有这些名称的选项卡。如果您查看这些标签下的信息,您将获得一个概述。您也可以在网上查看这些内容。我特别喜欢Martin Fowler的治疗方法。每种选择都有其优点和缺点。

在您的情况下,我将使用单表继承方法,两种类型只有一个Payments表。您必须有一个专栏说明每种付款的类型,以及仅与信用卡付款相关的几个列,以及一些仅与支票付款相关的列。

但这是你的电话。如果您决定使用Class-table-inheritance,并且使用Shared-Primary-Key在所有三个表中共享ID,那么您也会发现wotks非常好。

答案 1 :(得分:0)

付款表很大。取消表格小得多,对吗?也就是说,Cancellations只有行 才能取消,而非取消付款。

CancellationsJOINingPayments的列,对吗?因此,它实际上不需要包含payment_type或金额。只需cancellation_date和一些管理员。

使用两个表时,LEFT JOINUNION可以在需要查看两个信息时将它们组合在一起。所以,这不是一个“真正的”问题,只是一个编码麻烦。

答案 2 :(得分:0)

提到@Walter Mitty,问题的正常解决方案如下:

enter image description here

如果没有这样的重组,那么:

  

采取第二种选择是否正确?

1& 2会有一些问题,但两者都可以根据您的需要进行应用。

解决方案1:将取消ID列添加到付款表中 enter image description here
设计问题:

  1. 可以存在取消记录,但没有相关记录 付款表。
  2. 可以存在取消记录,其中包含多个相关记录 在支付表中记录。
  3. 性能问题:
    创建取消记录需要在取消内部插入一个,在相关的付款记录中进行一次更新。


    解决方案2:在取消表中付款FK enter image description here
    拥有两个可以为空的外键列,但必须填写一个,只需要一个检查约束即可实现此目的。

    设计问题:

    性能问题:
    检测付款记录是否被取消将需要查询表格付款加入取消表。

    在读取性能的情况下,首选1号 在数据一致性+写入性能的情况下,2号是首选。

    我更喜欢的另一种混合解决方案是使用No.2解决方案,并在付款表中使用一个名为is-cancelles的列(以克服读取性能)