在数据库方面,"正确化标准化,性能标准化"是一个正确的口头禅吗?

Ayd*_*dya 44 database database-design normalization denormalization

归一化导致许多基本和理想的特征,包括审美愉悦.此外,它在理论上也是"正确的".在这种情况下,非规范化被用作折衷方案,用于实现性能的校正.除了性能之外,还有其他任何理由可以对数据库进行非规范化吗?

Ste*_*owe 81

反规范化的两个最常见原因是:

  1. 性能
  2. 无知

前者应该通过分析进行验证,而后者应该用卷起的报纸进行纠正;-)

我会说一个更好的口头禅是"正确化的标准化,速度的非规范化 - 只有在必要时"

  • @ [Philippe Grondier]:"在编程中,没有绝对,甚至没有这个" - 匿名 (22认同)
  • @RamiFar:抱歉,是的;“消除更新异常”意义上的“正确性” (2认同)
  • 这个答案在 2020 年仍然有意义吗?我正在关注 firebase firestore 的文档,它实际上告诉我对数据进行非规范化以限制关系。我对 NoSQL 数据库还很陌生,但在数据库中故意引入冗余的概念对我来说并不“有吸引力”。在哪里可以找到有关如何在 NoSQL 数据库中存储具有多对多关系的域对象的精彩讲座? (2认同)

Chr*_*son 40

要完全理解原始问题的导入,您必须了解系统开发中的团队动态,以及不同角色/种类的行为(或不当行为).规范化很重要,因为它不仅仅是对设计模式的冷静辩论 - 它还与系统的设计和管理方式有很大关系.

数据库人员接受培训,数据完整性是一个至关重要的问题.我们喜欢用100%的数据正确性来思考,这样一旦数据存在于数据库中,您就不必考虑或处理它在逻辑上的错误.这种思想观念非常重视规范化,因为它会导致(迫使)团队掌握数据和系统的基本逻辑.考虑一个微不足道的例子 - 客户只有一个名称和地址,或者他可以有几个?有人需要决定,系统将依赖于一致应用的规则.这听起来像一个简单的问题,但是当你设计一个相当复杂的系统时,这个问题会增加500倍,你会看到问题 - 规则不能只存在于纸上,它们必须得到强制执行.规范化的数据库设计(除了唯一性约束,外键,检查值,逻辑执行触发器等附加帮助)可以帮助您获得定义明确的核心数据模型和数据正确性规则,这对于当许多人在系统的不同部分(不同的应用程序,报告,等等)工作并且不同的人在系统上工作时,您希望系统按预期工作.或者换句话说 - 如果你没有某种方法来定义和操作强制实施核心数据模型,那么你的系统就会很糟糕.

其他人(通常是经验不足的开发人员)不会这样看待它.他们认为数据库充其量只是他们正在开发的应用程序所奴役的工具,或者最坏的情况是要避免使用官僚机构.(请注意,我说的是"经验不足"的开发人员.一个优秀的开发人员会对数据库人员对可靠数据模型和数据正确性的需求有相同的认识.他们可能会有不同的最佳实现方式,但是根据我的经验,只要数据库团队知道他们正在做什么并且可以响应开发人员,就可以在数据库层中做这些事情.这些经验不足的人往往是那些推动非规范化的人,或多或少是做一个快速而肮脏的设计和管理数据模型工作的借口.这就是您最终获得具有应用程序屏幕和报告的1:1数据库表的方式,每个表反映了开发人员的不同设计假设,以及表之间完全缺乏理智/一致性.在我的职业生涯中,我经历了好几次.开发一个系统是一种令人沮丧且极其缺乏生产力的方式.

因此,人们对规范化有强烈感觉的一个原因是,这个问题是他们强烈关注的其他问题的替身.如果你陷入关于正常化的辩论中,请考虑各方可能为辩论带来的潜在(非技术性)动机.

话虽如此,这是对原始问题的更直接的答案:)

将数据库视为尽可能接近逻辑设计的核心设计(高度规范化和约束)以及解决稳定应用程序接口和性能等其他问题的扩展设计非常有用.

您应该想要约束和规范化您的核心数据模型,因为这样做不会损害数据的基本完整性以及构建系统的所有规则/假设.如果你让这些问题远离你,那么你的系统可能会很快变得糟透了.根据需求和实际数据测试核心数据模型,并疯狂迭代直到它工作.这个步骤将更像是澄清要求而不是构建解决方案,它应该.使用核心数据模型作为强制函数,为所涉及的每个人获得有关这些设计问题的明确答案.

在继续扩展数据模型之前,请完成核心数据模型.使用它,看看你能用它走多远.根据数据量,用户数量和使用模式,您可能永远不需要扩展数据模型.了解您可以在索引中获得多少,以及您可以在DBMS中转换的1,001个与性能相关的旋钮.

如果您真正挖掘了DBMS的性能管理功能,那么您需要考虑以增加非规范化的方式扩展数据模型.请注意,这不是关于对核心数据模型进行非规范化,而是添加处理denorm数据的新资源.例如,如果有一些巨大的查询破坏了您的性能,您可能希望添加一些预先计算这些查询将产生的数据的表 - 基本上是预先执行查询.以保持非规范化数据与核心(规范化)数据的一致性的方式执行此操作非常重要.例如,在支持它们的DBMS中,您可以使用MATERIALIZED VIEW自动维护denorm数据.如果您的DBMS没有此选项,那么您可以通过在存在基础数据的表上创建触发器来实现.

在以连贯的方式选择性地对数据库进行非规范化以处理真实的性能挑战与仅仅具有弱数据设计并使用性能作为其理由之间存在着天壤之别.

