您如何确定数据库规范化的程度?

时间:2008-09-06 18:31:26

标签: language-agnostic database-design normalizing

在创建数据库结构时,要遵循哪些好的指导方针或确定数据库应该规范化的好方法?您是否应该创建一个未规范化的数据库并在项目进展时将其拆分?您是否应该将其完全标准化并根据性能需要组合表?

14 个答案:

答案 0 :(得分:16)

您希望开始设计规范化数据库,直至第3范式。在开发业务逻辑层时,您可能决定必须对其进行非规范化,但从不,从不低于第3种形式。始终保持第1和第2表格合规。您希望对代码的简单性进行非规范化,而不是为了提高性能。使用索引和存储过程:)

不能“随时正常化”的原因是每次修改数据库设计时都必须修改已经编写的代码。

有几篇好文章:

http://www.agiledata.org/essays/dataNormalization.html

答案 1 :(得分:10)

@GrizzlyGuru一位聪明的人曾告诉我“正常化直到它受伤,反正常直到它起作用”。

它还没有让我失望:)。

我不同意以非规范化的形式开始它,但是根据我的经验,它更容易调整你的应用程序来处理规范化程度较低的数据库而不是更规范化的数据库。它也可能导致其“工作”得足够好的情况“所以你永远不会让它正常化(直到它'太晚了!)

答案 2 :(得分:7)

标准化意味着消除冗余数据。换句话说,非规范化或非规范化数据库是一个数据库,其中相同的信息将在多个不同的地方重复。这意味着您必须编写更复杂的更新语句以确保在任何地方更新相同的数据,否则您将获得不一致的数据,这反过来意味着查询的输出是不可实现的。

这是一个非常大的问题,所以我会说非规范化会伤害,而不是反过来。

在某些情况下,如果您判断利益超过更新数据的额外工作和数据损坏的风险,您可能会故意决定对数据库的特定部分进行非规范化。例如,数据仓库,出于性能原因聚合数据,以及初始输入后通常不更新的数据,这样可以降低不一致的风险。

但总的来说,厌倦了对性能进行非规范化。例如,非规范化连接的性能优势通常可以通过使用物化视图(也称为索引视图)来实现,这将与查询非规范化表一样快,但是仍然保护数据的一致性。

答案 3 :(得分:3)

杰夫在他的博客上对他的哲学有一个很好的概述:Maybe normalization isn't normal。主要的是:不要过度规范化。但我认为更重要的一点是,它可能并不重要。除非您正在运行下一个Google,否则在您的应用程序增长之前,您可能不会发现太多差异。

答案 4 :(得分:3)

数据库规范我认为是一种艺术形式。

您不希望过度规范化您的数据库,因为您将拥有太多的表,这会导致您对简单对象的查询所需的时间超出预期。

我遵循的一个好的经验法则是将一遍又一遍重复的相同信息规范化。

例如,如果您要创建联系人管理应用程序,将地址(街道,城市,州,邮政等)作为自己的表格是有意义的。

但是,如果您只有2种类型的联系人,无论是商务还是个人,如果您知道自己只有2个,那么您是否需要联系人类型表?对我来说没有。

我首先要弄清楚你需要的数据类型。使用建模程序来帮助喜欢Visio。您不希望以非规范化数据库开头,因为您最终会规范化。首先将对象放在逻辑分组中,如您所见,重复将数据转换为新表。我会跟上这个过程,直到你觉得你有数据库设计。

让测试告诉您是否需要组合表格。编写良好的查询可以涵盖任何过度规范化。

答案 5 :(得分:2)

我相信从未规范化的数据库开始,随着进度的推移逐步规范化,通常最容易上手。对于规范化程度的问题,我的理念是规范化,直到开始受到伤害。这可能听起来有点轻率,但它通常是一个很好的方法来衡量它的走多远。

答案 6 :(得分:2)

拥有标准化数据库将为您提供最大的灵活性和最简单的维护。我总是从一个规范化的数据库开始,然后仅在存在需要解决的现实生活问题时才进行非规范化。

我认为这类似于代码性能,即编写可维护的,灵活的代码,并在知道存在性能问题时对性能做出妥协。

答案 7 :(得分:2)

原始海报从未描述数据库将在何种情况下使用。如果它将成为任何类型的数据仓库项目,在某些时候你需要多维数据集(OLAP)处理数据用于某些前端,那么从明星模式(事实表+维度)开始而不是研究它会更明智正常化。在这种情况下,金博尔的书籍会有很大的帮助。

答案 8 :(得分:1)

我同意通常最好先使用规范化的数据库,然后使用非规范化来解决非常具体的问题,但我可能会从Boyce-Codd Normal Form而不是第3范式开始。

答案 9 :(得分:1)

事实是“这取决于”。这取决于很多因素,包括:

  • 代码(手动编码或工具驱动(如ETL包))
  • 主要应用程序(事务处理,数据仓库,报告)
  • 数据库类型(MySQL,DB / 2,Oracle,Netezza等)
  • 数据库架构(Tablular,Columnar)
  • DBA质量(主动,被动,无效)
  • 预期的数据质量(您希望在应用程序级别或数据库级别强制执行数据质量吗?)

答案 10 :(得分:1)

我同意你应尽可能正常化,只有在表现绝对必要的情况下才能反规范化。通过物化视图或缓存方案,这通常是不必要的。

要记住的是,通过规范化模型,您可以为数据库提供有关如何约束数据的更多信息,以便您可以消除在不完全规范化的模型中可能发生的更新异常的风险。

如果你反规范,那么你需要接受这样一个事实:你可能会得到更新的异常,或者你需要在应用程序代码中自己实现约束验证。这消除了使用DBMS的许多好处,它允许您以声明方式定义这些约束。

因此,假设代码质量相同,非规范化实际上可能无法为您提供更好的性能。

另外需要提及的是,硬件现在很便宜,因此在解决问题时投入额外的处理能力通常比接受清理损坏数据的潜在成本更具成本效益。

答案 11 :(得分:-1)

通常,如果你的其他软件会让你正常化,你就会完成。

例如,在使用对象关系映射技术时,您将拥有丰富的语义集,用于各种多对一和多对多关系。在引擎盖下,将提供有效2个主键的连接表。虽然相对罕见,但真正的规范化通常会为您提供3个或更多主键的关系。在这种情况下,我更喜欢坚持使用O / R并滚动我自己的代码以避免各种数据库异常。

答案 12 :(得分:-1)

尝试使用常识。

也有人说 - 我必须同意他们 - 如果你发现自己在大多数查询中加入了6个(神奇数字)表 - 不包括与报告相关的表 - 那么你可能会考虑非正规化一点。

答案 13 :(得分:-1)

不要忘记The mother of all database normalization debates on Coding Horror(在高可伸缩性博客上总结)。