oracle - bitmap算法

生活案例

我们思考一个问题:我们有一堆的球,编号按照从大到小排序,有中、大、小 3 种型号,我们如何快速找到所有的大球?

1、Range 分区

在放球的时候,就已经考虑按照大小,分成 3 堆,大球 1 个分区,中球 1 个分区,小球 1 个分区。

如果是考试,这个回答,看起来不得分,实际应用中,有一定参考价值。

(这样回答不好,是因为要考虑分区容量:如果每一堆只能放100个,我们有400个球,这时候就要考虑新的问题)

2、位图+平衡树

假设第一堆有 8 个球,2 个大球,2 个中球,4 个小球。

  • 大球记为 1,非大球记为 0,得出一串二进制数,1100 0000;
  • 中球记为 1,非中球记为 0,得出一串二进制数,0011 0000;
  • 小球记为 1,非小球记为 0,得出一串二进制数,0000 1111。

我们要找大球,只要看1100 0000这个数字,前面2个是1,所以前面2个球是大球;

我们要找大球或者中球, 1100 0000 与 0011 0000 “按位与” 运算,得出 1111 0000,就能看出,前面4个球满足条件。

很明显,如果我们有无数个球,这个二进制数就会特别长,这时候,我们对算法进一步优化,加入平衡树的算法:

min-m 放一堆,m-n 放一堆,n-max 放一堆,每一堆用一个二进制数表示, 如果 m-n 长度溢出了,就拆分成 m-x, x-n 两堆。

相关内容

bitmap 方式实现 12306 余票分配设计思路与基本算法:

https://zhuanlan.zhihu.com/p/266329767

总结

通过这个案例,再看 Oracle 中的位图索引

1、如果字段只有几个固定的值,比如 “男“、”女”,就很适合创建位图索引;

2、如果一个球漏气,变成小球怎么办?我们要改动 1100 0000 这一串值, 改动数据期间,另一个人也想改数据,这显然会出问题。

所以,1 个人改的时候,8 个球都要锁定,

更新 1 行记录,一下子锁定了 8 行记录,可见 bitmap 更新的成本非常高, 因此,oracle 不推荐在频繁更新的场合,使用位图索引。

posted on 2021-07-26 17:19  疯狂的妞妞  阅读(155)  评论(0编辑  收藏  举报

导航