杂谈--行数据库与列数据库以及bit-wise索引

行存储,把属于一行的所有列的数据存储在连续的空间即为行存储。

行存储有两个缺点:(1)由于DBMS中磁盘IO的单位是block (oracle中的block大小2K-32K), 如果查询只关心行中的部分列,需要同时读取其它的列,增加了IO;(2)block上的数据类型不一致(多个列的类型可能不一样)使得压缩率低。这两个缺点对数据仓储而言是非常大的限制。

列存储很好的解决了这两个问题。

1. 行存储与列存储的表的组织:

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

下面来看一个例子:

从上图可以很清楚地看到,行式存储下一张表的数据都是放在一起的,但列式存储下都被分开保存了。所以它们就有了如下这些优缺点:

                             

行式存储

列式存储

优点

Ø  数据被保存在一起

Ø  INSERT/UPDATE容易

Ø  查询时只有涉及到的列会被读取

Ø  投影(projection)很高效

Ø  任何列都能作为索引

缺点

Ø  选择(Selection)时即使只涉及某几列,所有数据也都会被读取

Ø  选择完成时,被选择的列要重新组装

Ø  INSERT/UPDATE比较麻烦

注:关系型数据库理论回顾 - 选择(Selection)和投影(Projection)

2补充:数据压缩

刚才其实跳过了资料里提到的另一种技术:通过字典表压缩数据。为了方面后面的讲解,这部分也顺带提一下了。

下面中才是那张表本来的样子。经过字典表进行数据压缩后,表中的字符串才都变成数字了。正因为每个字符串在字典表里只出现一次了,所以达到了压缩的目的(有点像规范化和非规范化Normalize和Denomalize)

3查询执行性能

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

关键步骤如下:

1.     去字典表里找到字符串对应数字(只进行一次字符串比较)。

2.     用数字去列表里匹配,匹配上的位置设为1。

3.     把不同列的匹配结果进行位运算(bit-wise)得到符合所有条件的记录下标。

4.     使用这个下标组装出最终的结果集。

4. bit-wise技术

位图索引在数据存储中是一个非常有用的索引,相比B+树索引而言,位图索引占用的空间极少,且非常适合集合运算,比如count函数。位图索引的缺点是只适用于基数小的列,当列的基数变大以后,位图索引占用的空间非常大。位图索引的另一个缺点是不支持范围查找。

SybaseIQ声称其采用的bit-wise索引解决了位图索引的缺陷,bit-wise索引支持高基数列,且支持范围查找。Sybase为bit-wise技术申请了专利,其专利内容参见《METHOD AND APPARATUSFOR IDNEXING DATABASE COLUMNS WITH BIT VECTORS》。

bit-wise原理

如下图所示,表存在两个列AA和BB。我们现在要在AA上建bit-wise索引。

AA

BB

row1

3

row2

1

row3

2

row4

4

row5

1

 生成索引
●计算bit vector的数量

针对AA列,我们用32bit整数(实际上只需3bit来表达,为了描述更通用的情况,所以用了32bit)来表达AA列上的值,我们需要32个bit vector。

●生成bit-wise索引

如下图所示。bit vector中的位图的数量与表中记录的数量一样。

单值查找

假设我们执行条件为where AA=1的查询。1的二进制表示是{0…0,1},分别与bit-vector执行and运算,结果下图。通过结果bit-vector即可获取目标记录,通过bit-vector进行集合运算也是非常方便的,比如count运算。

范围查找

假设我们执行条件为where AA>1的查询。

1)忽略目标值低位连续为1的位

在本例中我们可以忽略最低位。假如查询的条件为where AA > 11,11的二进制表示为{0…1011},则我们可以忽略最低的2位,即第1位和第2位。

2)从低位开始,依次处理目标值的每个bit

设V1是一个bit-vector,大小是表记录的数量,各个bit的值初始化为0。

从低位开始,依次处理目标值的各个bit。如果bit为0,则把V1和索引进行或操作,把结果写入V1;如果bit为1,则把V1和索引进行与操作,把结果写入V1。

如下图所示。由于第1位([0...001]的第1位)被忽略(R1),所以先处理第2个bit,由于第2个bit为0([0...001]的第2位),所以把V1和索引的第2个bit-vector进行或操作,把结果赋值给V1,见R2;然后处理第3个bit,由于第3个bit为0,把R2与索引的第3个bit-vector执行或操作,把结果赋值给V1,见R3;处理第32位以后,V1的值见RA(最终的R列)。RA中值为1的行记为目标记录,即符合条件where AA>1的行。(实际上是没有各Ri的,只有V1,V1直接和bit-vector直接运算,等所有的bit-vector运算完后,得到的V1,就是最终结果了。)

参考文献:

https://blog.csdn.net/qq_26091271/article/details/51778675

https://blog.csdn.net/liaoxiangui/article/details/80596737 

猜你喜欢

转载自blog.csdn.net/jinking01/article/details/85699532
今日推荐