数据库规范化死了吗?

PhD*_*PhD 16 normalization database-design

我从小就受过教育——在那里我们学会了在应用程序的业务层之前设计数据库模式(或将 OOAD 用于其他一切)。我一直很擅长设计模式(恕我直言:) 并且规范化只是为了删除不必要的冗余,而不是影响速度的地方,即如果连接是性能下降,冗余就留在原地。但大多数情况并非如此。

随着一些 ORM 框架的出现,如 Ruby 的 ActiveRecord 或 ActiveJDBC(以及其他一些我不记得了,但我相信有很多)似乎他们更喜欢为每个表设置一个代理键,即使有些有主键,例如'email' - 彻底打破 2NF。好吧,我不太明白,但是当这些 ORM(或程序员)中的一些不承认 1-1 或 1-0|1(即 1 比 0 或 1)时,我(几乎)会感到紧张。他们规定,无论是否有大量nulls “今天的系统可以处理它”,最好将所有东西都放在一张大桌子上,是我经常听到的评论。

我同意内存限制确实与规范化直接相关(还有其他好处:)但是在今天内存便宜和四核机器的时代,数据库规范化的概念是否只是留给文本?作为 DBA,您是否仍然练习标准化为 3NF(如果不是 BCNF :)?有关系吗?“脏模式”设计对生产系统有好处吗?如果它仍然相关,那么应该如何将其“用于”规范化。

注意:我不是在谈论数据仓库的星形/雪花模式,它们具有冗余作为设计的一部分/需要,而是具有后端数据库(例如 StackExchange)的商业系统)

gbn*_*gbn 17

规范化的一个原因是删除数据修改异常
ORM 通常不支持这一点。

我有许多违反此原则的 Hibernate 设计的数据库示例:

  • 臃肿(字符串重复数百万行)
  • 没有查找表(见上文)
  • DRI(约束、键)
  • varchar 聚集索引
  • 不必要的链接表(例如,当可空 FK 列就足够时强制执行 1..0:1)

我见过的最糟糕的是 1TB MySQL 数据库,由于这些原因,它可能大了 75-80%

我还建议“今天的系统可以处理它”这句话适用于大多数米老鼠系统。随着您的扩展,今天的系统不会。

在我上面的例子中,重构或更改密钥或修复数据没有吸引力:只是抱怨数据库增长率和无法在其上构建有意义的 DW


NoC*_*nce 13

似乎他们更喜欢每个表都有一个代理键,即使有些表有像“电子邮件”这样的主键 - 彻底打破 2NF。

代理键不会破坏 2NF。2NF 表示“如果一列仅依赖于多值键的一部分,则将该列移除到单独的表中。”

他们规定,无论是否有大量空值,最好将所有内容都放在一张大表中

只要遵循规范化规则,一个表中有几列是有效的。如果您想获得 SQL 和规范化的好处,那么在没有分析的情况下合并表是不正确的。

我同意内存限制确实与规范化直接相关关系范式是一个数学概念,与内存无关。

规范化不仅可以节省内存或磁盘,还可以增加完整性。毕竟它是一个独立于硬件的数学概念。

简单示例:假设您将学校信息维护为:

推荐 1:美国加利福尼亚州北岭高中

推荐 2:加拿大安大略省南多伦多勇士高中

如果你问你的系统安大略在哪里,你会发现它在加拿大。几天后,您删除了第 2 行并向系统提出了同样的问题,但您一无所获。在这个例子中,无论有多少磁盘空间或内存或 CPU,你都不会得到答案。

这是一个异常正常化的关系有助于防止。

编辑:根据下面的评论将多伦多一词改为安大略。


Joe*_*own 12

事物变化得越多,它们就越保持不变。总有一些懒惰的开发人员偷工减料,或者只是不知道或不想遵循最佳实践。很多时候他们可以在较小的应用程序中摆脱它。

它曾经将受 COBOL 启发的数据结构干扰到早期的 RDBMS 或 dBase 中。现在是 ORM 和“代码优先”。最后,这些只是人们试图找到获得工作系统的灵丹妙药的方法,而不是“浪费”时间仔细思考你想要和需要做什么。赶时间一直是个问题,也将永远是个问题。

对于那些有理智(和好运)花时间正确设计的人来说,数据模型永远是最合乎逻辑的起点。数据库中的内容是有关您的企业关心的事物(有形和无形)的信息。 什么关于改变您的企业的烦恼要少得多快于如何您的业务运作。这就是为什么您的数据库通常比您的代码稳定得多的原因。

数据库是任何系统的合法基础,从长远来看,花时间正确地奠定基础将不可避免地使您受益。这意味着规范化对于任何 OLTP 类型的应用程序来说始终是一个重要的、有用的步骤。


Mar*_*ith 9

我同意内存限制确实与规范化直接相关......

内存限制仍然很重要。数量不是问题,速度才是。

  • 目前 CPU 并没有变得更快(我们正在获得更多内核,而不是每秒周期数)
  • 现代 CPU 架构试图通过为每个处理器 ( NUMA )提供单独的内存来克服速度限制。
  • 片上缓存大小的增长速度与主内存不相上下。
  • 内存吞吐量并不像大多数人预期的那么高。QPI在 25GB/秒的范围内。

一些这个地方是在覆盖当超过INT使用TINYINT?您可能会觉得这很有用。我还建议遵循SQLCAT 团队的 @ThomasKejser(博客)的滑稽动作,因为他们往往处于推动数据库性能的前沿。最近发表的关于CPU 缓存和内存访问模式的影响的文章关于 Extreme DW Scale 的关系建模的 SQLBits 演示就是很好的例子。