我应该规范我的数据库吗?

时间:2009-06-01 12:13:19

标签: mysql database optimization rdbms

在为数据库(例如MySQL)设计模式时,会出现是否完全规范表格的问题。

一方面连接(以及外键约束等)非常慢,另一方面,您获得冗余数据和可能出现的不一致。

这里的“优化最后”是正确的方法吗?即创建一个由书本标准化的数据库,然后查看可以非规范化的内容以实现最佳速度增益。

对于这种方法,我担心的是我会选择可能不够快的数据库设计 - 但在那个阶段重构模式(同时支持现有数据)会非常痛苦。这就是为什么我很想暂时忘记我所学到的关于“正确”RDBMS实践的一切,并尝试一次“平台”方法。

这个数据库是否会影响插入效果这个决定?

9 个答案:

答案 0 :(得分:30)

哲学答案:次优(关系型)数据库充斥着插入,更新和删除异常。这些都会导致数据不一致,导致数据质量不佳。如果您不相信数据的准确性,它有什么用处?问问自己:你想要更慢的答案,还是想更快地得到错误答案?

作为一个实际问题:在你快速完成之前把它弄好。我们人类很难预测瓶颈会发生在哪里。使数据库变得更好,在相当长的一段时间内测量性能,然后决定是否需要加快速度。在你反规范化和牺牲准确性之前尝试其他技术:你能获得更快的服务器,连接,数据库驱动程序等吗?存储过程可能会加快速度吗?索引及其填充因子如何?如果这些和其他性能和调优技术不起作用,那么只考虑非规范化。然后测量性能以验证您获得了“付费”的速度增加。确保您正在执行优化,而不是悲观。

[编辑]

  问:那么如果我最后优化,你能吗?   建议合理的迁移方式   架构更改后的数据?如果,   例如,我决定摆脱一个   查找表 - 如何迁移   现有数据库这个新设计?

答:好的。

  1. 进行备份。
  2. 另外备份到其他设备。
  3. 使用“从oldtable中选择新表...”类型命令创建新表。您需要进行一些连接以组合以前不同的表。
  4. 放下旧桌子。
  5. 重命名新表。
  6. 但是 ......考虑采用更强大的方法:

    立即在完全规范化的表格上创建一些视图。那些视图(虚拟表,数据上的“窗口”......问我是否想要了解更多关于这个主题的内容)将具有与上面第三步相同的定义查询。在编写应用程序或DB层逻辑时,请使用视图(至少对于读取访问;可更新视图是......好的,感兴趣的)。然后,如果稍后进行非规范化,则创建一个如上所述的新表,删除视图,重命名视图所在的新基表。您的应用程序/ DB层将不知道其中的区别。

    在实践中实际上还有更多,但这应该让你开始。

答案 1 :(得分:14)

数据库的使用模式(insert-heavy与reporting-heavy)肯定会影响您的规范化。此外,如果您看到规范化表格显着减速,您可能需要查看索引等。您使用的是哪个版本的MySQL?

通常,插入密集型数据库应该比报告密集型数据库更多规范化。但是,YMMV当然......

答案 2 :(得分:7)

正常的设计是开始的地方;说实话,首先,因为你可能不需要加快速度。

对时间成本高的连接的关注通常基于设计不佳的经验。随着设计变得更加正常,设计中的表格数量通常会增加,而每个表格中的列数和行数减少,设计中的联合数量随着连接数量的减少而增加,指标变得更有用,& C。换句话说:好事发生了。

规范化只是结束正常设计的一种方式......

答案 3 :(得分:4)

  

这里的“优化最后”是正确的方法吗?即创建一个由书本标准化的数据库,然后查看可以非规范化的内容以实现最佳速度增益。

我会说,是的。我不得不多次处理结构糟糕的数据库,以宽恕“扁平表”而没有多少思考。

实际上,插入通常在完全标准化的DB上表现良好,因此如果插入量很大,则这不应该是一个因素。

答案 4 :(得分:4)

此问题的一般设计方法是首先将数据库完全标准化为第3范式,然后根据性能和易于访问的方式进行非规范化。这种方法往往是最安全的,因为您通过设计做出具体决策而不是默认情况下不进行规范化。

'酌情'是经验丰富的棘手问题。规范化是一个相当“可靠的”程序,可以教授,知道非规范化的位置不太精确,并且将取决于应用程序的使用和业务规则,因此应用程序因此而异。你所有的非规范化决定都应该对同事来说是可以辩护的。

例如,如果我有一对多的关系,A到BI就会在大多数情况下将此标准化,但如果我知道该业务只有例如每个A有两次出现B,那么这种情况极不可能要改变,B记录中的数据有限。他们通常会用A记录拉回B数据,我很可能会在两次出现B字段的情况下扩展A记录。当然,大多数通过DBA的人会立即将此标记为可能的设计问题,因此您必须能够令人信服地论证您对非规范化的理由。

由此可以明显看出,非规范化应该是例外。在任何生产数据库中,我都希望绝大多数 - 95%以上 - 处于第3范式,只有少数非规范化结构。

答案 5 :(得分:4)

在一个插入量很大的数据库上,我肯定从标准化表开始。如果查询存在性能问题,我首先尝试优化查询并添加有用的索引。

只有这样做没有帮助,你应该尝试非规范化表。确保在非规范化之前和之后对插入和查询进行基准测试,因为很可能会降低插入速度。

答案 6 :(得分:4)

你在哪里得到“加入(和外键约束等)非常慢”的想法?这是一个非常模糊的陈述,通常IMO没有性能问题。

答案 7 :(得分:4)

在操作系统上很少需要非规范化。我为数据模型制作的一个系统有560个表或左右(当时它是澳大拉西亚最大的J2EE系统)并且只有4个非规范化数据。其中两个项目是非规范化搜索表,旨在促进复杂的搜索屏幕(一个是物化视图),另外两个是为响应特定的性能要求而添加的。

不要过早地使用非规范化数据优化数据库。这是持续数据完整性问题的一个方法。此外,始终使用数据库触发器来管理非规范化数据 - 不要依赖应用程序来执行此操作。

最后,如果您需要提高报告性能,请考虑构建数据集市或其他单独的非规范化结构以进行报告。结合大量数据计算的聚合实时视图要求的报告很少见,并且往往只出现在少数几个业务领域。可以做到这一点的系统往往非常繁琐,因此很昂贵。

几乎可以肯定,只有少数报告真正需要最新的数据,而且几乎总是可以运行报告,例如可以处理少量数据的待办事项列表或异常报告。其他任何东西都可以推送到数据集市,每晚刷新可能就足够了。

答案 8 :(得分:2)

我不知道你在创建数据库 by-the-book 的意思是什么,因为我读过的大多数有关数据库的书都包含一个关于优化的主题,这与对数据库进行非规范化是一回事。设计。

这是一种平衡行为,所以不要过早优化。原因是非规范化数据库设计往往变得难以使用。你需要一些指标,所以要对数据库进行一些压力测试,以便决定你是否要反规范化。

因此规范化可维护性,但是非规范化以进行优化。