在数据库设计中,什么时候需要使用一对一关系?

7

在数据库设计中,何时需要使用1对1关系?我认为,如果两个表之间存在1对1关系,则它们可以合并为一个表。这是正确的吗?

5个回答

10
  1. 为了减少I/O和缓存需求,对于大表进行垂直分割 -- 将经常查询的列和不经常查询的列分开。

  2. 在生产系统中添加列时,如果“alter table”太昂贵,可以采用其他方法。

  3. 超类型/子类型模式。

  4. 通过垂直分割来受益于表(连接)消除 -- 前提是优化器支持它(同样是为了减少I/O和缓存)。

  5. 锚定建模 -- 类似于4,但达到了第六范式


1

有时候在使用表锁方面是很有用的。当您向数据库中添加一个列时,整个表将被锁定,直到完全重写完毕。当您的数据库有10万行时,这几乎没有任何影响。但是如果您有1亿行或10亿行,那就完全是另一回事了...

如果您正在使用MVCC并且某些列经常被覆盖,则将其放置在单独的表中偶尔是有意义的,这样有助于避免占用过多空间的死行。可以说,自动清理最终会进行,但出于节省硬盘工作的考虑,最好在单独的表中清除一些int字段,而不是整个包含文本、varchar(n)和其他未知字段的行。

一个最后的原因是ORM中滥用select *。例如,如果您存储图像或博客文章/文章,则将blob/text字段存储在单独的表中可能是有意义的。因为每次出于某种原因加载它时,您的ORM都会加载整个行。当您只需要图像或帖子的URL时,您最不想做的就是从数据库中拉取整个二进制/文本;但是您的ORM会这样做...

0

一般而言是的。

唯一的例外可能是您想要将特定列的权限分配给不同的子集。

还要考虑到只有在两边都需要时才成立。


0

一个原因是将经常访问的数据放在一个表中,将极少访问的数据放在另一个表中。这样可以运行得更快,节省一些内存。

但除非我被强烈要求,否则我不会这样做。


0
一对一是含糊不清的,因为“一”指的是基数,并没有明确说明它是否是关系中的强制参与(即一个且仅有一个)还是可选参与(即零或一个)。

enter image description here

如果是“一对一”,你确实可以在实践中决定将两个设计实体合并到一个表中来实现。这种方法在数据表示的角度上是等效的,有时可以简化实现过程。技术上的优缺点在其他答案中已经很好地描述了。然而,它与初始设计并不完全等同。
  • 两个实体间的关注点分离已经被破坏。这可能会有一些缺点,例如如果每个实体背后的概念可能演变不同(例如不同的应用程序负责其维护)或具有不同的要求(例如授权)。
  • 从理论上讲,实体应该定义自己独立的身份,在数据库级别实现主键。合并将导致两个不同的潜在主键,其中一个功能上依赖于另一个:考虑到规范化原则,这是不推荐的。为两个实体使用相同的主键可以轻松解决此问题,但意味着实体不再具有独立的身份。这是一个微妙的语义差异,如果优点超过不便,则可以忽略它。
  • enter image description here
    enter image description here

    如果涉及到“零或一”的任何组合,那么你应该避免将这两个实体合并到一个表中:
    从技术上讲,你可以这样做,但这将需要可选实体的属性可为空。在上面的第二个例子中,这意味着除了主键之外的所有列都可以为空,这将不再能够强制执行一致性,例如如果某些列是必填的。
    将它们分开可能会增加一些额外的开销,因为你会有一个额外的表,但在数据库层面准确地表示了所有可能的情况。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接