服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-08-30 更新于 2026-08-30 简米科技 2,588 字 6 分钟阅读

列式存储的字典编码能缩减宽表存储空间吗,怎么实现?

导读列式存储的字典编码,能将宽表中大量重复的列值映射为短整数,存储空间缩减效果立竿见影,尤其在性别、城市、状态这类低基数列上, 字典编码的思路并不复杂:给每个不同的值分配一个数字编号,保存数据时只存编号,编号对应的原值单独存一份,行式存储因为一行数据交错存放,不同列的值混在一起,编号很难连续排列;而列式存储把同一列……

列式存储的字典编码,能将宽表中大量重复的列值映射为短整数,存储空间缩减效果立竿见影,尤其在性别、城市、状态这类低基数列上。 字典编码的思路并不复杂:给每个不同的值分配一个数字编号,保存数据时只存编号,编号对应的原值单独存一份,行式存储因为一行数据交错存放,不同列的值混在一起,编号很难连续排列;而列式存储把同一列的值挨个排好,重复值天然聚在一起,字典编码就能发挥最大威力。

列式存储和行式存储的区别:为什么字典编码在列式上更省

行式存储的布局特点

  • 一行记录的所有字段连续写在磁盘上,像一张纸质表格的每一行。
  • 读取单条记录快,但分析类查询要扫全表,且不同列数据类型混编,通用压缩算法也很难压出理想效果。
  • 字典编码在行式上也能用,但重复值不连续,每个值都需要单独处理,字典映射表开销大,整体收益不明显。

列式存储的布局特点

  • 每一列单独成文件或块,同一列的数据类型一致,取值范围通常有限。
  • 查询某几列时只需读取对应列块,IO大幅减少。
  • 同一列的重复值在物理上相邻,字典编码后编号序列有很强的规律性,后续还能配合其他压缩算法再压一层。

行业共识认为,列式存储天生适合分析型负载,字典编码正是把这一优势放大到存储空间的利器,换句话讲,同样的宽表数据,用列式存储再开字典编码,比行式存储加普通压缩能省下可观的容量。

宽表存储空间怎么省?字典编码的压缩原理

很多做数据仓库的朋友都有过这样的困惑:明明业务表只

列式存储的字典编码能缩减宽表存储空间吗,怎么实现?

有几千万行,展开成宽表后磁盘占用却涨了好几倍,原因就在于宽表里塞进了大量重复的维度字段,比如订单状态、支付方式、用户等级、渠道来源,这些字段在每一行里都存着完整的字符串,占用的字节数远高于字段本身的信息量。

字典编码到底做了什么

  • 假设有个省份列,里面只有“北京”“上海”“广东”三个值,重复一万次。
  • 建一张字典表:北京→0,上海→1,广东→2。
  • 数据文件里实际存放的是 0、1、2、0、1、2…… 这样的整数序列,每个整数通常只占 1 到 2 字节,远小于中文字符串的存储开销。
  • 查询时先读字典,再对整列做翻译,或者直接在编号上执行聚合,省空间的同时还能提升速度。

宽表为什么更依赖字典编码

  • 宽表动辄几十上百列,其中相当一部分是低基数的维度列,重复度极高。
  • 这类列经过字典编码后,体积可以缩到原来的几分之一,多个列叠加起来,整体存储量下降非常明显。
  • 以订单宽表为例,用户ID这类高基数列不适合编码,但状态、地区、类型等列几乎都能大幅压缩。

业内专家指出,在实际数据仓库场景中,宽表经过列式存储和字典编码后,总体存储开销往往能减少一半以上,这个结论在多个开源引擎的公开测试中都能得到验证。

编码后还能叠加压缩

  • 生成整数序列后,相邻值之间往往有重复或规律,可以再用RLE、Snappy等算法。
  • 列式存储引擎通常支持先字典编码,再做通用压缩,两层效果叠加,压缩比更可观。
  • 有些引擎还会把字典本身也单独压缩,进一步减少元数据占用。

列式存储的字典编码能缩减宽表存储空间吗,怎么实现?

列式存储字典编码怎么用:Parquet与ORC实操对照

字典编码不是需要你手动写算法的黑科技,主流列式存储格式都内置了自动字典编码机制,你只需要选对文件格式,再确认参数没被关掉就行。

Parquet字典编码的开启与关闭

  • Parquet默认启用字典编码,当列的不同值数量相对于行数较低时自动触发。
  • 在Spark中设置参数:spark.conf.set("parquet.enable.dictionary", "true"),该参数控制是否允许构建字典页。
  • 如果某个列的基数太高,Parquet会自动跳过字典编码,改用普通编码,不会强行为每个唯一值建字典。
  • 查看效果时,用Spark写入Parquet后对比目录大小,比CSV或行式存储格式往往能看到明显差距。

ORC字典编码的行为

  • ORC同样默认使用字典编码,对字符串列会自动判断是否值得建字典。
  • 当列的基数超过字典大小阈值时,会退回直接存储,保证不产生负优化。
  • Hive中涉及ORC的配置主要是orc.compress,默认是ZLIB,字典编码后还会再走一层通用压缩,大多数情况下无需手动干预。

实操对比:一张宽表在行式与列式下的体积差

  • 准备一张模拟订单宽表,包含多条记录、多个列,其中一半以上是低基数字符串列。
  • 分别用CSV(行式)和Parquet(列式)存储,观察目录占用。
  • 常见结果是Parquet体积连CSV的一半都不到,字典编码贡献很大,如果列基数更低,节省更明显。

字典编码的局限:什么情况别指望它省空间

字典编码不是万能的,遇到高基数列或频繁更新的数据,效果会大打折扣,甚至变成负担。

高基数列是字典编码的克星

列式存储的字典编码能缩减宽表存储空间吗,怎么实现?

  • 比如用户ID、订单编号、UUID,每行都不重复,字典需要为每个值分配编号,字典本身可能比源数据还大,编码毫无意义。
  • 列式存储引擎会自动跳过这些列,不给它们建字典,所以更不会拖累整体压缩效果。

更新频繁的表要谨慎

  • 字典编码适合写入后很少修改的数据,如果某个列频繁新增不同值,字典要不断重建,维护开销很高。
  • 数据仓库的宽表多为离线批量写入,正好匹配这个前提,如果是实时高频更新的表,建议评估字典重建成本。

选型建议

  • 列基数低于一定阈值(比如几千)且列重复度高,放心用字典编码。
  • 列基数高但长度也长时,可以尝试通用压缩算法,别指望字典。
  • 混合负载场景下,把高基数列和低基数列分开存储,或者用不同的压缩策略,效果往往更好。

关于列式存储字典编码节省宽表空间的常见问题

字典编码会影响查询速度吗?

不会,因为聚合操作可以直接在整数编号上进行,比如按地区分组,只需对编号做group by,只有在需要显示原始字符串值时才做解码,而解码开销远小于IO节省带来的收益,很多情况下,字典编码反而让查询更快,因为数据体积变小,扫描的数据量也减少了。

宽表用列式存储还是行式存储好?

同一条记录整体读写频繁且每次涉及的列很多,行式更顺手;但宽表场景下,分析查询往往只取少数列,列式存储只需读取对应数据块,再叠加字典编码的压缩效果,综合表现远优于行式,多数数据仓库宽表分析场景,列式存储是更合理的选择。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