关于不可知的语言:如何确定规范化数据库的距离?

关于不可知的语言:如何确定规范化数据库的距离?

How do you determine how far to normalize a database?

创建数据库结构时,应遵循哪些良好准则或确定应规范化数据库多远的良好方法? 您是否应该创建一个非标准化的数据库,并在项目进行时将其拆分? 您是否应该创建完全标准化的表,并根据性能组合表?


您想开始设计一个标准化的数据库,最多可使用第3个标准格式。在开发业务逻辑层时,您可能会决定必须稍微规范化,但是永远不要低于3阶。始终保持第一张和第二张表格的合规性。您想对代码进行标准化以简化代码,而不是为了提高性能。为此使用索引和存储过程:)

之所以不能"随便进行标准化",是因为每次修改数据库设计时,您都必须修改已经编写的最多的代码。

有几篇好文章:

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


@GrizzlyGuru一个聪明的人曾经告诉我"归一化直到痛苦,反归一化直到起作用"。

它还没有使我失望:)

我不同意以非规范化的形式开始它,但是,根据我的经验,与规范化程度更高的数据库相比,使应用程序适应规范化程度较低的数据库更容易。它还可能会导致其"足够好"地工作,以至于您永远无法规范化它(直到为时已晚!)。


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

这是一个非常大的问题,所以我想说非正规化很痛苦,而不是相反。

在某些情况下,如果您认为对数据库的特定部分进行规范化,则认为您的好处胜于更新数据的额外工作和数据损坏的风险。例如,在数据仓库中,出于性能原因汇总数据,并且在初次输入之后通常不更新数据,从而减少了不一致的风险。

但总的来说,要为性能标准化而烦恼。例如,通常可以通过使用实例化视图(也称为索引视图)来实现非规范化连接的性能优势,该视图将与查询非规范化表一样快,但仍可保护数据的一致性。


Jeff在自己的博客上对他的哲学作了很好的概述:也许规范化是不正常的。最主要的是:不要过度标准化。但我认为,要带走的更大一点是,这可能关系不大。除非您运行下一个Google,否则除非您的应用程序增长,否则您可能不会注意到很大的不同。


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

您不希望对数据库进行过度规范化,因为您将有太多的表,这将导致即使是简单对象的查询也要花比他们更长的时间。

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

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

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

我首先要弄清楚您需要的数据类型。使用建模程序可以像Visio一样提供帮助。您不想从非规范化数据库开始,因为您最终将进行规范化。首先,将对象放在逻辑分组中,您会看到重复的数据将这些数据放入新表中。在您觉得自己已经设计好数据库之前,我会一直保持这一过程。

让测试告诉您是否需要合并表。编写良好的查询可以涵盖所有过度规范化的问题。


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


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

我认为这与代码性能类似,即编写可维护的,灵活的代码,并在知道性能问题时牺牲性能。


我认为,从未规范化的数据库开始,然后随着进度的发展而逐渐走向规范化通常是最容易上手的。对于标准化多远的问题,我的理念是标准化直到开始受到伤害。听起来有些flip昧,但这通常是衡量距离的好方法。


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

要记住的事情是,通过对模型进行规范化,您将为数据库提供有关如何约束数据的更多信息,从而消除了在不完全规范化的模型中发生更新异常的风险。

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

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

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


事实是,"取决于"。它取决于许多因素,包括:

  • 代码(手动编码或工具驱动(如ETL软件包))

  • 主应用程序(事务处理,数据仓库,报告)

  • 数据库类型(MySQL,DB / 2,Oracle,Netezza等)

  • 数据库架构(表式,列式)

  • DBA质量(主动,被动,非主动)

  • 预期的数据质量(您要在应用程序级别还是数据库级别上强制执行数据质量?)


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


只是尝试使用常识。

也有人说-我必须同意他们的看法-如果您发现自己在大多数查询中将6个表(魔术数字)连接在一起(不包括报告相关的表),则可能需要考虑对非规范化一点。


通常,只要您对其他软件允许的范围进行归一化,就可以解决。

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


推荐阅读