22

一个数据库设计问题:您何时决定使用 1 对 1 关系表?

我看到的其中一个地方是,例如,当您有一个 User 和 UserProfile 表时,人们将它们拆分,而不是将所有列都放在 User 表中。

从技术上讲,您可以将所有列放在一个表中,因为它们的关系是一对一的。

我知道有人说对于 UserProfile 表,随着时间的推移,您需要更改表以添加更多列,但我真的不认为这是拆分表的充分理由。

那么,如果我要设计一个 User 表和 UserProfile 表,对我来说只在一个表中做会更好吗?

4

8 回答 8

17

我唯一一次使用 1 对 1 关系是当我希望它多态地属于多个对象时。

比如地址。用户有一个地址,企业有一个地址,特色餐厅有一个地址。所有实例都在同一个表中处理,并且具有管理它的相同代码。把它想象成重构你的数据模型,这样你就可以在其他地方重用它。

于 2009-02-05T17:52:39.693 回答
10

考虑如何设计业务对象。您是要拥有一个带有 50 个属性的用户对象,还是要拥有一个带有一些详细属性的用户对象,然后是一个包含配置文件其他数据的配置文件对象?

当表中的数据相关但不是出于相同目的时,您应该使用 1 对 1。(可能措辞更好)

它也可以使事情更容易找到。没有什么比浏览一个有 75 列的表格更让我讨厌的事情了。

于 2009-02-05T17:53:04.013 回答
9

经典的原因是避免可为空的列。

列中有 NULL 值会使编写清晰(可维护)的 SQL 变得更加困难。@Ovid在这里写了这篇文章借鉴了Chris Date的作品。

于 2009-02-05T18:05:13.880 回答
6

仅当 UserProfile 表中的字段不需要用户表中的所有记录数时。例如,如果您有 3,000,000 个用户,但其中只有 3,000 个具有 UserProfile,则拆分它们可能是有意义的(以避免一大堆空列。)

尽管现在随着数据库速度的提高和存储成本的降低,但出于这个原因将它们拆分并没有太大的区别......

于 2009-02-05T17:52:53.000 回答
3

我最近看到一个表,其中包含大部分数据,然后是另一个包含大量可选数据的表。

第二个表有三分之一的行,但列的数量是原来的三倍。

这是几年前完成的,避免了列中的大量空值 - 即空白空间。

但是,如果您现在这样做,我很想不打扰。与空旷的空间一起生活。它给应用程序开发带来的麻烦根本不值得,而且空间比开发时间便宜。

于 2009-02-05T17:53:45.930 回答
3

这是今天在这个线程中弹出的另一个问题的直接复制和粘贴,但在这里感觉也很有用。 是否曾经有过使用数据库 1:1 关系有意义的时候?

我使用它们主要有几个原因。一是数据变化率的显着变化。我的一些表可能有审计跟踪,我可以在其中跟踪以前版本的记录,如果我只关心跟踪 10 列中的 5 列的以前版本,将这 5 列拆分到一个单独的表中,上面有审计跟踪机制会更有效。另外,我可能有只写的记录(比如会计应用程序)。您不能更改美元金额或它们所用于的帐户,如果您犯了错误,则需要进行相应的记录以注销不正确的记录,然后创建更正条目。我对表有限制,强制执行它们无法更新或删除的事实,但我可能对该对象有几个可延展的属性,这些都保存在一个单独的表中,没有修改的限制。我这样做的另一次是在医疗记录应用程序中。有与访问相关的数据一旦签署就无法更改,而与访问相关的其他数据可以在签署后更改。在这种情况下,我将拆分数据并在锁定表上放置一个触发器,在注销时拒绝对锁定表的更新,但允许对医生未签署的数据进行更新。

另一位发帖人评论说 1:1 没有被规范化,在某些情况下,我不同意这一点,尤其是子类型化。假设我有一个员工表,主键是他们的 SSN(这是一个例子,让我们把关于这是否是另一个线程的好键的争论)。员工可以是不同的类型,比如临时的或永久的,如果他们是永久的,他们有更多的字段需要填写,比如办公室电话号码,只有在 type = 'Permanent' 时才应该不为空。在第 3 范式数据库中,列应该仅取决于键,即员工,但它实际上取决于员工和类型,因此 1:1 关系是完全正常的,并且在这种情况下是可取的。它还可以防止过于稀疏的表,如果我有 10 个通常填充的列,

于 2009-02-05T19:32:32.957 回答
2

这已经很好地解决了,但我只是添加一个快速说明来澄清一些对我来说并不明显并且没有明确说明的事情。1 对 1 的关系并不意味着表 A 中的每条记录在表 B 中都有 1 条对应的记录,而是意味着对于表 A 中的每条记录在表 B 中都会有 0 或 1 条对应的记录。

Shane D. 和其他人描述了利用这一事实的场景。

于 2013-05-03T08:18:09.277 回答
0

我认为 Shane D 有一个非常合理的理由。甚至我也遇到了大约 40 列的表的相同情况,这些列的数据通过 csvs 上传,仅用于报告目的和一组列来处理这些文件,这些文件经常更新。

因此,如果我们维护一张表作为解决方案。我们对该表执行频繁更新,并且将只更新 50 列中的 5 列。我觉得每次更新都会干扰行分配,并且很有可能发生行链接,所以为了避免行链接,我采用了基于数据分离的方法关于 DML 活动。

让我知道是否有更好的解决方案

于 2009-04-09T07:43:10.660 回答