我很难弄清楚何时在数据库设计中使用1对1的关系,或者是否有必要。
如果您只能在查询中选择所需的列,则有必要将表拆分为1对1关系。我想更新一个大表比一个较小的表对性能的影响更大,我确信它取决于表用于某些操作(读/写)的重量程度
因此,在设计数据库模式时,您如何将1对1关系考虑在内?您使用什么标准来确定是否需要一个标准,与不使用标准有什么好处?
答案 0 :(得分:35)
从逻辑角度来看,1:1关系应始终合并为一个表。
另一方面,对于此类"vertical partitioning"或“行拆分”可能存在物理注意事项,尤其是如果您知道您将更频繁地访问某些列或以不同的方式访问某些列其他人,例如:
数据库非常擅长操作数据,所以我不会仅仅为了更新性能拆分表,除非你已经对代表性的数据量执行了实际基准并得出了性能差异实际上存在且足够重要(例如,以抵消增加的JOINing需求)。
另一方面,如果你在谈论“1:0或1”(而不是真正的1:1),这完全是一个不同的问题,值得一个不同的答案......
答案 1 :(得分:8)
职责分离和数据库表抽象。
如果我有一个用户并且我为每个用户设计了一个地址系统,但是我改变了系统,我所要做的就是在地址表中添加一条新记录而不是添加一个全新的表格迁移数据。
目前,如果你想要一个人记录并且每个人只有一个地址记录,那么你可以在一个Person表和一个Address表之间建立一对一的关系,或者你可以只拥有一个Person表那也有地址列。
将来也许您决定允许一个人拥有多个地址。您不必在1对1关系场景中更改数据库结构,只需更改处理返回给您的数据的方式。但是,在单表结构中,您必须创建一个新表并将地址数据迁移到新表,以便创建最佳实践1对多关系数据库结构。
答案 2 :(得分:4)
嗯,在纸面上,标准化形式看起来是最好的。在现实世界中,通常是一种权衡。我所知道的大多数大型系统都做了权衡,而不是试图完全正常化。
我会试着举个例子。如果您在银行应用程序中,拥有10百万的存折帐户,而通常的交易只是查询某个帐户的最新余额。您有表A只存储这些信息(帐号,帐户余额和帐户持有人姓名)。
您的帐户还有另外40个属性,例如客户地址,税号,映射到表B中其他系统的ID。
A和B有一对一的映射。
为了能够快速检索帐户余额,您可能希望对具有帐户余额和帐户持有人名称的小型表采用不同的索引策略(例如哈希索引)。
包含其他40个属性的表可能位于不同的表空间或存储中,使用不同类型的索引,例如,因为您希望按名称,帐号,分支ID等对它们进行排序。您的系统可以容忍慢检索这40个属性,同时您需要按帐号快速检索帐户余额查询。
在一个表中拥有所有43个属性似乎是自然的,并且可能“自然缓慢”并且仅仅检索单个帐户余额是不可接受的。
答案 3 :(得分:2)
使用1-1关系来模拟现实世界中的实体是有意义的。这样,当更多实体被添加到您的“世界”时,它们也只需要与它们所属的数据相关(而不是更多)。
这才是真正的关键,你的数据(每个表)应该只包含足够的数据来描述它代表的现实世界,而不是更多。应该没有多余的字段,因为就“事物”而言都是有意义的。这意味着整个系统中重复的数据更少(带来更新问题!)并且您可以独立检索单个数据(例如,不必拆分/解析字符串)。
要弄清楚如何执行此操作,您应该研究“数据库规范化”(或规范化),“正常形式”和“第一,第二和第三范式”。这描述了如何分解数据。带示例的版本总是有用的。也许试试这个tutorial。
答案 4 :(得分:1)
通常人们都在谈论1:0..1的关系并将其称为1:1。实际上,在任何情况下,典型的RDBMS都不能支持文字1:1关系。
因此,我认为在这里解决子类别是公平的,即使它在技术上需要1:0..1的关系,而不是1:1的字面概念。
当您在多个实体/表中具有完全相同的字段时,1:0..1非常有用。例如,员工和客户可能常见的联系信息字段(如地址,电话号码,电子邮件等)可以分解为纯粹用于联系信息的实体。
联系表将包含公共信息,如地址和电话号码。
因此,员工表中包含员工特定信息,如员工编号,雇用日期等。它还有一个外键引用联系人表的员工联系信息。
客户表会保存客户信息,例如电子邮件地址,雇主姓名,以及某些人口统计数据,例如性别和/或婚姻状况。客户端还可以使用联系人表的外键引用来获取联系信息。
在这样做时,每个员工都会有联系人,但不是每个联系人都会有员工。同样的概念适用于客户。
答案 5 :(得分:0)
过去项目的一些样本: