我需要一个db来存储,即用户记录。常规的东西:姓名,电子邮件,地址,电话,传真等。问题是,在这种情况下,每个用户可以有多个电话号码。还有不止一封电子邮件。甚至不止一个地址。而且还有更多不止一个的东西。
一种方法是将所有内容存储在一个表中,例如一个电话列中的序列化电话阵列。或者在一个电话栏中用逗号分隔手机。但我真的不喜欢这种方式,我宁愿做过于复杂的数据库,以使编程逻辑比其他方式更简单。
另一个是电话的个人表,地址的个人表等。列: ID , customer_id ,电话。 customer_id 参考 客户。 id 现在这看起来真的有点过头了,只有10个表用于存储联系人详细信息
我提出的另一个想法是另外一个用于联系人的表格,例如 id , customer_id (< -foreign key),键,值。钥匙可以是“电话”和价值“+123 3435454”,或关键“电子邮件”和价值......你明白了。到目前为止,我最喜欢这个。
你会建议什么? #3方法的缺点是什么?
db我将使用 postgresql ,但它并不重要。
答案 0 :(得分:3)
每个实体一个表行是正确的。因此,一个用于电子邮件,一个用于电话号码等是正确的。这不是过度杀伤:它是规范化的数据库设计。
您的选项3可以完成,但是,如果您想对电话号码和电子邮件地址强制执行某种模式会怎样?
答案 1 :(得分:3)
有些人可能会说方法#3是最好的。其他人会说它基本上是数据库中最常见的反模式之一 - 即EAV,这引起了很多仇恨。
至于我 - 我对你提出解决方案的申请知之甚少。通常 - 方法#2为您提供最多的功能。
还有方法#4,它的变体 - 方法#5:
4 - 使用值数组 - 即电话列,而不是TEXT数据库,是TEXT [],然后您可以在其中存储许多电话。
5 - 因为你在PostgreSQL上 - 使用它。在contrib中有非常酷的hstore数据类型,您可以使用它来代替数组来添加一些语义(如手机类型)。
答案 2 :(得分:2)
缺点:
看似下注选项,但可以通过使用域表来获取该“关键”值进行规范化
Customer (Id, Name)
AdditionalData( Id, Name )
(电话,地址等)CustomerAdditionalData(Id, CustomerId, AdditionalDataId, Value)
答案 3 :(得分:2)
一些纯粹主义者会建议不要走3条路。事实上,使用这种方法,理论上可以构建一个表数据库!
然而,正如gbn所提到的,这会导致特定格式出现问题,您只需要在客户端上强制执行数据长度等。
我会考虑你的第二个建议,并使用具有不同表格的方法,地址类型,电话号码类型等类似于下面所示。
身份证号码 addrss_type varchar(主页/联系人/邮件等) addrs_line1 varchar addrs_line2 varchar 等等