这篇文章主要分享存储模型和数据压缩
DATABASE WORKLOADS
DATABASE WORKLOADS分为以下三类
- OLTP: 针对每次写入/更新小批量数据有较好的性能表现
- OLAP: 主要针对读取大量数据进行聚合等复杂查询的场景
- HTAP: 结合OLTP和OLAP的特性于一体
OLAP偏向于复杂查询以及读场景更多
OLTP偏向于简单查询和写场景更多
STORAGE MODELS
DBMS中的STORAGE MODELS是用来管理和组织存储在磁盘和内存中的tuples。主要有以下三种方式:
- N-ary Storage Model (NSM)
- Decomposition Storage Model (DSM)
- Hybrid Storage Model (PAX)
N-ary Storage Model (NSM)
NSM就是我们所说的行存储,DBMS把每个tuple中的所有属性连续的存储在一个Page中。
这样的存储方式对于OLTP这种写操作较多且通常只访问独立的entities来说是非常理想的。
但对于OLAP场景来说,通常只对指定的几个列做分析,这样会导致读取很多无效的数据,从而影响查询的效率。
对于NSM模型,优缺点如下:
Decomposition Storage Model (DSM)
DSM就是我们常说的列存储,在DSM中,DBMS把所有tuples的每个列单独连续的存储在Page中。每个列都维护单独的文件进行存储。
这种存储方式有利于OLAP这种读场景较多且会对某些列进行大量查询的场景
在OLAP场景下,针对某个列进行过滤或聚合时,则只需要读这个列所在的Page就行。
优缺点如下:
PAX STORAGE MODEL
PAX是一种混合存储模型,在每个Page中垂直区分保存表的每个属性。
采用这种模型的目的是为了既能获得列存的快速处理的高性能又能获得行存的空间本地性优势。
Paraquet and Orc都是采用的这种模式
DATABASE COMPRESSION
对于数据库来说,从磁盘中读取数据的IO是主一个主要的瓶颈点。因此DBMS可以对数据进行压缩来提高每次IO的数据利用率。压缩的颗粒度主要有以下四种选择:
- Block-level: 同一张表中一定数量的数据作为压缩块
- Tuple-level: 压缩每个Tuple的全部内容
- Attribute-level: 压缩每个tuple中的单个属性
- Column-level: 将每一列作为一个压缩单元。不同列的数据分别进行压缩,并以列为单位存储在数据库
COLUMNAR COMPRESSION
与传统的行式存储相比,列式压缩在数据库系统中广泛应用,因为它可以显著减少存储空间占用并提高查询性能。主要有以下几种方式:
RUN-LENGTH ENODING
RUN-LENGTH ENODING 是一种简单而有效的压缩算法,特别适用于连续重复值较多的数据。它的基本思想是将连续出现的相同值替换为一个计数值和该值本身,从而减少重复值的存储空间。例如,一个连续的重复序列 "AAAAA" 可以用 "5A" 表示,大大减少了存储空间。RLE 在处理压缩数据时非常高效,并且对于有较多连续重复值的数据可以获得较高的压缩比。
BIT-PACKING ENCODING
Bit-Packing Encoding 是一种用于处理二进制数据的压缩技术。它将数据按照位(bit)的方式进行打包和存储。通常,数据元素的位数不是固定的,因此使用 Bit-Packing Encoding 可以将不同位数的数据元素紧密地打包在一起,减少存储空间。例如,如果数据元素的有效位数为 4 位,那么每个数据元素只占用 4 位的存储空间。Bit-Packing Encoding 在处理位数较小且相对均匀分布的数据时效果显著,可以获得很高的压缩比。
具体实例如下图
BITMAP ENCODING
对于一个列数据,针对每个不同的取值创建一个位图。位图是一个二进制向量。这样占用的空间就会比之前减少了很多。
示例如下,原本每个值需要占用8个bits,总的需要72bits, 转换成位图后,每个位图只占用2bits, 总的就是2x9加上原始数据2x8 等于34bits
DELTA ENCODING
Delta Encoding主要用于存储连续的数值或顺序数据。主要基于以下原理:
- 差值计算:Delta Encoding 使用当前值与前一个值之间的差异来表示数据。相邻值之间的差异通常较小,可以使用较少的位数来存储这些差异。
- 增量存储:不需要存储原始的数值或数据,Delta Encoding 存储数据序列中的第一个值,然后存储后续值与前一个值之间的差异。这样可以减少存储空间,并且可以通过前一个值和差异重新构建原始数据。
和RUN-LENGTH ENODING结合一起使用可以有更好的压缩比例
DICTINARY COMPRESSION
DICTINARY COMPRESSION主要是用更小的代码来替换原始数据,基本原理为:
- 创建字典:对于要进行压缩的数据集,首先创建一个字典。字典中维护原始值和一个比较小的固定长度的代码之间的映射关系。
- 替换重复值:遍历数据集,对于每个值,检查其是否已存在于字典中。如果存在,将其替换为对应的代码。如果不存在,将该值添加到字典,并使用新的代码替换数据集中的值。
Conclusion
对于不同的workload来说选择正确的存储模型是很重要的,比如对于OLTP来说就使用行存储,OLAP场景使用列存。
DBMS可以组合不同的压缩方式来获得更好的压缩效果。DICTINARY COMPRESSION可能是最好使的方式,因为他不需要对数据进行预先排序。