数据库索引-位图索引

在学习hive的时候遇到了位图索引,查了查资料。现则很难管理如下,算是个基础知识的了解吧。

一:概念介绍:

百度百科:

  位图索引主要针对大量相同值的列而创建(例如:类别,操作员,部门ID,库房ID等),索引块的一个索引行中存储键值和起止Rowid,以及这些键值的位置编码,位置编码中的每一位表示键值对应的数据行的有无.一个块可能指向的是几十甚至成百上千行数据的位置.

当然百度百科你们懂的。。。来看看wiki的吧

维基百科:

  Bitmap indexes have traditionally been considered to work well for low-cardinality columns, which have a modest number of distinct values, either absolutely, or relative to the number of records that contain the data. The extreme case of low cardinality is Boolean data (e.g., does a resident in a city have internet access?), which has two values, True and False. Bitmap indexes use bit arrays (commonly called bitmaps) and answer queries by performing bitwise logical operations on these bitmaps. Bitmap indexes have a significant space and performance advantage over other structures for query of such data. Their drawback is they are less efficient than the traditional B-tree indexes for columns whose data is frequently updated: consequently, they are more often employed in read-only systems that are specialized for fast query - e.g., data warehouses, and generally unsuitable for online transaction processing applications.

  Some researchers argue that bitmap indexes are also useful for moderate or even high-cardinality data (e.g., unique-valued data) which is accessed in a read-only manner, and queries access multiple bitmap-indexed columns using the AND, OR or XOR operators extensively.

ok ,翻译应该很简单的。

二:示例:

  如果,简介看不懂,来看实例吧:

1.需求描述:

  有张表名为table的表,

由三列组成,分别是姓名、性别和婚姻状况,其中性别只有男和女两项,婚 姻状况由已婚、未婚、离婚这三项,该表共有100w个记录。现在有这样的查询: select * from table where Gender=‘男’ and Marital=“未婚”;

  姓名(Name)  性别(Gender)  婚姻状况(Marital)

    张三       男         已婚

    李四       女         已婚

    王五       男         未婚

    赵六       女         离婚

    孙七       女         未婚

    ...        ...         ...

  1)不使用索引

    不使用索引时,数据库只能一行行扫描所有记录,然后判断该记录是否满足查询条件。

  2)B树索引

    对于性别,可取值的范围只有'男','女',并且男和女可能各站该表的50%的数据,这时添加B树索引还 是需要取出一半的数据, 因此完全没有必要。相反,如果某个字段的取值范围很广,几乎没有重复,比 如身份证号,此时使用B树索引较为合适。事实上,当取出的行数据占用表中大部分的数据时,即使添加 了B树索引,数据库如oracle、mysql也不会使用B树索引,很有可能还是一行行全部扫描。

2. 位图索引出马

  如果用户查询的列的基数非常的小, 即只有的几个固定值,如性别、婚姻状况、行政区等等。要为这些 基数值比较小的列建索引,就需要建立位图索引。

   对于性别这个列,位图索引形成两个向量,男向量为10100...,向量的每一位表示该行是否是男,如果是 则位1,否为0,同理,女向量位01011。

     RowId   1   2   3   4   5

      男    1   0   1   0   0

     女     0   1   0   1   1

  对于婚姻状况这一列,位图索引生成三个向量,已婚为11000...,未婚为00100...,离婚为00010...

    RowId   1   2   3   4   5  

    已婚    1   1   0   0   0

    未婚    0   0   1   0   1

    离婚     0   0   0   1   0

  当我们使用查询语句“select * from table where Gender=‘男’ and Marital=“未婚”;”的时候 首先取出男 向量10100...,然后取出未婚向量00100...,将两个向量做and操作,这时生成新向量00100...,可以发现 第三位为1,表示该表的第三行数据就是我们需要查询的结果。

    RowId   1   2   3   4   5

     男    1   0   1   0   0

  and 未婚     0   0   1   0   1

    结果    0   0   1   0   0

3.位图索引的适用条件

  上面讲了,位图索引适合只有几个固定值的列,如性别、婚姻状况、行政区等等,而身份证号这种 类型不适合用位图索引。

  此外,位图索引适合静态数据,而不适合索引频繁更新的列。

  举个例子,有这样一个字段busy,记 录各个机器的繁忙与否,当机器忙碌时,busy为1,当机器不忙碌时,busy为0。 这个时候有人会说使用位图索引,因为busy只有两个值。好,我们使用位图索引索引busy字段!假 设用户A使用update更新某个机器的busy值,比如update table set table.busy=1 where rowid=100;,但 还没有commit,而用户B也使用update更新另一个机器的busy值,update table set table.busy=1 where rowid=12; 这个时候用户B怎么也更新不了,需要等待用户A commit。 原因:用户A更新了某个机器的busy值为1,会导致所有busy为1的机器的位图向量发生改变,因此 数据库会将busy=1的所有行锁定,只有commit之后才解锁。

资料来源:

  http://www.360doc.com/content/14/0508/15/11965070_375805586.shtml

  https://en.wikipedia.org/wiki/Bitmap_index

  http://baike.baidu.com/link?url=V3bMusSRzP6u-1bBHYDX1WeYs2OAmE9v9KKwmVAwRt_Huk7Ky2QmqXgDbdN5oaZtZgh6rPk740r8r8QN6Jdm6_

原文地址:https://www.cnblogs.com/not-NULL/p/5165709.html