StarRocks xx_hash32 哈希函数详解:语法、示例与 XXH32 底层实现
【免费下载链接】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
xx_hash32 是 StarRocks 内置的哈希函数之一,基于业界知名的 xxHash 算法家族中的 XXH32(32 位)变体,将任意 VARCHAR 字符串输入映射为一个 32 位有符号整数,常用于数据分桶、去重预筛、随机采样等需要快速、稳定散列的场景。本文以 官方文档 为主体,结合 StarRocks 后端(BE)源码,完整讲解其语法、参数行为、返回类型、多参数组合哈希逻辑、NULL 语义以及与 xx_hash64、xx_hash3_64、murmur_hash3_32 等兄弟哈希函数的选型差异,帮助你在实战中正确、高效地使用该函数。
函数概述
xx_hash32 返回输入字符串的32 位 XXH32 哈希值。它以INT类型(即 StarRocks 中的 32 位有符号整数)返回结果,属于确定性哈希——相同输入在相同环境下必然产生相同输出,因此可以放心用于需要对同一批数据反复计算的场景。
该函数由 StarRocks 官方文档正式收录,其功能定位与项目中 xx_hash64(64 位)、xx_hash3_64(基于 XXH3 算法的 64 位)形成互补,共同构成 StarRocks 的 xxHash 系列哈希函数家族。
语法详解
函数语法定义如下:
INT XX_HASH32(VARCHAR input, ...)要点说明:
| 项目 | 说明 |
|---|---|
| 返回值类型 | INT(32 位有符号整数,值域约为 -2147483648 ~ 2147483647) |
| 参数类型 | VARCHAR,且支持可变参数(...表示可传入一个或多个 VARCHAR 参数) |
| 函数名大小写 | 函数名不区分大小写,xx_hash32与XX_HASH32等价 |
| NULL 语义 | 只要任一参数为 NULL,整体结果即为 NULL(见下文"NULL 处理") |
从源码实现看,函数签名中的可变参数在 BE 侧被实现为接收一个starrocks::Columns容器,逐个参数参与哈希累加计算,具体见 hash_functions.cpp。
参数行为与核心语义
单参数:对单个字符串取 XXH32 哈希
将单个 VARCHAR 字符串作为输入,返回其 XXH32 哈希值。这是最基础的使用方式,适用于单列的分桶键计算或数据打散。
多参数:级联组合哈希
当传入多个 VARCHAR 参数时,StarRocks 会按参数顺序将前一个参数的哈希结果作为后一个参数的种子(seed),形成级联哈希:
- 以默认种子
XXHASH32_SEED(源码中定义为 0,见 hash_util.hpp)开始; - 对第一个参数计算 XXH32,得到中间哈希值;
- 将该中间值作为种子,对第二个参数继续计算 XXH32;
- 依此类推,直到所有参数处理完毕,最终结果即函数返回值。
这一实现细节在 hash_functions.cpp 中有清晰的代码佐证:每一行数据维护一个seeds_vec[row],对每个 viewer(参数列)逐行执行HashUtil::xx_hash32(slice.data, slice.size, seed)并回写新种子。
NULL 处理
- 任一参数为 NULL:整体结果为 NULL;
- 参数列全部为 NULL(如对整列调用且该列全空):同样整体返回 NULL 列。
源码中通过is_null_vec标记位实现:一旦某行任一参数为 NULL,该行的 NULL 标记置位并跳过后续参数的计算,最终由ColumnBuilder<TYPE_INT>统一输出 NULL,见 hash_functions.cpp。
完整示例
以下是官方文档给出的三组典型示例,可以直接在 StarRocks 的 MySQL 兼容客户端中执行验证。
示例一:NULL 输入
MySQL > select xx_hash32(null); +-----------------+ | xx_hash32(NULL) | +-----------------+ | NULL | +-----------------+任一参数为 NULL 时,函数直接返回 NULL。
示例二:单个字符串参数
MySQL > select xx_hash32("hello"); +--------------------+ | xx_hash32('hello') | +--------------------+ | -83855367 | +--------------------+输入字符串hello的 XXH32 哈希值映射为 32 位有符号整数-83855367。注意哈希结果本身是 32 位无符号位模式,但 StarRocks 以有符号INT类型呈现,因此可能表现为负数。
示例三:多个字符串参数
MySQL > select xx_hash32("hello", "world"); +-----------------------------+ | xx_hash32('hello', 'world') | +-----------------------------+ | -920844969 | +-----------------------------+两个参数hello、world级联哈希后结果为-920844969。多参数形式适合对多个列组合取哈希,例如xx_hash32(col_a, col_b)可一次得到两列联合分布的散列值。
实战用法参考
结合示例,可以将该函数应用到真实查询中,例如:
-- 基于字符串列计算分桶键 SELECT xx_hash32(user_id) % 64 AS bucket_id, COUNT(*) FROM user_events GROUP BY bucket_id; -- 对多列联合哈希,实现组合维度打散 SELECT xx_hash32(region, device_type) AS combo_hash FROM events;说明:上述 SQL 仅为常见用法示意,具体取模与分桶策略请结合业务数据分布自行设计。
底层实现与源码级原理
实现入口
xx_hash32 的 BE 侧实现位于 hash_functions.cpp 的HashFunctions::xx_hash32方法,整体流程如下:
- 为每个参数列创建
ColumnViewer<TYPE_VARCHAR>,用于逐行读取字符串值及其 NULL 标记; - 初始化每行的种子向量
seeds_vec为默认值HashUtil::XXHASH32_SEED; - 遍历每个参数列、每一行,跳过已标记为 NULL 的行,对非 NULL 值调用
HashUtil::xx_hash32(data, size, seed)并更新该行种子; - 通过
ColumnBuilder<TYPE_INT>构造结果列,NULL 行输出 NULL; - 若所有输入列均为常量列,则自动折叠为常量列返回(
ColumnHelper::is_all_const优化)。
默认种子
XXH32 算法允许指定自定义种子,StarRocks 将默认种子固定为 0:
static const uint32_t XXHASH32_SEED = 0;定义于 hash_util.hpp。由于种子固定为 0,同一输入的哈希结果在 StarRocks 全局范围内是确定且稳定的,这保证了跨查询、跨批次结果的一致性——这是将其用于数据分桶、Join 前哈希预筛的前提。
与 xx_hash64 / xx_hash3_64 的对比
同样在 hash_functions.cpp 中实现的还有:
| 函数 | 返回类型 | 底层算法 | 默认种子 | 位宽 |
|---|---|---|---|---|
xx_hash32 | INT | XXH32 | 0 | 32 位 |
xx_hash64 | BIGINT | XXH64 | 0 | 64 位 |
xx_hash3_64 | BIGINT | XXH3-64 | 0 | 64 位 |
三者默认种子均为 0(见 hash_util.hpp),区别在于算法版本与输出位宽。官方文档 xx_hash3_64 指出,xx_hash3_64 通过 AVX2 指令集可获得比 murmur_hash3_32 更优的性能与更现代的哈希质量,且该函数自 v3.2.0 起支持。
选型建议:
- 仅需 32 位散列、追求最小结果集占用时,选用
xx_hash32; - 需要 64 位更低冲突概率(如大规模 Join 哈希键、去重场景)时,选用
xx_hash64; - 追求最优性能且环境支持(v3.2.0+)时,优先考虑
xx_hash3_64。
使用注意事项
- 哈希不等于加密:XXH32 是散列函数而非密码学安全哈希,结果可逆性虽差但并非为防碰撞攻击设计,切勿用于安全敏感场景。
- 结果可能为负数:底层 32 位位模式以有符号
INT呈现,大数可能显示为负数,属正常现象。 - NULL 传播:多参数场景下任一参数为 NULL 即整体为 NULL,处理含 NULL 数据时需在 SQL 层面自行兜底(如使用
COALESCE预处理)。 - 分布质量:XXH32 散列分布均匀,适合取模分桶,但取模前建议结合业务基数评估是否会产生倾斜。
相关函数
- xx_hash64:返回 64 位 XXH64 哈希值;
- xx_hash3_64:返回基于 XXH3 算法的 64 位哈希值,性能更优;
- murmur_hash3_32:同属 32 位非加密散列,Seed 默认为 104729,可与 xx 系列按需互换。
延伸阅读
- 函数实现源码:hash_functions.cpp(xx_hash32 及 xx_hash64、xx_hash3_64、xx_hash3_128、murmur_hash3_32 等同源实现)
- 种子常量定义:hash_util.hpp
- xxHash 系列函数文档:
docs/en/sql-reference/sql-functions/hash-functions/目录下xx_hash32.md、xx_hash64.md、xx_hash3_64.md
【免费下载链接】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),仅供参考