BitMap
位图又称点阵图, 在索引、数据压缩等广泛使用
1 byte = 8 bit
应用场景1 - 不重数字排序
比如: 1,7,3,5,2 进行排序, 只需要用 `1 byte` 即 `0 1 1 1 0 1 0 1`
Q&A:10亿不重复的数值怎么排序?
2的32次方 = 4294967296 (512M的bitmap)
Redis BitMap
redis 中提供了类似的命令,最大可存放 2的32次方个数字。`setbit`, `getbit`, `bitcount`, `bitop` `bitfield`
- bitop 有四种操作符即:AND、OR、NOT、XOR
应用场景2 - 每日签到
存储用户签到可用`setbit 20200114 UID 1` (UID为bitmap的offset)
offset为2的32次方(分配512 M)。
统计签到人数: `bitcount 20200114`即可。
统计多天签到:`bitop AND N_days_sign_key 20200114 20200113 20200112`
ClickHouse BitMap
clickhouse 提供了用于两个位图对象进行计算的函数,对任何一个位图函数,返回的是一个位图对象。当基数小于32时,用Set保存。当基数大于32时,用RoaringBitmap保存。
- bitmapBuild - 位图创建函数
SELECT bitmapBuild([1, 2, 3, 4, 5])Query id: 44b4230f-3b16-43fe-91b8-855e8e3177c6┌─bitmapBuild([1, 2, 3, 4, 5])─┐│ │└──────────────────────────────┘
- bitmapToArray - 把位图转化为整形数组
SELECT bitmapToArray(bitmapBuild([1, 2, 3, 4, 5])) AS resQuery id: 778f00e1-9af2-4234-bd76-3916d3648175┌─res─────────┐│ [1,2,3,4,5] │└─────────────┘
- bitmapContains - 检查位图是否包含指定元素
SELECT bitmapContains(bitmapBuild([1, 5, 7, 9]), toUInt32(9)) AS resQuery id: 88027d6f-d1b7-4673-a1cb-7ec9ff7b72dd┌─res─┐│ 1 │└─────┘
- bitmapHasAny - 位图有公共元素则返回1 否则返回0
- bitmapHasAll - 第一个位图是否包含第二个
- bitmapAnd - 位图与运算
SELECT bitmapToArray(bitmapAnd(bitmapBuild([1, 2, 3]), bitmapBuild([3, 4, 5]))) AS resQuery id: 28ad9bc1-b0c4-4879-b201-d8e4a3469ca1┌─res─┐│ [3] │└─────┘
- bitmapOr - 或运算
- bitmapXor - 异或运算
应用场景3 - 留存分析
查询`2020-12-01`号注册的用户后面几天的留存情况,如下:
SELECT openid, retention((logday = '2020-12-01') AND (ename = 'registe'), (logday = '2020-12-02') AND (ename = 'login'), (logday = '2020-12-03') AND (ename = 'login'), (logday = '2020-12-15') AND (ename = 'login')) AS rFROM t_event_logWHERE logday IN ('2020-12-01', '2020-12-02', '2020-12-03', '2020-12-15')GROUP BY openidHAVING (r[2]) = 1LIMIT 10Query id: 2a8701b9-1307-43b2-b884-c7ff989ee1d6┌─openid─────────────────────────────┬─r─────────┐│ oVvSI5OFyiGCzgKA6Mg7T4jw1RL8 │ [1,1,0,0] ││ o70Pe4sO2fjGedFdbBnZdJdk3wpg │ [1,1,0,0] ││ 6E275AE67AAC855E767199494EA27B25** │ [1,1,1,0] ││ o4Mvk5CXLh6a1_gYGYUSEOvSyFuo │ [1,1,0,0] ││ o7VmR4tyCpvCUivYNaf47YPwE3_g │ [1,1,1,0] ││ o70Pe4rzjoICTzgcWPjTGv7MrRHk │ [1,1,1,0] ││ o70Pe4iFP1jEyYkcBxcl-3VYU0Rw │ [1,1,1,0] ││ 08A477275FD15BAAF5C1A494136E441F │ [1,1,0,0] ││ oFHpu5fByQeE6jLAU_da2SnaCYjw │ [1,1,0,0] ││ oFHpu5Rq6j0Xw8PKh5JIL9idY3hY │ [1,1,1,0] │└────────────────────────────────────┴───────────┘