druid.io 1---列式存储概念

应用场景

  • OLTP类型的查询访问的行数比较少,但往往需要大部分的数据列。传统的行式数据库将一个个完整的数据行存储在数据页中。这种方式在磁盘IO上是比较高效的。
  • OLAP类型的查询可能需要访问几百万甚至几十亿个数据行,数据量大需要进行压缩,且往往只关心少数几个数据列。这种情况下就需要列式存储。列式存储每一列单独存储,并且同一列里面的数据类型基本是相同,天生适合压缩。

当然,列式数据库不是万能的,每次读取某个数据行时,需要分别从不同的地方读取各个数据列的值,然后合并在一起形成数据行。因此,如果每次查询涉及的数据量较小或者大部分查询都需要整行的数据,列式数据库并不适用。

列式存储vs行式存储

简单来说两者的区别就是如何组织表,具体区别如下:

对比项 行式存储 列式存储
存储 每一行数据作为一个整体来存储 每一列数据作为一个整体来存储
存储顺序 把一行中的数据值串在一起存储起来,然后再存储下一行的数据 把一列中的数据值串在一起存储起来,每列存储的位置分开
插入/更新 只需对一行进行操作,相对容易 需要对多个列进行操作,相对麻烦
索引 对个别列建立索引 任何列都能作为索引
查询 选择(Select)即使只涉及某几列,所有数据会被读取,存在冗余列 查询时只有涉及到的列会被读取,被选择的列要重新组装
查询适合场景 随机查询 范围查询(聚合)
应用 OLTP OLAP

从下图可以很清楚地看到,行式存储下一张表的数据都是放在一起顺序保存的,但列式存储下都被分开保存了。

image

数据压缩

列式存储天生就是适合压缩,因为同一列里面的数据类型基本是相同。经过字典表进行数据压缩后,表中的字符串才都变成数字了。正因为每个字符串在字典表里只出现一次了,所以达到了压缩的目的。

image

查询性能

通过一条查询的执行过程说明列式存储(以及数据压缩)的优点,下图为:

1
select * from table where Customer Name = 'Miller' and Materiral = 'Refrigerator'

image

关键步骤如下:

  • 去字典表里找到字符串对应数字(只进行一次字符串比较)。
  • 用数字去列表里匹配,匹配上的位置设为1。
  • 把不同列的匹配结果进行位运算得到符合所有条件的记录下标。
  • 使用这个下标组装出最终的结果集。

索引优化

可以针对列式存储做专门的索引优化。比如,性别列只有两个值,“男”和“女”,可以对这一列建立位图索引:

image

“男”对应的位图为100101,表示第1、4、6行值为“男”;“女”对应的位图为011010,表示第2、3、5行值为“女”。如果需要查找男性或者女性的个数,只需要统计相应的位图中1出现的次数即可。另外,建立位图索引后0和1的重复度高,可以采用专门的编码方式对其进行压缩。

参考

http://blog.csdn.net/dc_726/article/details/41143175
http://chattool.sinaapp.com/?p=1234

文章目录
  1. 1. 应用场景
  2. 2. 列式存储vs行式存储
  3. 3. 数据压缩
  4. 4. 查询性能
  5. 5. 索引优化
  6. 6. 参考
|