HEX()按输入类型不同转换:字符串逐字节转两位十六进制,整数转无符号十六进制;UNHEX()严格要求偶数长度、仅含0-9/A-F的字符串,且返回二进制值。

HEX() 函数怎么把字符串或数字转成十六进制
HEX() 的行为取决于输入类型:传入字符串时,它逐字节转为两位十六进制(如 'A' → '41');传入整数时,则直接转为该整数的无符号十六进制表示(如 255 → 'FF')。注意:MySQL 严格区分类型,HEX(255) 和 HEX('255') 结果完全不同——前者是 'FF',后者是 '323535'(因为字符 '2'、'5'、'5' 的 ASCII 码分别是 32、35、35)。
常见误用场景:
- 想把 ID 字段(INT 类型)转成固定长度十六进制用于短链,但没意识到
HEX(id)不补零,1得到'1'而非'0001' - 对中文字段用
HEX()后发现结果很长,其实是 UTF-8 多字节编码导致(如'你好'→'E4BDA0E5A5BD'),不是函数出错
UNHEX() 只接受偶数长度的十六进制字符串
UNHEX() 是 HEX() 的逆操作,但它非常严格:输入必须是偶数长度、只含 0-9 和 A-F(不区分大小写)的字符串。一旦长度为奇数,比如 UNHEX('ABC'),MySQL 直接报错 ERROR 1416 (22003): Cannot get geometry object from data you send to the GEOMETRY field(这个错误信息很误导,实际是长度校验失败)。
安全使用建议:
- 用
LENGTH(hex_str) % 2 = 0先判断再调用UNHEX() - 从外部系统接收 hex 数据时,最好用
UPPER()+TRIM()预处理,避免空格或小写引发兼容问题 -
UNHEX()返回的是二进制字符串(BINARY类型),如果要转回可读文本,需配合字符集转换,例如CONVERT(UNHEX('E4BDA0') USING utf8mb4)
HEX() 和 UNHEX() 在 WHERE 条件中慎用索引
在 WHERE 子句里对字段套 HEX()(如 WHERE HEX(name) = '414243')会导致全表扫描——因为函数改变了原始列值,无法命中 name 上的索引。同理,WHERE id = UNHEX('FF') 也不行,类型不匹配(UNHEX() 返回 VARBINARY,而 id 是 INT)。
更高效的做法:
- 需要按 hex 形式查询整数 ID?改用
WHERE id = 255,而不是反向转换 - 真要存 hex 表示(如 UUID 存储优化),建议新增一个生成列:
hex_id VARCHAR(16) AS (HEX(id)) STORED,并给它建索引 - 模糊搜索 hex 内容?优先考虑正则或前缀匹配,避免在 WHERE 中实时计算
HEX() 结果长度不固定,UNHEX() 对空值和 NULL 敏感
HEX(NULL) 返回 NULL,但 UNHEX(NULL) 也返回 NULL;而 UNHEX('')(空字符串)会返回空二进制值(''),不是 NULL。这在 JOIN 或聚合时容易引发意外结果——比如用 UNHEX() 做关联键,空字符串和 NULL 就不会被当成同一类。
实际开发中要注意:
- 数据库字段允许 NULL 时,
HEX(col)查询结果可能混有NULL,前端解析需判空 - 批量导入 hex 数据前,用
WHERE hex_col REGEXP '^[0-9A-F]{2,}$'过滤非法格式,比等运行时报错更可控 - MySQL 8.0+ 支持 CHECK 约束,可加
CHECK (LENGTH(hex_col) % 2 = 0 AND hex_col REGEXP '^[0-9A-F]*$')防脏数据入库
HEX/UNHEX 看似简单,但类型隐式转换、索引失效、空值语义这些点,线上出问题时往往查半天才定位到根源。










