StarRocks base64_to_bitmap 函数详解:把 Base64 序列化 Bitmap 高效导入 BITMAP 列
2026/9/17 11:55:40 网站建设 项目流程

StarRocks base64_to_bitmap 函数详解:把 Base64 序列化 Bitmap 高效导入 BITMAP 列

【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks

base64_to_bitmap是 StarRocks 提供的 Bitmap 族函数之一,用于将经过序列化并编码为 Base64 字符串的 Bitmap 数据还原为 BITMAP 类型,是 Stream Load / Broker Load 等导入链路中向 BITMAP 列装载数据的关键转换函数。读完本文,你将掌握该函数的语法、底层执行原理(含常量折叠优化与异常处理路径),并能够独立完成「序列化 Bitmap → Base64 编码 → 导入 → 查询」的完整实战流程。该函数自 StarRocks v2.3 起支持。

函数定位:为什么需要 base64_to_bitmap

StarRocks 的 BITMAP 类型常用于精确去重计数(如 UV 统计)场景。BITMAP 是一个二进制对象,无法以可读文本的形式直接写入导入文件,因此在导入之前,需要先在客户端(Java 或 C++ 程序)中构造BitmapValue对象、添加元素、序列化,并将序列化结果编码为 Base64 字符串;待 Base64 字符串进入 StarRocks 后,再用base64_to_bitmap将其还原为 BITMAP 数据落库。

整个过程对应两条链路:

  • 序列化方向:BitmapValue→ 序列化字节 → Base64 字符串(对应逆函数 bitmap_to_base64 与to_base64类函数);
  • 还原方向:Base64 字符串 →base64_to_bitmap→ BITMAP 列(本文主角)。

语法与参数

BITMAP base64_to_bitmap(VARCHAR bitmap)

参数说明

参数类型说明
bitmapVARCHAR传入的 Base64 字符串。它必须是由 BitmapValue 对象序列化后再经 Base64 编码得到的合法内容,而不是任意 Base64 文本。

返回值

返回 BITMAP 类型值。若入参为NULL、空字符串、非法 Base64 或解码后无法反序列化为合法 Bitmap,则根据执行环境返回NULL或抛出错误(详见下文「异常与边界处理」)。

底层实现:从 Base64 到 BitmapValue 的两步还原

base64_to_bitmap的向量化实现在 be/src/exprs/bitmap_functions.cpp,核心逻辑可以拆解为两层:

  1. Base64 解码:调用base64_decode2将 VARCHAR 输入解码为原始二进制字节;
  2. Bitmap 反序列化:调用BitmapValue::valid_and_deserialize(定义于 be/src/types/bitmap_value.h 与 be/src/types/bitmap_value.cpp)校验并还原为内存中的BitmapValue对象。

函数内部针对「常量列」与「普通列」提供了两条执行路径,并配套prepare/close生命周期钩子,见 be/src/exprs/bitmap_functions.h:

  • 常量快路径(const path)base64_to_bitmap_prepareFRAGMENT_LOCAL阶段检查第 0 列是否为常量列;若是,则在prepare只解码一次并缓存Base64ToBitmapState,随后base64_to_bitmap_const对所有行复用同一 Bitmap,避免逐行重复解码(对应测试 bitmap_functions_test.cpp);
  • 通用路径(general path):对非常量列逐行调用ColumnViewer读取 VARCHAR 值,逐行解码、反序列化,遇到空值或解码失败行则append_null()
  • 资源回收base64_to_bitmap_close负责释放prepare阶段分配的Base64ToBitmapState,防止状态泄漏。

从行级行为看,base64_to_bitmap_general对每一行执行如下判断(bitmap_functions.cpp):

  • 行为NULL→ 结果为NULL
  • 行为空字符串 → 结果为NULL
  • base64_decode2返回负值(非法 Base64)→ 结果为NULL
  • valid_and_deserialize失败 → 若allow_throw_exception()为真则抛出base64_to_bitmap: failed to deserialize bitmap: ...RuntimeError(错误信息中截取输入前 200 字符辅助排查),否则该行置NULL

因此,保证写入导入文件的是「合法序列化 + 合法 Base64」的内容,是使用该函数的前提。

前置准备:如何生成合法的 Base64 输入

参数文档要求在使用base64_to_bitmap之前,先用 Java 或 C++ 构造BitmapValue对象、添加元素、序列化并 Base64 编码。C++ 侧的BitmapValue支持三种内部存储形态,反序列化时valid_and_deserialize均能正确还原(对应测试见 bitmap_functions_test.cpp 的bitmapToBase64Test):

  • 空 Bitmap:基数 0,往返转换后cardinality()仍为 0;
  • Set 形态:逐个 add 不超过 32 个元素时按集合存储(如{1,2,3,4});
  • 32bit / 64bit 位图形态:使用向量或大整数构造时进入位图存储(如{600123456781, 600123456782, ...}等 64 位值)。

由于bitmap_to_base64base64_to_bitmap互为逆运算,一个简单可靠的生成方式是:先在 StarRocks 内用bitmap_to_base64对合法 Bitmap 求值得到标准 Base64 样例,再将其写入导入文件——测试bitmapToBase64Test正是采用「先bitmap_to_base64base64_to_bitmap」的往返断言来验证二者一致性的。

注意:base64_to_bitmap要求输入是BitmapValue 序列化字节的 Base64 编码,而不是任意字符串的 Base64 编码。把一段普通文本 Base64 化后传入,会因反序列化校验失败而得到NULL或报错。

