MySQL是否会自动将重复的VARCHAR存储减至最少?

kbr*_*bro 5 mysql database optimization

该问题针对的是在默认InnoDB表类型为Ubuntu 10.04 LTS Server上运行的MySQL 5.5 ...

假设我有一个房屋地址表“ Address”,其中有“ number”,“ street”,“ district”,“ town”,“ county”和“ postcode”列。在这些列中,我将有许多行具有相同的值,并且将它们分别索引以进行搜索。假设我将每列实现为VARCHAR(127)并创建1000行,所有行都带有town ='London'。这是否意味着我最终在数据库中获得了字符串“ London”的1000个副本,还是MySQL做得很聪明,只将该字符串存储了一次,然后从所有1000行中引用了该副本?

我到目前为止所做的事情是通过为每个列创建单独的表来显式处理重复项,每个表都具有“ id”和“ value”列,然后在Address表中使用外键引用每个表中的唯一值表。每次插入新的“地址”行时,我都会搜索每个表,以查看号码,街道,地区等是否已经存在。如果是,则使用现有索引,如果不使用,则我在该表中插入一行并使用新索引。

显然,我的方法最大程度地减少了存储的VARCHAR字符串的数量,因为每个重复项只有一个副本。问题是,如果我只是将列声明为VARCHAR并为它们建立索引,MySQL会做同样的事情吗(或更好!)?

Ric*_*mes 5

您将获得 1000 份《伦敦》。在 a 中VARCHAR(127),每个副本将消耗 1 或 2 个字节的长度,加上“London”的 6 个字节。这样想……指向单个副本等的开销(平均而言)可能比节省的开销更大。

如果您正在谈论索引中的“前缀重复数据删除”,那么这还没有完成,但已被建议。这实际上是一种更通用的节省空间的方法,但它仅适用于类似索引的结构。

(这个答案适用于所有版本的 MySQL、所有常见引擎、所有CHARACTER SETs.)

寻找“列存储”,例如 InfiniDB。

此外,TokuDB、InnoDB ROW_FORMAT=COMPRESSED、FusionIO 等将使用压缩技术来减少磁盘使用量。这些不会像您所描述的那样进行重复数据删除。