sql分库分表中全局id需满足唯一、趋势递增、无冲突,主流方案是snowflake(64位时间戳+机器id+序列号,依赖时钟且需容错)、号段模式(db批量预取,连续性强但有单点风险)及时间前缀混合方案(适合展示id,不推荐主键);伪方案如db偏移、uuid、redis单key自增均存在扩容、性能或可靠性缺陷。

在 SQL Sharding(分库分表)架构中,全局序列和跨库 ID 唯一性是核心难点。单库自增主键失效后,必须引入外部或分布式机制来生成全局唯一、趋势递增、无冲突的 ID。关键不在于“有没有方案”,而在于选型是否匹配业务吞吐、时钟敏感度、运维复杂度和容错要求。
基于雪花算法(Snowflake)的分布式 ID 生成器
这是目前最主流的方案:将 64 位 long 拆分为时间戳(41bit)+ 机器 ID(10bit)+ 序列号(12bit),天然支持毫秒级有序、分布式无中心协调。
- 需自行部署 ID 服务集群(如用 Twitter 的 snowflake 改造版、美团 Leaf、百度 UidGenerator),每个实例分配唯一 workerId
- 依赖系统时钟——时钟回拨会导致 ID 重复或服务拒绝发号,建议启用时钟监控 + 容错降级(如等待/抛异常/切换备用节点)
- 生成的 ID 是数字,可直接作主键,但长度固定(64 位),且高位时间戳导致数值“不连续”,对范围查询友好度略低
数据库号段模式(Segment Mode)
以“批量预取 + 本地缓存”降低 DB 访问频次,兼顾性能与简单性。典型实现如美团 Leaf-segment、滴滴 TinyID。
- 中心数据库维护一张 sequence 表,字段含 biz_tag(业务标识)、max_id(当前最大已发 ID)、step(每次取号数量,如 1000)
- 应用启动时请求一个号段(如 [100001, 101000]),缓存在内存中逐个分配;用完再同步更新 max_id 并取下一段
- 单点 DB 成为瓶颈?可通过多 tag 分库、读写分离、或双 sequence 表热备缓解;ID 连续性强,适合分页/排序场景
混合逻辑:时间前缀 + 随机/自增后缀
适用于对严格单调性要求不高、但需避免 ID 泄露业务量的场景(如对外展示订单号、短链 ID)。
- 例如:20240520_872391 → 时间部分保证大致有序,后缀由本地线程安全计数器或 DB 表 per-day 自增生成
- 需注意后缀位数上限(如每天最多 100 万单,则后缀至少 6 位),并设计日期切换逻辑(避免午夜并发重置错误)
- 不推荐用于主键——因字符串索引效率低、无法做范围扫描、且跨天 ID 不保序
禁止使用的“伪方案”与常见陷阱
有些做法看似简单,实则埋雷:
- DB 自增 + 库/表偏移:如库 0 的 ID 加 0,库 1 的 ID 加 1000 万——扩容时无法平滑迁移,且偏移量易算错
- UUID / MD5:无序、过长(128bit 字符串)、索引碎片严重、JOIN 和排序性能差,仅适合非主键场景(如 trace_id)
- Redis INCR + 固定 key:单点 Redis 故障即停服;若用 Redis Cluster,key 落不同 slot 导致无法原子 INCR,需改用 Lua 或改用 Redlock 等复杂协议
真正可靠的方案,都是在可用性、一致性、性能三者间做明确取舍。没有银弹,只有适配——高并发交易系统倾向 Snowflake 或号段;中小业务可先用成熟 SaaS 化 ID 服务;强审计需求则考虑带签名/加密的定制 ID 格式。










