数据库设计问题:您何时决定使用1对1关系表?
我看到的其中一个地方是,例如,当你有一个User和UserProfile表时,人们会拆分它们,而不是把所有列都放在User表中。
从技术上讲,您可以将所有列放在一个表中,因为它们的关系是1对1。
我知道有人说对于UserProfile表,随着时间的推移,您需要更改表以添加更多列,但我真的不认为这是拆分表的强烈理由。
所以,如果我要设计一个User表和UserProfile表,我可以在一个表中做到这一点吗?
答案 0 :(得分:16)
我唯一一次使用1对1的关系就是当我希望它多态地属于多个对象时。
就像地址一样。用户有一个地址,企业有一个地址,有特色的餐馆有一个地址。所有实例都在同一个表中处理,并具有相同的代码来管理它。可以把它想象成重构你的数据模型,这样你就可以在其他地方重复使用它。
答案 1 :(得分:10)
考虑如何设计业务对象。您是否要拥有一个包含50个属性的User对象,或者您将拥有一个具有一些详细属性的User对象,然后是一个包含配置文件的其他数据的Profile对象?
当表中的数据相关时,您应该使用1对1,但不是出于相同的目的。 (可能措辞更好)
此外,它可以使事情更容易找到。我讨厌的事情并不多,只需要查看75列的表格。
答案 2 :(得分:9)
经典的原因是避免可以为空的列。
在列中包含NULL值会使编写清晰(可维护)的SQL变得更加困难。 @ Ovid根据here的工作撰写了关于此Chris Date的文章。
答案 3 :(得分:6)
仅当用户表中的所有记录数不需要UserProfile表中的字段时。例如,如果您有3,000,000个用户,但只有3,000个用户具有UserProfiles,则拆分它们可能是有意义的(以避免一大堆空列。)
虽然现在是数据库速度提升和存储成本低廉的日子,但由于这个原因,拆分它们并没有什么区别......
答案 4 :(得分:3)
这是今天在这个帖子中出现的另一个问题的直接复制和粘贴,但它在这里也很有用。 Is there ever a time where using a database 1:1 relationship makes sense?
我主要使用它们有几个原因。一个是数据变化率的重大变化。我的一些表可能有审计跟踪,我跟踪以前版本的记录,如果我只关心跟踪以前版本的10列中的5列,将这5列拆分到一个单独的表上,其上有一个审计跟踪机制更有效。此外,我可能有只写的记录(比如会计应用)。您无法更改美元金额或其所用的帐户,如果您犯了错误,那么您需要创建相应的记录来编写调整不正确的记录,然后创建更正条目。我在表上有约束,强制它们无法更新或删除,但我可能有一些可塑性的对象属性,这些属性保存在一个单独的表中,没有修改限制。我这样做的另一次是医疗记录应用。存在与访问相关的数据,一旦签名就无法更改,以及与签名相关的其他数据可以在签收后更改。在这种情况下,我将拆分数据并在锁定表上放置一个触发器,在签名时拒绝对锁定表的更新,但允许更新医生未注销的数据。
另一张海报评论1:1没有被标准化,在某些情况下,我会不同意,尤其是亚型。假设我有一个员工表,主键是他们的SSN(这是一个例子,让我们保存关于这是否是另一个线程的好键的辩论)。员工可以是不同类型的,例如临时的或永久的,如果他们是永久性的,他们有更多的字段需要填写,例如办公室电话号码,如果类型='永久',则该字段应该不为空。在第三个普通形式的数据库中,该列应仅依赖于密钥,即雇员,但实际上它取决于员工和类型,因此1:1关系是完全正常的,在这种情况下是可取的。它还可以防止过度稀疏的表,如果我有10列通常填充,但只有20列用于某些类型。
答案 5 :(得分:2)
我最近看到过一个表,其中包含大部分数据的表,然后是另一个包含大量可选数据的表。
第二个表有三分之一的行,但列数是其中的三倍。
这是在几年前完成的,避免了列中的大量空值 - 即空格。
但是,如果你现在这样做,我会不想打扰。住在空旷的地方。它可能导致应用程序开发的麻烦根本不值得,而且空间比开发时间便宜。
答案 6 :(得分:1)
这已经得到了很好的解决,但我只是添加一个快速说明,以澄清一些对我来说不明显的事情,并且没有明确说明。 1对1的关系并不意味着表A中的每条记录在表B中都有1条相应的记录。相反,这意味着对于表A中的每条记录,表B中将有0或1条相应的记录。
Shane D.和其他人描述了利用这一事实的情景。
答案 7 :(得分:0)
我认为Shane D有一个非常有效的理由。因为即使我遇到大约有40列的表的相同情况,这些列的数据也是通过csvs上传的,仅用于报告目的,还有一组列来处理这些文件,这些列经常更新。
所以如果我们维护一个表作为解决方案。我们在该表上执行频繁更新,并且仅更新5列50。 我觉得每次更新都会扰乱行分配,并且很可能存在行链接,所以为了避免行链接,我采用了基于DML活动分离数据的方法。
让我知道是否有更好的解决方案