OceanBase 数据库的高级压缩功能采用全新设计的行列混合存储结构,以及高效的数据编码技术与一系列综合的数据压缩算法结合的方法,实现了在使用相同后端进行压缩的场景下,存储空间大幅减少。
通用压缩
通用压缩指的是在压缩算法对数据内部的结构没有了解的情况下,直接对数据块进行压缩。这种压缩往往是根据二进制数据的特征进行编码来减少存储数据的冗余,并且压缩后的数据不能随机访问,压缩和解压都要以整个数据块为单位进行。对数据块的压缩,OceanBase 数据库支持 zlib、snappy、lz4 和 zstd 四种压缩算法,zstd 和 lz4 的压缩等级是 1,zlib 的压缩等级为 6,snappy 使用默认的压缩等级。在 OceanBase 数据库内部对默认16 KB 大小的微块进行压缩的测试中,snappy 和 lz4 压缩速度都比较快,但压缩率比较低,zlib 和 zstd 压缩率比较高但是压缩速度更慢一些。lz4 和 snappy 的压缩率相似但 lz4 压缩解压的速度会更快一些,同样,zstd 的压缩率与 zlib 相似但压缩解压速度都更快。
支持用户指定单独选择 zlib、snappy、lz4 或 zstd 压缩算法。
数据编码
在通用压缩的基础上,OceanBase 数据库自研了一套对数据库进行行列混存编码的压缩方法(encoding)。和通用压缩不同,Encoding 建立在压缩算法感知数据块内部数据的格式和语义的基础上。OceanBase 数据库是一个关系型数据库,数据是以表的形式来组织的,表中的每一列都有固定的类型,这就保证了同一列数据在逻辑上存在着一定的相似性;而且在一些场景下,业务的表中相邻的行之间数据也可能会更相似,所以如果将数据按列进行压缩并存储在一起就可以带来更好的压缩效果。因此 OceanBase 数据库引入了一种 encoding 格式的微块。与所有数据逐行序列化到块中的 flat 格式的微块不同,encoding 格式的微块是行列混存的,逻辑上仍然是一组行的数据存在微块里,但微块会按列对数据进行编码,编码后的定长数据存储在微块内部的列存区,部分变长数据还是按行存储在变长区。并且在 encoding 微块中,数据是可以随机访问的,当需要读取微块中的某一行数据时,可以只对这一行数据进行解码,避免了有些解压算法读一部分数据需要解压整个数据块的计算放大;在向量化执行的过程中也可以对指定的列进行解码,降低了投影的开销。
OceanBase 数据库在对数据进行分析的过程中,会选择合适的编码算法。当前,OceanBase 数据库支持多种数据编码技术,比较常见且有效的几种编码方式如下:
字典编码
将基数(Cardinality)较小的数据进行去重,再把去重后的数据建立成字典,而将原来存放数据的地方存为指向特定字典下标的引用。此外,字典中的各数据按类型排序,这样既有利于数据压缩,也可以在计算时直接将谓词下压到字典上,通过二分逻辑完成快速迭代。
游程编码(Run-Length Encoding)或 RLE 编码
对于连续相等的数据,例如:100,100,100,120,120,120,150,150,......,将连续的数据去重,仅保留其起始行号和值。
RLE 编码在数据库中通常用于处理基数较低的连续数据,例如,索引前缀和索引后缀等。
整型差值编码(Delta Encoding)
数值型编码,适用于在一个小值域范围内分布的整数型数据,通过计算区间内的最小值和最大值,然后将数据减去最小值后,用更小的位宽进行编码。
常量编码
编码识别一个最常见的数据作为常量,只记录所有不等于这个常量的异常值和它们的行号。
除此以外,OceanBase 数据库还提供了字符串前缀编码(Prefix Encoding)、十六进制编码(Hex Encoding)、列间等值编码(Column Equal Encoding)、列间子串编码(Column SubString Encoding)等多种编码方式。OceanBase 数据库会在合并时根据数据的特点选择合适的编码类型,并计算数据的压缩比,如果发现压缩比不高,会尽快回退,选择其他的编码方式,从而确保数据编码的过程不会影响正常的数据写入性能。如果您对数据的特点非常了解,您也可以在创建表时,手动指定编码方式。
更多信息
更多数据压缩与数据编码的介绍信息,请参见 压缩与编码。




