You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL中BIGINT(Long)主键耗尽后的替代方案及高性能实现咨询

替代BIGINT主键的高性能方案

针对你每日高插入量、BIGINT主键即将耗尽的场景,以下几种方案既解决ID耗尽问题,又能保证插入性能:

1. 二进制存储UUID(V4)

MySQL原生的UUID()生成的字符串(36字符)作为主键会导致索引碎片严重、插入性能差,但转成二进制存储可解决这个问题:

  • 表结构设计:主键字段用BINARY(16)类型
  • 插入时:使用UUID_TO_BIN(UUID(), 1)生成二进制UUID,第二个参数1会把UUID的时间戳部分放在二进制的前8位,让插入的ID近似递增,大幅减少索引碎片
    INSERT INTO new_table (id, col1, col2) VALUES (UUID_TO_BIN(UUID(), 1), 'val1', 'val2');
    
  • 查询时:用BIN_TO_UUID(id, 1)转回字符串UUID
    SELECT BIN_TO_UUID(id, 1) AS uuid, col1 FROM new_table;
    
  • 性能优势:二进制存储仅占16字节,比字符串UUID节省一半空间;近似递增的ID让B+树索引的插入性能接近自增BIGINT,完全适配高并发插入场景。

2. 雪花算法(Snowflake)ID

雪花算法生成64位数字ID,结构为时间戳(41位)+机器ID(10位)+序列号(12位),既保证全局唯一,又天然递增:

  • 表结构:主键仍用BIGINT(和原有类型兼容,减少代码改动)
  • 实现方式:Java端生成雪花ID(无需依赖数据库自增),示例核心逻辑:
    public class SnowflakeIdGenerator {
        private final long epoch = 1609459200000L; // 2021-01-01 00:00:00
        private final long workerIdBits = 10L;
        private final long sequenceBits = 12L;
        private long workerId;
        private long sequence = 0L;
        private long lastTimestamp = -1L;
    
        public synchronized long nextId() {
            long timestamp = System.currentTimeMillis();
            if (timestamp < lastTimestamp) {
                throw new RuntimeException("Clock moved backwards");
            }
            if (timestamp == lastTimestamp) {
                sequence = (sequence + 1) & ((1 << sequenceBits) - 1);
                if (sequence == 0) {
                    timestamp = waitNextMillis(lastTimestamp);
                }
            } else {
                sequence = 0L;
            }
            lastTimestamp = timestamp;
            return ((timestamp - epoch) << (workerIdBits + sequenceBits))
                    | (workerId << sequenceBits)
                    | sequence;
        }
        private long waitNextMillis(long lastTimestamp) { 
            long timestamp = System.currentTimeMillis();
            while (timestamp <= lastTimestamp) {
                timestamp = System.currentTimeMillis();
            }
            return timestamp;
        }
    }
    
  • 性能优势:完全在应用端生成ID,避免数据库自增锁的竞争,高并发插入性能比自增BIGINT更优;ID是数字类型,索引操作和原有BIGINT一致,无额外性能开销。
  • 注意点:需处理系统时钟回拨问题,可通过配置不同机器ID避免集群内重复。

3. 分布式ID生成服务

如果是多节点集群场景,可使用成熟的分布式ID服务(如美团Leaf、百度UidGenerator):

  • 核心逻辑:服务端维护ID分段,给每个应用节点分配一段ID缓存,应用从本地缓存取ID,用完再申请新段
  • 表结构:主键仍用BIGINT
  • 性能优势:ID生成延迟极低(本地缓存),支持超高并发;服务端保证ID全局唯一且递增,索引插入性能优异。

新表迁移的性能保障步骤

如果你选择创建新表切换主键,按以下步骤操作可避免影响业务:

  • 双写阶段:修改应用代码,同时向旧表和新表写入数据,持续1-2天确保数据完全同步
  • 读流量切换:逐步将读请求从旧表切到新表,验证数据一致性和查询性能
  • 停止旧表写入:确认新表稳定后,停止向旧表写入,完全切换到新表
  • 归档旧表:后续可将旧表数据归档到冷存储,释放数据库资源

内容的提问来源于stack exchange,提问作者dead programmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:35:30