一对一关系是否正常化?


12

考虑我们有大量的统计数据记录;例如20-30 INT列。最好将整个集合都保留在一个表中,因为它们都属于一条记录,还是创建另一个具有一对一关系的表。

前者的优点是避免JOIN并可以快速访问相应记录的所有统计数据。

后者的优点是使色谱柱保持整洁。第一列是读密集型的,第二列是写密集型的。当然,我认为它对性能没有显着影响,因为我将InnoDB与行级阻塞一起使用。

总的来说,我想知道为一条记录分离不同的数据集是否有用?


2
“规范化”是指第一范式(1NF),是关系模型的基本要求。“完全标准化”是指5NF或更高。您提议的“一对一关系”表具有较高的正常形式(甚至可能是6NF),因为它已经分解了!您现有的表格可以满足哪些范式?
某天,2012年

@onedaywhen与其他许多人一样,我没有一步一步地遵循规范化,因为有时取消规范化也会有所帮助。一般而言,整个数据库的标准化级别应在3NF-5NF之间(我总是对4NF有问题!)
Googlebot

Answers:


19

如果符合规范化规则,则可以将1:1关系规范化(根据定义!)-换句话说,关于1:1关系没有什么让他们无法服从常规形式。

为了回答有关1:1关系的实用性的问题,有时这是一个非常有用的构造,例如,当您具有带有不同谓词(列)的子类型时。

使用1:1关系的原因取决于您的观点。DBA倾向于将一切视为性能决定。数据建模人员和程序员倾向于将这些决策视为面向设计或面向模型的决策。实际上,这些观点之间有很多重叠之处。这取决于您的观点和优先事项。以下是1:1关系的动机示例:

  • 您有一些很宽的列子集,出于性能原因,您想在存储中将它们物理隔离。

  • 您有一些不经常读取或更新的列子集,出于性能原因,您要将它们与经常使用的列分开。

  • 您通常有一些可选的列,但是当您知道记录属于某种类型时,它们是必选的。

  • 您有一些列在逻辑上属于一个子类型,并且您希望对其进行建模以使其与代码的对象模型完全匹配。

  • 您有一些只能应用于实体超类型的某些子类型的列,并且您希望您的架构对其他子类型强制缺少此数据。

  • 您有一些属于实体的列,但需要使用更具限制性的访问规则(例如,雇员表上的薪水)来保护这些特定的列。

因此,您可以看到,有时驱动程序是性能,有时是模型纯度,或者只是想充分利用声明性架构规则。


You have some subset of columns that are very wide and you want to segregate them physically in your storage for performance reasons.隔离它们如何提高性能(假设每次主表都始终访问列)?
吉利2014年

@Gili-如果您的假设是正确的,那么这种情况将不适用。分隔大的和不常需要的列可以使更多的行适合页面,从而可以更快地检索常用的列。显然,由于必须进行联接,因此读取分隔的列以及常用的列会比较
乔尔·布朗

由于设计原因(关注点分离,代码重用增加),我想沿着常用列进行隔离。有没有人发布过这样的加入费用的估算?是微不足道的还是我应该长期担心的事情?
吉利2014年

@Gili-re:加入的代价:除了“取决于”之外,没有正确的答案。加入费用受许多因素影响。它们是否可以忽略不计甚至更难回答,因为这最终是主观的。回答您问题的最好方法是模拟一些测试数据并进行容量测试。两种方法都尝试一下,看看是否可以使用实际数据量(无论对您的应用程序意味着什么)来区分出差异。
2014年

我做到了,并且得到了令人惊讶的结果:dba.stackexchange.com/q/74693/4719 我承认这不是规范化的典型示例,但是它并没有说明JOIN(仍然)非常昂贵。
吉利2014年

4

使用一对一映射将大表分成两部分的主要原因是出于性能方面的考虑,例如:

a)该表在经常访问的表中具有二进制/斑点/ blob数据,因此,由于大列的处理方式不同,因此会降低性能。

b)该表有许多列,不同的查询可以访问这些列,因此性能会降低,因此您需要将相关列移到单独的表中以提高访问性能

但是,具有许多整数列并不能证明将表拆分为单独的表并不得不查询它们的额外努力。


非常好的一点来澄清这个问题!
Googlebot 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.