实战:Stream Load 导入 JSON 中的 Base64 Bitmap

以下完整示例来自函数文档,演示「建表 → Stream Load 导入 → 查询」三步流程。相关导入语法可参阅 STREAM_LOAD。

1. 创建数据库与 Bitmap 表

以下示例创建一个以tagnametagvalue为主键的 Primary Key 表,其中userid列为 BITMAP 类型,用于存储用户 ID 集合:

CREATE database bitmapdb; USE bitmapdb; CREATE TABLE `bitmap_table` ( `tagname` varchar(65533) NOT NULL COMMENT "Tag name", `tagvalue` varchar(65533) NOT NULL COMMENT "Tag value", `userid` bitmap NOT NULL COMMENT "User ID" ) ENGINE=OLAP PRIMARY KEY(`tagname`, `tagvalue`) COMMENT "OLAP" DISTRIBUTED BY HASH(`tagname`) PROPERTIES ( "replication_num" = "3", "storage_format" = "DEFAULT" );

2. 准备 JSON 数据文件

假设本地存在 JSON 文件simpledata,其中userid字段是 BitmapValue 序列化后的 Base64 字符串:

{ "tagname": "Product", "tagvalue": "Insurance", "userid":"AjowAAABAAAAAAACABAAAAABAAIAAwA=" }

3. 通过 Stream Load 导入并在 columns 映射中调用函数

使用curl发起 Stream Load,核心在于-H "columns: ..."中用base64_to_bitmap(c3)将 JSON 中的第 3 个字段(Base64 字符串)转换为 BITMAP 值:

curl --location-trusted -u <username>:<password>\ -H "columns: c1,c2,c3,tagname=c1,tagvalue=c2,userid=base64_to_bitmap(c3)"\ -H "label:bitmap123"\ -H "format: json"\ -H "jsonpaths: [\"$.tagname\",\"$.tagvalue\",\"$.userid\"]"\ -T simpleData http://host:port/api/bitmapdb/bitmap_table/_stream_load

其中jsonpaths按 JSON 字段顺序把tagnametagvalueuserid分别映射为c1c2c3,再经columns完成「字段 → 列」的最终映射。<username>:<password>替换为实际账号,host:port替换为 FE 的 HTTP 服务地址。

4. 查询验证

导入完成后,使用bitmap_to_string把 BITMAP 还原为逗号分隔的 ID 列表进行验证:

mysql> select tagname,tagvalue,bitmap_to_string(userid) from bitmap_table; +--------------+----------+----------------------------+ | tagname | tagvalue | bitmap_to_string(`userid`) | +--------------+----------+----------------------------+ | Product | Insurance | 1,2,3 | +--------------+----------+----------------------------+ 1 rows in set (0.01 sec)

查询结果中的1,2,3表明:JSON 里AjowAAABAAAAAAACABAAAAABAAIAAwA=解码还原出的 Bitmap 包含用户 ID 1、2、3,导入链路完全打通。

异常与边界处理速查

结合函数源码 bitmap_functions.cpp 与常量路径的专项测试 base64ToBitmapConstNullHandling,各边界行为总结如下:

输入情形行为
NULL返回NULL
空字符串''返回NULL
非法 Base64(如!!!invalid_base64!!!返回NULL
Base64 合法但被截断(末组不完整,无法反序列化)返回NULLallow_throw_exception开启时报错)
合法 Base64 但非 BitmapValue 序列化内容反序列化失败,返回NULL或报错
合法且完整的 Bitmap 序列化 Base64返回对应 BITMAP(含空 Bitmap、Set、32bit、64bit 各形态)

从测试用例可以看到,常量路径与通用路径对上述非法输入的行为保持一致,均产出NULLonly_null()列),确保导入任务不会因个别脏数据整批失败——实际导入时建议结合bitmap_to_string等函数对结果做抽样校验。

延伸:同一函数族的配套能力

  • bitmap_to_base64base64_to_bitmap的逆函数,将 BITMAP 序列化并 Base64 编码为 VARCHAR,实现见 bitmap_functions.cpp,可用于导出数据或生成可复用的 Base64 样本;
  • bitmap_to_string:将 BITMAP 转为1,2,3形式的可读字符串,是验证导入结果最直观的手段;
  • Hive UDF 参考实现:仓库在 UDFBase64ToBitmap.java 中提供了GenericUDF风格的 Java 参考实现,通过java.util.Base64解码字符串并返回字节数组,展示了「客户端侧 Base64 解码 + 服务端反序列化」协作模型的 Java 侧写法;
  • 向量化测试覆盖:完整行为契约可在 bitmap_functions_test.cpp 的bitmapToBase64Testbase64ToBitmapConstNullHandlingbase64ToBitmapNonConst等用例中找到,它们是理解该函数边界语义的权威参考。

总结

base64_to_bitmap打通了「外部系统序列化 Bitmap → Base64 文本 → StarRocks BITMAP 列」的数据通路,是精确去重场景下导入用户 ID 集合等位图数据的标准入口。使用时务必牢记:输入必须是BitmapValue序列化字节的 Base64 编码;导入侧通过 Stream Load 的columns映射即可完成转换;查询侧用bitmap_to_string即可验证还原结果。其 BE 端实现通过常量快路径与通用路径的分离、valid_and_deserialize的严格校验,在保证性能的同时对脏数据提供了稳健的兜底行为。

【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询