【问题标题】:How do I not normalize continuous data (INTS, FLOATS, DATETIME, ....)?如何不规范化连续数据(INTS、FLOATS、DATETIME、....)?
【发布时间】:2018-09-19 23:22:43
【问题描述】:

根据我的理解——如果我错了请纠正我——“规范化”是从数据库设计中删除冗余数据的过程

但是,当我尝试了解数据库优化/调优以提高性能时,我遇到了 Mr. Rick James 建议反对规范化连续值,例如(INTS、FLOATS、DATETIME,...)

“标准化,但不要过度标准化。”特别是,不要标准化 日期时间或浮点数或其他“连续”值。

source

当然,纯粹主义者会说时间标准化。这是一个很大的错误。一般来说, “连续”值不应标准化,因为您通常 想要对它们进行范围查询。如果归一化,性能 会差几个数量级。

标准化有几个目的;它们在这里并不真正适用:

  • 节省空间——一个时间戳是 4 个字节;用于标准化的 MEDIUMINT 为 3;节省不多

  • 允许更改通用值(例如,在一处将“International Business Machines”更改为“IBM”)——此处不相关;每个 时间是独立分配的,你不是时间领主。

  • 对于日期时间,规范化表可能有额外的列,如“星期几”、“一天中的小时”。是的,但性能仍然 糟透了。

source

不要规范化“连续”值——日期、浮点数等—— 特别是如果您要进行范围查询。

source.

我试图理解这一点,但我无法理解,有人可以向我解释一下,并举例说明应用此规则会提高性能的最坏情况吗?

注意:我本可以在评论或其他内容中询问他,但我想单独记录并强调这一点,因为我相信这是非常重要的说明,几乎影响了我的整个数据库性能 p>

【问题讨论】:

  • 你能引用一本可信的教科书,将数据库规范化定义为用 ID 号替换文本吗? (不,你不能。)规范化永远不会引入新属性。
  • 属性schools.id 是新的。
  • PS RickJames 似乎不知道什么是“标准化”。他们似乎认为这与用 id 替换值有关。它们似乎也意味着用与其结合的值替换一个值,这确实与“1NF”的某些概念有关,但与更高 NF 的规范化无关。无论如何,'不要规范化“连续”值'太短了,无法表示任何意思,甚至不清楚 continuous 是什么意思,而且这句话通过吓人的引号承认它并不清楚;您需要更多地搜索他们的帖子和/或在 SO 帖子上向他们发表评论以解释他们的意思。
  • “这只是 ID ......” 这不只是 ID。这是一个巨大的危险信号,上面写着“我不了解数据库规范化”。规范化从不引入新属性。没有“过度规范化”之类的东西。只有各种范式 1NF、2NF、BCNF 等。声称“肯定纯粹主义者说标准化时间”,我认为这意味着用代理整数替换时间戳,这只是无稽之谈。代理 id 编号与规范化无关。
  • RickJames 似乎不知道什么是“规范化” 并且 '不要规范化“连续”值'太短了,没有任何意义,甚至不清楚什么连续意味着,这句话承认它通过吓人的引号不清楚。为什么还要问报价是什么意思?我可以猜测这些误解,再加上不明确的文字,导致了这句话。这告诉你我的猜测,而不是他们的意思。评论 RickJames 的帖子,将它们发送到这里。但是不要相信他们对“规范化”一词的使用。 Re "1NF" & "normalization"..

标签: performance database-design database-normalization denormalization


【解决方案1】:

评论(到目前为止)正在讨论“规范化”一词的滥用。我接受这种批评。讨论的内容有术语吗?

让我用这个例子详细说明我的“声明”...一些 DBA 用代理 ID 替换 DATE;使用日期范围时,这可能会导致严重的性能问题。对比一下:

-- single table
SELECT ...
    FROM t
    WHERE x = ...
      AND date BETWEEN ... AND ...;   -- `date` is of datatype DATE/DATETIME/etc

-- extra table
SELECT ...
    FROM t
    JOIN Dates AS d  ON t.date_id = d.date_id
    WHERE t.x = ...
      AND d.date BETWEEN ... AND ...;  -- Range test is now in the other table

将范围测试移动到JOINed 表会导致速度变慢。

第一个查询可以通过以下方式进行优化

INDEX(x, date)

在第二个查询中,优化器将(至少对于 MySQL)从两个表中选择一个开始,然后对另一个表进行一些乏味的来回处理以处理 WHERE 的其余部分。 (其他引擎使用其他技术,但成本仍然很高。)

DATE 是您可能进行“范围”测试的几种数据类型之一。因此,我声明它适用于任何“连续”数据类型(整数、日期、浮点数)。

即使您没有范围测试,辅助表也可能不会带来性能优势。我经常看到 3 字节的 DATE 被 4 字节的 INT 替换,从而使主表变大! “复合”索引几乎总是会为单表方法带来更有效的查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-30
    • 2020-05-04
    • 2014-05-30
    • 1970-01-01
    • 2014-12-23
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    相关资源
    最近更新 更多