Database design 什么时候是打破规范化规则的好时机?

Database design 什么时候是打破规范化规则的好时机?,database-design,database-normalization,Database Design,Database Normalization,请给出您对不正常化是个好主意的情况的看法。我刚刚看到一位architech和DBA之间进行了一些激烈的讨论,他们坚持认为数据库太规范化了。性能查询可能性:如果数据库太规范化,这可能会导致查询中出现大量连接,并限制您搜索特定属性的可能性。 在做DB设计时,您应该考虑使用它的方式,通过访问路径分析。 更详细地说,对频繁更新的数据进行规范化,并对大部分读取的数据进行反规范化,这是一条经验法则 标准化消除了冗余,但如果它在某种程度上降低了性能(由于所有必需的连接),那么硬件的成本是不够的,是时候为了性能

请给出您对不正常化是个好主意的情况的看法。我刚刚看到一位architech和DBA之间进行了一些激烈的讨论,他们坚持认为数据库太规范化了。

性能查询可能性:如果数据库太规范化,这可能会导致查询中出现大量连接,并限制您搜索特定属性的可能性。 在做DB设计时,您应该考虑使用它的方式,通过访问路径分析。
更详细地说,对频繁更新的数据进行规范化,并对大部分读取的数据进行反规范化,这是一条经验法则

标准化消除了冗余,但如果它在某种程度上降低了性能(由于所有必需的连接),那么硬件的成本是不够的,是时候为了性能而允许冗余了。这是我的经验法则。回答时间长的情况下也是如此。

出于性能原因,数据仓库通常使用非规范化方法。Per:

一个标准的数据库设计指南是,设计者应该创建一个完全规范化的设计;出于性能原因,可随后执行选择性非规范化。然而,一些建模规程,如数据仓库设计的维度建模方法,明确推荐非规范化设计,即在很大程度上不符合3NF的设计


你必须找到最合适的地方。。。由于过于规范化,您最终会得到许多“膨胀”的抽象结构,这些结构只包含1或2列数据,对于大多数查询,您最终会连接5个表

由于标准化不足,您最终会在许多不同的地方拥有大量数据。由于缓存大小等原因,这可能会导致数据库速度变慢。另外,现在当您需要更新某些内容时,您有4个不同的表要更新,而不是1个表,而且甚至不需要让我开始确保不同位置的所有数据都匹配

基本上,选择你的毒药,观察你的DB将如何使用,并保持理智。所有的规则都是要被打破的,如果你在两个地方有一段数据,这些数据通常都被访问,我会说这没关系。在连接(可能超过2个)表的过程中,这是一个非常重要的环节。。但也不要对数据库的空间或速度进行微观优化

当您过早地进行优化时 有些正常化是为了允许未来的增长,而您可能不需要它

例如,假设您有一个
person
表。您可以将
生日
列为一列,因为每个人只有一个生日

如果严格进行规范化,则不会将
phone\u number
cell\u number
fax\u number
作为
person
中的列,而是可能有一个
phonenumber
表,其中每行都有一个号码、类型和person\u id关系。这比只在
person
表中粘贴新列要好,因为

  • 许多人不会拥有所有这些,留下许多空白,并且
  • 如果某人有3个手机号码,你可能会添加一些尴尬的列,比如
    cell\u number\u 2
  • 关注点#1是有效的,但关注点#2可能是“你不需要它”的一个例子。说“我们只允许一个手机号码,就是这样”是有效的。在这种情况下,你可能不需要麻烦为电话号码制作单独的表格

    这是一种权衡。通过不创建单独的表,您没有严格地规范化,并且可能会有很多空空间。但是你也有更少的连接要做,这只是更少的工作

    像许多好的实践一样,规范化本身也可以成为目的——一个你私下给自己的金徽章,因为你做得对。那很好但是,我们很高兴认识到,为了保持事情的简单,有时规则会被扭曲。


    最后一件事:您必须权衡这样一个事实:一旦代码启动并运行,更改db模式就很糟糕。所以说“我们不需要它”是可以的,但在提交之前请尽量确定。

    关于存储与性能的几个很好的答案,但除此之外,我还想补充一点,对我来说,应该考虑去规范化的另一个指示是,您需要使用自连接进行查询

    从概念上讲,自联接表当然没有什么错,但经验表明,对于没有经验的程序员来说,它是一个更难掌握的概念,因此往往会产生错误。如果您能够设计出这些功能的需求,您很可能会简化未来的维护路径


    这当然是一个判断的问题,也是一个指示,而不是一个规则。

    规则是正常化,直到它受伤,然后去正常化,直到它起作用。(谁说的?)

    一般来说,当我有很多父子关系时,我经常进行非规范化,我知道我经常需要连接到五个或六个大表以获取一段数据(例如,客户机id),并且在大多数情况下不需要中间表中的任何信息。如果可能的话,我会尝试去规范化那些不会经常改变的东西(比如id字段)。但是,任何时候你去规范化,你都必须编写触发器或其他进程(但如果不能通过PK/FK关系和级联更新来处理,则通常会触发),以确保数据保持同步。如果无法在数据库级别执行此操作,则会出现数据完整性问题,数据将变得无用。不要认为您可以通过应用程序代码来维护非规范化。这会导致灾难,因为数据库经常从应用程序以外的地方更新

    正确地去规范化可以减缓插入、更新和删除的速度,特别是当您需要执行大型bat时