MySQL:最好有两个表或两列

时间:2017-05-26 14:22:21

标签: mysql database-design relational-database

我有一个包含联系人的数据库。有两种不同类型的联系人,即供应商和客户。

Vendor表具有通过外键值附加的vendor_contacts表,以允许一对多关系。客户端有一个类似的表。

这些联系人可以与电话号码表有一个或多个关系。我是否应该为每个或一个共享电话号码表分别使用一个电话号码表,其中两个外键允许一个为空?

选项1

enter image description here

在这里,我必须强制执行vendor_id或client_id中的一个为NULL而另一个在共享电话表中不为NULL。

选项2

enter image description here

此处每张表都有自己的电话号码表。

5 个答案:

答案 0 :(得分:3)

我会使用两个不同的表,vendor_contacts表和client_contacts表。 如果您只有一个表,则总是浪费空间,因为每行中都有一个空列

答案 1 :(得分:3)

TBH我会合并供应商和客户表,并有一个联系人'表。这可能具有联系类型,并允许添加更新的联系人。 考虑你想要给你的联系人添加一些东西 - 地址,你可能必须以同样的方式改变每个表,然后你想要生日(好吧可能不是但仅作为一个例子)再次,改变多个表。如果您有一个表,它可以减少管理它的开销。 这也意味着你有一个联系电话号码表!

答案 2 :(得分:3)

在现代数据库系统中,“浪费空间”并不是真正有意义的问题 - 并且“null”值通常由存储引擎优化,无论如何都不占用空间。

相反,我认为您需要查看可能的查询方案,可维护性以及架构的可理解性。

因此,通常情况下,重复自身的架构 - 许多具有相似列的表 - 表明可维护性较差,并且通常会导致复杂的查询。

在您的示例中,想象一个查询,以找出从给定号码打来的人,以及他们可能试图联系的人。

在选项1中,您查询电话号码,并将其连接到两个联系人表 - 相对容易。在选项2中,你有两个类似查询的联合(只有表名会改变) - 重复和很多错误的机会。

想象一下,您想要将电话号码分成国家,地区和电话号码 - 在选项2中,您必须执行此操作两次(并修改所有查询两次);在选项1中,您只需执行一次。

一般而言,重复是软件设计不良的标志;这也是数据库模式的重要原因。

这也是一个原因(正如@siggisv和@NigelRen建议的那样)将vendor_contact和client_contact表压缩成一个带有“contact_type”列的表。

答案 3 :(得分:2)

选项2

但将vendor_contact和client_contact更改为' contact'

并添加'类型'列到'联系'确定了客户'或者'供应商'如果你需要分开记录。

答案 4 :(得分:2)

我会像其他人一样建议并将vendor_contactclient_contact合并到一个contact表中。

但最重要的是,我怀疑contact<->phone是一对多的关系。如果你考虑这个例子,你会发现它是一个多对多的关系:

  

&#34; Joe和Mary都是供应商,在同一个办公室工作。因此他们都有相同的固定电话号码。他们也有自己的手机号码。&#34;

因此,在我看来,您需要添加一个contact_number表,其中包含两列外键,contact_idphone_id