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

Ass*_*vie 31 mysql database optimization rdbms

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

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

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

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

这个数据库是否会插入重量会影响决定吗?

Ala*_*lan 31

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

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

[编辑]

问:所以如果我最后一次优化,你可以推荐一种合理的方法来在模式更改后迁移数据吗?例如,如果我决定摆脱查找表 - 如何将现有的数据库迁移到这个新设计?

A:好的.

  1. 做一个备份.
  2. 对另一台设备进行另一次备份.
  3. 使用"从oldtable中选择新表..."类型命令创建新表.您需要进行一些连接以组合以前不同的表.
  4. 放下旧桌子.
  5. 重命名新表.

但是 ......考虑一种更强大的方法:

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

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


Gal*_*boy 14

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

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

  • 插入重的DB应该更加标准化,因为它们的主要焦点是捕获数据.如果是事务性的,则需要3NF数据库.如果您正在进行报告数据库,主要关注的是将信息拉出,那么您需要一个半非规范化的数据库. (3认同)
  • 更一般地说,规范化数据库从数据中获取数据的速度较慢(因为需要计算更多数据),但获取数据的速度更快(因为必须完成更少).因此,插入量大的DB将受益于规范化,但数据仓库DB将受益于较少的规范化. (3认同)

小智 7

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

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

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


eri*_*len 5

你从哪里得到“连接(和外键约束等)非常慢”的想法?这是一个非常模糊的声明,通常 IMO 没有性能问题。

  • 扫描好的索引,尤其是覆盖索引的连接非常高效。另一件要注意的事情是锁定你的桌子。根据您的要求,拥有多个表可能意味着某些插入、删除和更新可以安全地同时发生在不同的表中。 (5认同)
  • 加入不是免费的。根据您的数据库的标准化程度,您可能会看到一个数量级的慢得多的查询。本质上,它是每个表的所有行的叉积,其中不满足连接条件的行将被消除。这可能是优化的,但这仍然是一个更昂贵的操作。 (2认同)
  • @Assaf:OTOH,您的数据可能较少,因此数据适合 RAM。而你声称“本质上它是一个交叉产品......”完全是错误的。这是一个连接,仅此而已。 (2认同)

Con*_*lls 5

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

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

最后,如果您需要提高报告性能,请考虑为报告构建数据集市或其他单独的非规范化结构。结合对大量数据计算的实时聚合视图的要求的报告很少见,而且往往只出现在少数业务线中。可以做到这一点的系统往往构建起来非常繁琐,因此成本很高。

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