【问题标题】:Does normalizing strings increase SELECT performance in SQLite?规范化字符串是否会提高 SQLite 中的 SELECT 性能?
【发布时间】:2013-06-13 09:20:25
【问题描述】:

我刚读到Coding Horror: Maybe Normalizing Isn't Normal,他们特别说规范化会降低 SELECT 查询的性能,因为有很多 INNER JOIN 语句。

但是我有一个表,我打算将几个 TEXT 列放在单独的表中,这样我就可以比较整数索引而不是字符串,但是现在我阅读了这篇文章,我不确定是否应该这样做。

作为一个例子,如果我们比较这个非规范化的表:

CREATE TABLE addresses (country TEXT, city TEXT, address TEXT);
SELECT address FROM addresses WHERE Country=? AND City=?;

使用规范化形式:

CREATE TABLE countries (name TEXT UNIQUE);
CREATE TABLE cities (name TEXT UNIQUE);
CREATE TABLE addresses (country INT, city INT, address TEXT);
SELECT addresses.address FROM addresses INNER JOIN countries ON countries.ROWID=addresses.country INNER JOIN cities ON cities.ROWID==addresses.city WHERE countries.name=? AND cities.name=?;

对于 SQLite,第二种形式是更慢、更快还是与第一种形式的速度相同?

【问题讨论】:

  • 他们错了。标准化是一件好事。
  • 那么它会提高我的 SELECT 查询的速度吗?它看起来和这个例子一模一样,只是列名不同:)
  • 文章还说没关系,直到你达到数百万或数十亿(用户数/帖子数等)
  • 除非您在人员和地址之间存在一对多关系,否则您有一个地址表这一事实很奇怪。
  • 这是一个虚构的例子,不是我的实际表格。我只有 2 个文本列,可以放在另一个表中。这些列包含的值通常相同,就像国家和城市通常是相同的文本一样。

标签: sql performance sqlite normalization


【解决方案1】:

大多数人不知道规范化是什么意思。

如果您要求每个表中的每一行都有一个 ID 号,并且您使用这些 ID 号作为外键,那么您需要进行 很多 次连接以获取有用的信息。 (从这个意义上说,身份证号码不是有用的信息。)

但规范化与识别依赖关系和投射新关系有关。规范化与 ID 号有任何关系。

在您的表格中,您将文本替换为 ID 号。那不是标准化。这只是用 ID 号替换文本。

在大多数情况下,文本会比 ID 号和连接更好。我自己对此进行了测试,并在 stackoverflow.com 和 dba.stackexchange.com 上多次写过。

【讨论】:

  • 你的回答让我有点困惑。规范化不是将数据拆分为单独的表以避免重复吗?在我的示例中,我可以有 10000 行重复“美国”。
  • 在您使用术语 duplication 的意义上,不,这不是规范化的意义所在。用值 123 替换 10000 行中的“美国”不是规范化。这种替换不会改变正常形式;如果表在替换前处于 3NF,则替换后仍将处于 3NF。而且你仍然会有重复。你只会复制数字而不是字符串。
  • 但是来自 C++ 背景,数字比字符串小,而且比较数字也比比较字符串快。但可能是 SQLite 使用了一些非常优化的比较操作。此外,如果第三列将 PNG 图像保存为二进制 blob,每个大小为 50 KB,并且它们重复很多次,那么同一个 PNG 会出现多次怎么办?那么我用 ID '替换' PNG 会是规范化吗?
  • 规范化从不问,“列有多宽?”或“我可以多快比较值?”用 ID 号替换 PNG 不是规范化,尽管出于其他原因这可能是一个好的设计决策。 (许多数据库设计决策与规范化无关。)无论数据类型如何,不需要连接通常比需要两个连接更快。你不必相信我的话;自己做一些测试。 (不要忘记添加必要的索引。)
  • 数据规范化与对一系列限制性更强的范式的一致性有关。表分解是实现更高范式的常用变换。规范化仅与性能有关。这主要是为了避免使用自相矛盾的数据库。
猜你喜欢
  • 2013-05-08
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 2014-06-06
  • 2018-04-16
  • 2021-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多