【问题标题】:MySQL: When To Break Up / Split a TableMySQL:何时分解/拆分表
【发布时间】:2014-04-24 12:49:32
【问题描述】:

我正在构建一个数据库,但我不确定我应该建立多深的层次结构。

似乎节省空间的最佳情况是三层。 group->sub_group->item

在平均情况下,一个子组有 300 个项目,而组有 100 个子组。项目目前接近 100 万件,并且正在加速增长。

我很想将 GROUP 与 ITEM 区分开来,因为它反映了现实世界,但 SUB_GROUP 仅存在是因为 ITEM 通常在几百行中是相同的。需要明确的是,我可以将数据放在子组的一个实例中,并将其附加到项目的每个实例中。

在每个查询中至少进行 3 个连接会更好地提高性能吗?还是我最好用更多重复数据制作更少的表格?

【问题讨论】:

  • 我不知道有什么时候后悔过规范化表格,而且很多时候不这样做会引起很多头痛。索引将为您提供所需的性能。

标签: mysql sql rdbms


【解决方案1】:

这与其说是一个 MySQL 问题,不如说是一个 SQL RDBMS 问题。

您有一个规范化的数据库以消除重复并最大限度地减少存储。

在以下情况下,您可能正确地将子组信息归一化并与项目一起放置:

  1. 子组数据很小。
  2. 您经常同时查询子组和项目信息,查看是不够的。
  3. 您实际上遇到了会推动更改的性能问题 - 不要过早地进行优化。

可能还有其他考虑因素,但这应该让你开始。

这里没有绝对的。

【讨论】:

  • 我认为这引导我不要制作子组表。澄清一下,如果 SUB_GROUP 存在,则在未加入 SUB_GROUP 的情况下永远不会查询 ITEM。项目基本上不包含任何数据。没有 SUB_GROUP 将极大地有助于查看/理解数据库。我只是不熟悉节省所有这些空间是否值得,以及它是否克服了查询中相关的麻烦。
  • 那将是错误的决定,因为它允许您的数据以不正确的状态存在(items 的某些行中的公共值可能会被更新,而其他行则保留其原始值 --哪个是正确的?正确地构造数据,如果JOIN将表放在一起是常见的操作,则将其封装在 VIEW 中。
  • 再一次,似乎正确的规范化应该包括 sub_group,但我也相信插入的数据基本上是最终的。不创建这个新层将有利于生成报告,这是我计划对数据做的所有事情。我仍然犹豫不决,似乎问题是:技术上正确 VS 保持简单和更真实的世界。
  • 子组级别存储了多少数据?非规范化在报告/数据仓库工作中很常见,其中重复数据可以简化分析并加快检索速度。也就是说,使用视图封装连接或直接使用它们不应该被认为是一件令人头疼的事情——它是关系数据库的基础。
  • 子组将保存 5 个 int 值,并且项目将仅指向子组。
【解决方案2】:

您的决定首先不应基于性能问题、检索数据所需的 JOIN 数量或任何相关问题。您应该选择正确为您的数据建模的设计。如果您使用关系数据库来存储数据,则意味着遵循数据规范化原则独立于感知的性能问题。完成此操作后,如果您确实无法获得所需的性能,则可以考虑进行有限的战略性非规范化以获得所需的性能。然而,在大多数情况下,归一化的解决方案也是性能最高的。

也就是说,我并不完全清楚什么是“组”、“子组”和“项目”在现实世界中建模。但是,数据规范化的原则绝对表明items 中多条记录的多列中的公共值应抽象为sub-group 中的一条记录。不清楚的是您是否可以仅使用三个表,或者是否还有其他级别的分组需要规范化。

【讨论】: