clickhouse在20以后的版本支持數(shù)據(jù)列為64位的壓縮位圖
內(nèi)部實際類型為Roaring64NavigableMap,具體可參考https://github.com/RoaringBitmap/CRoaring
1、如何建表
只需要設置列的類型為 AggregateFunction(groupBitmap,UInt64) 即可
例:
CREATE TABLE test.bitmapdemp
(
bit AggregateFunction(groupBitmap,
UInt64)
)
...
2、數(shù)據(jù)如何寫入
通常是明細表進行轉(zhuǎn)換,通過groupBitmapState對某offset字段進行分組合并
groupBitmapState(offset) AS bit
3、位圖之間是否可以進行計算
位圖之間可以進行與或非等計算,具體可參考官方文檔
4、位圖與明細表進行join
也就是要從明細表中查出offset 在該位圖里的明細數(shù)據(jù)
SELECT offset FROM 明細表 WHERE offset IN (SELECT bitmapToArray(bit) FROM 位圖表 WHERE ...)
5、位圖數(shù)據(jù)導出
把位圖轉(zhuǎn)成一張?zhí)摂M表的一列來通過ResultSet讀出
SELECT arr AS offset FROM (SELECT bitmapToArray(bit) as arr FROM 位圖表 WHERE ... LIMIT 1) ARRAY JOIN arr
6、如何把位圖寫入ck
String sql = "INSERT INTO bitmap.crowd(crowd_code, crowd_version, offset_bitmap) VALUES(?, ?, ?)";
try{
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, crowdCode);
pstmt.setString(2, version);
Roaring64NavigableMap bitmap = new Roaring64NavigableMap();
bitmap.add(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
ClickHouseBitmap wrap = ClickHouseBitmap.wrap(bitmap, ClickHouseDataType.UInt64);
pstmt.setObject(3, wrap);
pstmt.execute();
}catch (Exception e){
e.printStackTrace();
}
7、查詢分布式表里的bitmap,合并成一個數(shù)組
SELECT COUNT(arrayJoin(bitmapToArray(offset_bitmap))) AS arr FROM test.bitmap_dist PREWHERE xxx;
8、從詳情表查詢數(shù)據(jù)構(gòu)建成一個bitmap
SELECT bitmapBuild(groupArray(offset)) AS bitmap FROM ...
測試發(fā)現(xiàn)
SELECT bitmapBuild(groupArray(offset)) 改成SELECT
bitmapBuild(groupArrayDistinct(offset)) 性能提高非常顯著