ZRANGEBYLEX能做前缀补全因其只按字节比较member字符串本身、不依赖score,但需满足score全为0、member为纯ASCII(中文转拼音)、加统一哨兵前缀(如"+”),且min/max须用"[+ab"和"[+ac"等安全边界构造,否则易漏词错序。
ZRANGEBYLEX 是唯一能做纯前缀字典序扫描的 Redis 命令,但直接用 f"[{prefix}" 和 f"[{prefix}xff" 很容易漏词或错序——关键在 member 设计和边界构造。
它不看 score,只按字节逐个比较 member 字符串本身,天然适合“找所有以 abc 开头的词”。但前提是:
— 所有 member 必须是纯 ASCII 字符串(中文需转拼音首字母,否则 UTF-8 编码排序不可控)
— score 必须完全一致(推荐全设为 0),否则命令行为未定义
— 不能混入空格、控制字符或高位字节开头的字符串(如 u4f60),Redis 按字节比,不是按 Unicode 归一化比
— 如果存了 "user:123" 和 "users",用户输 "user:" 时,"users" 不会被扫到(因为 : 的 ASCII 是 58,s 是 115,"users" > "user:")
别直接存原始词,必须做归一化处理:
— 统一转小写:"Apple" → "apple"
— 去首尾空格:" python " → "python"
— 加统一哨兵前缀(推荐 "+"):"apple" → "+apple",避免空字符串或数字开头词干扰排序
— 不要存所有前缀(如 "a", "ap", "app"),只存完整词,靠 min/max 边界切范围
— 插入命令示例:ZADD autocomplete 0 "+apple" 0 "+application" 0 "+abc"
错误写法:"[ab" 和 "[abxff" —— xff 在某些边界下会越界(比如词本身以 xff 结尾)
正确做法:用哨兵 + 字典序后继字符
— min = "+ab"(左闭,必须带 [)
— max = "+ac"?不行,"abz" 会被漏掉
— 正确 max = "+abxff" 是常用解,但更稳的是用 "[+ab" 和 "[+ac" 配合哨兵设计,确保所有 "ab*" 都落在 [+ab, +ac) 内
— 实际调用:ZRANGEBYLEX autocomplete "[+ab" "[+ac"(注意双引号和方括号都要传)
— 如果没加哨兵,且词含数字或符号,"app" 和 "app2" 可能排错位(2 的 ASCII 是 50,a 是 97)
ZRANGEBYLEX 复杂度是 O(log N + M),看着低,但真到百万级词+每秒千次请求时:
— 返回结果数 M 过大会拖慢整个链路(网络序列化+前端渲染)→ 务必加 LIMIT 0 10
— 没设 EXPIRE 导致内存持续上涨(见过补全库占满 16GB 内存的 case)→ 建议 EXPIRE autocomplete 86400
— 中文场景若不做拼音转换,"北京" 和 "保定" 的 UTF-8 字节序是 E58C97E4 和 E4BFB9E5,排序结果完全不符合语义预期
— 不要用 ZLEXCOUNT 预估再查,它和 ZRANGEBYLEX 是两遍扫描,开销翻倍