问题针对的是在 Ubuntu 10.04 LTS Server 上运行的 MySQL 5.5,默认的 InnoDB 表类型...
假设我有一个包含房屋地址的表“Address”,其中包含列“number”、“street”、“district”、“town”、“county”和“postcode”。我将在这些列中有许多具有相同值的行,并且我将单独为它们建立索引以进行搜索。假设我将每一列实现为 VARCHAR(127) 并创建 1000 行,所有行都包含 town='London'。这是否意味着我最终在我的数据库中得到了字符串“London”的 1000 个副本,或者 MySQL 做了一些聪明的事情并仅存储该字符串一次,然后从所有 1000 行中引用该副本?
到目前为止,我一直在做的事情是通过为这些列中的每一列创建单独的表来显式处理重复项,每个表都有“id”和“value”列,然后使用 Address 表中的外键来引用唯一的每个表中的值。每次我插入一个新的地址行时,我都会搜索每个表以查看号码、街道、地区等是否已经存在。如果是,我将使用现有索引,如果不是,则我会在该表中插入一行并使用新索引。
显然,我的方法最大限度地减少了存储的 VARCHAR 字符串的数量,因为每个副本只有一个副本。问题是,如果我简单地将列声明为 VARCHAR 并为其建立索引,MySQL 是否会做同样的事情(或更好!)?
最佳答案
您将获得 1000 份《伦敦》。在 VARCHAR(127)
中,每个副本将占用 1 或 2 个字节的长度,加上 6 个字节的“伦敦”。以这种方式思考......指向单个副本等的开销可能比节省的开销更大(平均而言)。
如果您在谈论索引中的“前缀去重”,那还没有完成,但已被建议。这实际上是一种更通用的节省空间的方法,但它仅适用于类似索引的结构。
(此答案适用于所有版本的 MySQL、所有常见引擎、所有CHARACTER SETs
。)
寻找“列存储”,例如 InfiniDB。
此外,TokuDB、InnoDB with ROW_FORMAT=COMPRESSED
、FusionIO 等,将使用压缩技术来减少磁盘使用。那些不会像您描述的那样删除重复数据。
关于mysql - MySQL 会自动最小化重复的 VARCHAR 存储吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33312068/