我看到很多设计都认为标准化不是决策阶段的首要考虑。
在许多情况下,这些设计包括超过30列,主要方法是“将所有内容放置在同一位置”
根据我记得,归一化是最重要的第一件事,那么为什么有时它这么容易掉下来?
编辑:
好的建筑师和专家选择非规范化的设计,而没有经验的开发人员选择相反的设计,这是真的吗?反对着手规范化设计的观点是什么?
我看到很多设计都认为标准化不是决策阶段的首要考虑。
在许多情况下,这些设计包括超过30列,主要方法是“将所有内容放置在同一位置”
根据我记得,归一化是最重要的第一件事,那么为什么有时它这么容易掉下来?
编辑:
好的建筑师和专家选择非规范化的设计,而没有经验的开发人员选择相反的设计,这是真的吗?反对着手规范化设计的观点是什么?
Answers:
这个问与答线程有趣的是,实际上有3个问题。每个人都回答了一个不同的答案,几乎没有人回答了第一个:
机敏的读者会注意到,这是完全不同的问题,我将尝试分别回答每个问题,同时避免过多的细节。“太多”,我的意思是,我认为这不是就支持或反对规范化的各种论点进行广泛辩论的适当背景。我只是要解释这些论点是什么,也许列出一些警告,并在提出更具体的问题时保留其哲学。
另外,在这个答案中,我假设“规范化”意味着“ BCNF,3NF或至少2NF”,因为这是设计人员通常旨在实现的规范化水平。很少见到4NF或5NF设计。尽管它们当然不是不可能的目标,但它们关注关系的语义,而不仅仅是关系的表示,这需要大量有关领域的知识。
因此,向前和向上:
答案可能是“因为他们不应该这样”,但是立即做出这样的假设是非常可怜的侦探工作。如果我们始终假设一切都应该如此,那么作为一个社会,我们将不会取得很大进步。
首先不对数据库进行规范化的真正原因更加复杂。以下是我遇到的前5名:
设计它的开发人员不知道或不了解如何规范化。有力的证据表明,还有许多其他错误的设计选择,例如对所有内容使用varchar列,或者将无意义的表名和列名混成细面条。我向您保证,我看到的“真实”数据库与TDWTF文章中的数据库一样糟糕。
原则上,设计它的开发人员不在乎或积极反对规范化。请注意,这里我不是在谈论故意不根据上下文分析进行标准化的情况,而是在团队或公司中或多或少了解标准化但只是出于习惯而忽略或避免标准化的情况。再次,出奇的普遍。
该软件已作为Brownfield项目完成。许多纯粹主义者不理会这种完全合法的事情,而不是不规范的技术原因。有时,您实际上并不需要从头开始设计新数据库,而必须使用现有的旧架构,而在那时进行规范化将带来太多麻烦。3NF直到1971年才发明,某些系统,尤其是财务/会计系统,其起源远不止于此!
该数据库最初是经过规范化的,但是长期以来积累的少量变更和/或分布广泛的团队引入了细微的复制形式,以及其他违反原始形式的复制形式。换句话说,规范化的丢失是偶然的,并且重构花费的时间太少。
做出了一个刻意的业务决策,不要在业务分析或数据库设计上花费任何时间,而只是“完成”。这通常是一种虚假的经济,最终会成为越来越多的技术债务形式,但有时至少是基于当时已知的信息,是一个理性的决定-例如,该数据库可能已被设计为原型,但最终被淘汰出局。由于时间限制或商业环境的变化而被提升为生产用途。
当数据库这种讨论经常出现的标准化入手。无论是性能低下,还是查询(联接)中有很多重复项,团队都正确或错误地认为,他们已对当前设计进行了尽可能多的努力。需要注意的是标准化是很重要的提高性能的最的时候,有几个选项,以消除时正常化似乎是工作对你,其中有许多是比简单地改变一个非规范化模型创伤小,风险过量加入:
创建索引视图以封装最常见的问题区域。现代的DBMS能够使它们可插入或可更新(例如SQL Server INSTEAD OF
触发器)。这对基础表/索引上的DML语句来说要付出一点代价,但是通常是您应该尝试的第一个选择,因为几乎不可能搞砸,而且几乎不需要维护。当然,并非每个查询都可以转换为索引视图- 聚合查询最麻烦。这导致我们进入下一个项目...
创建由触发器自动更新的非规范化汇总表。这些表除了归一化表外还存在,并形成一种CQRS模型。当今越来越流行的另一种CQRS模型是使用pub / sub更新查询模型,这提供了异步的好处,尽管这可能不适用于数据无法陈旧的极少数情况。
有时,索引视图是不可能的,事务速率和数据量过高而无法接受具有可接受性能的触发器,并且查询必须始终返回实时数据。这些情况很少见-我可能会猜测它们可能适用于高频交易或执法/情报数据库之类的情况-但它们可能存在。在这些情况下,您实际上别无选择,只能对原始表进行规范化。
实际上,这里有几个很好的例子:
如果数据库仅用于报告/分析。通常,这意味着存在用于OLTP 的其他标准化数据库,该数据库通过ETL或消息传递定期同步到分析数据库。
在执行规范化模型时,将需要对输入数据进行不必要的复杂分析。例如,某个系统可能需要存储从多个外部系统或数据库收集的电话号码。您可以对呼叫代码和区号进行非规范化,但是您必须考虑所有可能的格式,无效的电话号码,虚荣号码(1-800-GET-STUFF),更不用说其他区域设置了。通常,麻烦多于其应有的价值,而且电话号码通常只会被挤到一个字段中,除非您自己对区号有特定的业务需求。
当关系数据库主要位于那里时,它将为其他非关系数据库提供事务支持。例如,当主数据存储在Redis或MongoDB或任何其他数据库中时,您可能会将关系数据库用作消息队列,或者跟踪事务或传奇的状态。换句话说,该数据是“控制数据”。标准化实际上不是业务数据的数据通常没有意义。
共享物理数据库的面向服务的体系结构。这有点奇怪,但是在真正的SOA中,由于不允许服务直接查询彼此的数据,因此有时需要物理复制数据。如果它们恰好共享同一物理数据库,则数据似乎将不被规范化-但是通常,除非存在其他缓解因素之一,否则每个服务所拥有的数据仍将被规范化。例如,帐单服务可能拥有帐单实体,但是会计服务需要接收并存储帐单日期和金额,才能将其包括在该年的收入中。
我确定还有更多未列出的原因;从本质上讲,我要讲的是它们很具体,在实践中会很明显。OLAP数据库应该使用星型模式,SOA 应该具有某些重复性,等等。一般而言,架构模型优先于数据模型。
并回答最后一个问题:
好的建筑师和专家选择非规范化的设计,而没有经验的开发人员选择相反的设计,这是真的吗?反对以规范化开始设计的观点是什么?
不,那是完整而完全的BS 专家们总是选择标准化设计也是 BS 。专家不只是遵循口头禅。他们研究,分析,讨论,澄清和迭代,然后选择适合其特定情况的最合适的方法。
3NF或BCNF数据库通常是一个很好的分析起点,因为它已经在世界各地成千上万的项目中进行了尝试并证明是成功的,但是C同样如此。这并不意味着我们会在每个数据库中自动使用C新项目。实际情况可能需要对模型进行某些修改,或者完全使用其他模型。在这种情况下,您才知道。
问题和某些答案中内置的假设是标准化是好的数据库设计的同义词。实际上通常并非如此。如果您严重依赖数据库来实施有关数据元素之间关系的“业务规则”,那么标准化是实现一组特定设计目标和要求的一种方法。
规范化为您带来一些关键的好处:
就是说,有很多正则化的正当理由:
尚不清楚标准化是否是良好设计的标志。在某些情况下,规范化是指存储空间非常宝贵并且对业务规则进行编码的大部分责任都驻留在数据库中的时间的假象(请考虑一下2层客户端-服务器应用程序,其中大多数(如果不是全部)业务逻辑存储过程)。很有可能许多项目都偏离了基于良好的体系结构决策而不是对数据库设计原则的掌握不充分的规范化。
上面评论中引用的Jeff Atwood的文章提供了一些很好的详细讨论- “也许规范化不是正常的”。
从历史上看,规范化也是进行近乎宗教争论的领域,因此,我不愿多说。
在大型项目中,尤其是在大型机中,情况并非如此。实际上,如果您搜索工作站点,您将看到几个数据建模人员的职位。同样,在一个表上有许多列也不会违反规范。但是,您的观察对于某些项目是有效的。
数据库设计是构建质量系统所需的技能之一。话虽如此,一些开发人员对数据库设计的了解还不够,仍然被指派从事数据建模和数据库设计的任务。有些项目甚至跳过了数据建模。许多项目的重点主要是编码和前端设计。
导致数据库设计不佳的另一个因素是,对于第4个NF,第5个NF等,规范化并不是一个特别的话题。我见过的大多数书都无法清楚地说明这些形式。通常会有不好的例子和太多的理论。这使该主题的受欢迎程度降低了。
除非您寻找错误或在测试过程中遇到错误,否则很难发生数据库设计中的错误。没有标准的数据库设计质量会使错误更有可能发生。
此外,有些项目没有遵循严格的开发方法(一种可以促进数据库设计的方法),因此,业务分析师,开发人员和DBA之间职责混合,任务丢失。开发人员在OO和UML中进行交谈,而DBA在DD中进行交谈,而在ERD中则进行一些交谈,可能很多人没有获得UML或OO。简而言之,都是缺乏知识,缺乏好的清晰资源,缺乏描述数据的统一语言以及缺乏方法论。