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

有帮助吗?

解决方案

您想要开始设计一个符合第三范式的规范化数据库。当您开发业务逻辑层时,您可能决定必须稍微反规范化,但是 从来没有,从来没有 低于第三种形式。始终保持第一和第二表格合规。您想要非规范化是为了代码的简单性,而不是为了性能。为此使用索引和存储过程:)

不“随行标准化”的原因是,每次修改数据库设计时,您都必须修改已经编写的大部分代码。

有几篇不错的文章:

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

其他提示

@GrizzlyGuru 一位智者曾经告诉我“正常化直到它受伤,非正常化直到有效”。

它还没有让我失望:)

我不同意以非标准化形式开始,但是,根据我的经验,调整应用程序以处理标准化程度较低的数据库比标准化程度更高的数据库更容易。它还可能导致其工作“足够好”的情况,因此您永远无法将其标准化(直到为时已晚!)

标准化意味着消除冗余数据。换句话说,非规范化或非规范化数据库是相同信息将在多个不同位置重复的数据库。这意味着您必须编写更复杂的更新语句以确保在各处更新相同的数据,否则您会得到不一致的数据,这又意味着查询的输出不真实。

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

在某些情况下,如果您认为好处超过了更新数据的额外工作和数据损坏的风险,您可能会故意决定对数据库的特定部分进行非规范化。例如,对于数据仓库,出于性能原因而聚合数据,并且数据在初始输入后通常不更新,从而降低了不一致的风险。

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

Jeff 在他的博客上对他的哲学做了很好的概述: 也许标准化并不正常. 。主要的是:不要过度标准化。但我认为更重要的一点是,这可能并不重要。除非您运行的是下一个 Google,否则在您的应用程序增长之前您可能不会注意到太大的差异。

我觉得数据库规范化是一种艺术形式。

您不想过度规范化数据库,因为您将拥有太多表,这将导致您对简单对象的查询花费比应有的时间更长的时间。

我遵循的一个好的经验法则是对一遍又一遍重复的相同信息进行标准化。

例如,如果您正在创建联系人管理应用程序,那么拥有地址(街道、城市、州、邮政编码等)是有意义的。。)作为它自己的表。

但是,如果您只有 2 种类型的联系人(企业或个人),并且您知道只有 2 种类型,您是否需要联系人类型表?对我来说没有。

我首先要弄清楚您需要的数据类型。使用 Visio 等建模程序来提供帮助。您不想从非标准化数据库开始,因为您最终会标准化。首先将对象放入逻辑分组中,当您看到重复的数据时,将该数据放入新表中。我会跟上这个过程,直到你觉得你已经设计好了数据库。

让测试告诉您是否需要合并表。编写良好的查询可以涵盖任何过度标准化的情况。

我相信从非规范化数据库开始,随着进展逐渐转向规范化通常是最容易上手的。对于正常化到什么程度的问题,我的哲学是正常化,直到开始受到伤害。这听起来可能有点轻率,但它通常是衡量要走多远的好方法。

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

我认为这与代码性能类似,即编写可维护、灵活的代码,并在以下情况下对性能做出妥协: 知道 存在性能问题。

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

我同意通常最好从规范化数据库开始,然后进行非规范化以解决非常具体的问题,但我可能会从 博伊斯-科德范式 而不是第三范式。

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

  • 代码(手动编码或工具驱动(如 ETL 包))
  • 主要应用程序(事务处理、数据仓库、报告)
  • 数据库类型(MySQL、DB/2、Oracle、Netezza 等)
  • 数据库架构(表格、列式)
  • DBA 质量(主动、被动、不主动)
  • 预期数据质量(您想在应用程序级别还是数据库级别强制执行数据质量?)

我同意您应该尽可能地标准化,并且仅在性能绝对必要时才进行非标准化。对于物化视图或缓存方案,这通常是不必要的。

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

如果您进行非规范化,那么您要么需要接受可能会出现更新异常的事实,要么需要自己在应用程序代码中实现约束验证。这剥夺了使用 DBMS 的很多好处,DBMS 允许您以声明方式定义这些约束。

因此,假设代码质量相同,非规范化实际上可能不会给您带来更好的性能。

另一件值得一提的是,如今硬件很便宜,因此投入额外的处理能力来解决问题通常比接受清理损坏数据的潜在成本更具成本效益。

通常,如果您在其他软件允许的范围内进行标准化,那么您就可以完成。

例如,当使用对象关系映射技术时,您将拥有一组丰富的用于各种多对一和多对多关系的语义。在底层,它将提供具有有效 2 个主键的连接表。虽然相对较少,但真正的规范化通常会为您提供与 3 个或更多主键的关系。在这种情况下,我更愿意坚持使用 O/R 并编写自己的代码以避免各种数据库异常。

只需尝试使用常识即可。

还有一些人说 - 我必须同意他们的观点 - 如果您发现自己在大多数查询中将 6 个(神奇的数字)表连接在一起 - 不包括报告相关的表 - 那么您可能会考虑稍微反规范化。

别忘了 关于编码恐怖的所有数据库规范化争论之母 (在高可扩展性博客上进行了总结)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top