当我与经验丰富的中低级数据库人员和开发人员合作时,我坚持他们会产生一个绝对正常化的设计......然后,在讨论选择性非规范化时,可能会涉及少数更有经验的人.在您的核心数据模型中,非规范化或多或少总是坏的.在核心之外,如果以一种经过深思熟虑和连贯的方式进行非规范化,则没有任何错误.

换句话说,从正常设计到保留法线的一个非规范化,同时添加一些非规范性 - 处理数据的物理现实同时保留其基本逻辑 - 很好.没有正常设计核心的设计 - 甚至不应被称为去标准化,因为它们从未被规范化,因为它们从未有意识地以规律的方式设计 - 并不好.

不要接受弱的,无纪律的设计是"非规范化"设计的术语.我认为故意/小心非规范化数据与普通旧的糟糕数据库设计之间的混淆导致非正规数据,因为设计师是一个粗心的白痴是许多关于非规范化的争论的根本原因.

  • 绝对值得一读克里斯的回答,很多一般的建议.在upvotes方面应该更高. (2认同)

Jon*_*ler 16

非规范化通常意味着检索效率的一些提高(否则,为什么要这样做),但是在修改(插入,更新,有时甚至删除)操作期间验证数据的复杂性的巨大成本.大多数情况下,额外的复杂性被忽略(因为它太难以描述),导致数据库中的虚假数据,这通常直到后来才被发现 - 例如当有人试图找出公司破产的原因时事实证明,数据是自我不一致的,因为它是非规范化的.

我认为口头禅应该"正常化,只有当高级管理层提出将你的工作交给其他人时才能正常化",此时你应该接受机会去新的牧场,因为当前的工作可能无法生存,只要你我想.

或者"只有当管理层向您发送一封电子邮件,证明您将要创建的混乱时,才会进行非规范化".

当然,这假设您对自己的能力和对公司的价值充满信心.

  • +1 指出政治成分;现代数据库采用缓存策略,这意味着对于大多数查询,规范化数据通常优于非规范化数据。首先配置文件,然后进行非规范化 ;-) (2认同)

Wal*_*tty 11

Mantras几乎总是过分简化他们的主题.这就是一个例子.

归一化的优点更多仅仅是理论上的或美学上的.对于2NF及以上的正常形式的每次偏离,当您不遵循正常形式时会发生更新异常,并且当您遵循正常形式时会出现更新异常.从1NF出发是一个完全不同的蠕虫,我不打算在这里处理它.

这些更新异常通常包括插入新数据,更新现有数据和删除行.您通常可以通过巧妙,棘手的编程来解决这些异常现象.接下来的问题是使用巧妙,棘手的编程值得花费的好处.有时成本是错误.有时成本是失去适应性.实际上,成本实际上是相信与否,表现不佳.

如果您学习了各种正常形式,在理解随附的更新异常之前,您应该认为您的学习不完整.

"denormalize"作为指导原则的问题在于它并没有告诉你该怎么做.有无数种方法可以对数据库进行非规范化.他们中的大多数都是不幸的,这就是慈善事业.最愚蠢的方法之一就是每次只想对一个步骤进行非规范化,每次你想要加速一些特定的查询.如果不了解应用程序的历史,你最终会得到一个疯狂的mish mosh.

很多非正规化步骤"在当时看起来像个好主意"后来变成非常糟糕的举动.

当您决定不完全正常化时,这是一个更好的选择:采用一些产生某些好处的设计规则,即使该设计规则偏离完全规范化.例如,有星型模式设计,广泛用于数据仓库和数据集市.这是一种更加连贯和规范的方法,而不仅仅是通过奇思妙想的非规范化.您将从星型模式设计中获得特定的好处,并且您可以将它们与您将遭受的更新异常进行对比,因为星型模式设计与规范化设计相矛盾.

通常,许多设计星型模式的人正在构建一个不与OLTP应用程序交互的辅助数据库.保持这样的数据库最新的最困难的问题之一是所谓的ETL(提取,转换和加载)处理.好消息是所有这些处理都可以在少数程序中收集,处理规范化OLTP数据库的应用程序员不必学习这些东西.有一些工具可以帮助ETL,将数据从规范化的OLTP数据库复制到星型模式数据集市或仓库是一个很好理解的案例.

一旦你构建了一个星型模式,并且你已经很好地选择了你的维度,明智地命名了你的列,并且特别选择了你的粒度,那么使用这个星形模式与像Cognos或Business Objects这样的OLAP工具结果就像玩游戏一样简单一个视频游戏.这允许您的数据分析师专注于分析数据,而不是了解数据容器的工作方式.

除了星型模式之外还有其他设计偏离了规范化,但是星型模式值得特别提及.


Cad*_*oux 6

维度模型中的数据仓库通常以(非规范化的)星型模式建模.这些类型的模式(通常)不用于在线生产或交易系统.

根本原因是性能,但事实/维度模型还允许许多时间特征,如传统ER风格模型中可以缓慢改变的维度,但可能非常复杂和缓慢(有效日期,存档表,活动记录)等).


Phi*_*ier 5

不要忘记,每当您对数据库的一部分进行非规范化时,随着代码中的错误风险的增加,您进一步调整数据库的能力会降低,从而使整个系统的可持续性越来越低.

祝好运!

  • 每次你反规范化,EF Codd和CJ Date都会执行CS实习生!;-) (4认同)

nvo*_*gel 5

规范化与性能无关.我不能真正把它比Erwin Smout在这个帖子中做得更好: 标准化数据库会对资源产生什么影响?

大多数SQL DBMS对更改数据的物理表示形式的支持有限而不会影响逻辑模型,因此不幸的是,这可能是您发现必须进行重归一化的一个原因.另一个原因是许多DBMS对多表完整性约束没有很好的支持,因此作为实现这些约束的解决方法,您可能会被迫将无关的属性放入某些表中.