【发布时间】:2019-07-31 15:25:24
【问题描述】:
我有多个表,每个表存储超过 1 亿行数据。任何给定列只有几个可能的唯一值,因此许多列都有重复值。
当我最初设计架构时,我决定使用二级链接表来存储实际值,以优化数据库所需的存储空间。
例如:
而不是像这样存储用户代理的表:
- id (int)
- user_agent (varchar)
我正在使用 2 个这样的表:
表 1
- id (int)
- user_agent_id (int)
表 2
- id (int)
- user_agent (varchar)
当有超过 1 亿行时,我发现此架构可以节省大量存储空间,因为只有几百个可能的用户代理,而这些字符串构成了大部分数据。
我遇到的问题是: 使用链接表在许多不同的表中存储如此多的字符串数据会增加开发方面的开销,并且由于需要连接,因此查询数据的速度要慢得多。
我的问题是: 有没有办法可以将所有列放在一个表中,并强制 mysql 不复制具有重复值的列所需的存储?我开始认为必须有一些内置的方法来处理这种情况,但我在研究中没有发现任何东西。
如果我有一列有 10 个唯一值和 1 亿多行,为什么 MySQL 会将每个值(包括重复项)完全保存在存储中,而不仅仅是对唯一值的引用?
谢谢!
【问题讨论】:
-
您是否尝试过 COMPRESSION 表选项? MYSQL可以为每一页压缩表空间中的数据。
-
@PeterHe - 是的,我所有的表都已经压缩了。在测试时我发现即使每一行都是相同的列的重复值,当切换到 COMPRESSION 时,大小也只会减少 25% 左右。如果我使用关联列和辅助表,则大小会减少 98-99%。使用 ARCHIVE 可以解决我的问题,但鉴于限制,我的应用程序无法解决。
-
如果您有“10 个唯一值”,请使用 1 字节的
TINYINT UNSIGNED而不是 4 字节的INT。这每行节省了 3 个字节,如果在索引中使用则更多。
标签: mysql indexing storage innodb