当前位置: 首页 > news >正文

ID生成策略

ID生成策略

ID生成是系统设计中重要的一环,不同的场景需要不同的ID生成策略。


自增ID

自增ID是数据库中最简单的ID生成方式,通常通过数据库的自动递增功能实现(如MySQL的AUTO_INCREMENT)

优点

简单易用:数据库原生支持,无需额外开发
绝对有序:ID严格按插入顺序递增
空间效率高:通常使用32位或64位整数
索引效率高:B+树索引对连续数字非常友好

缺点

可预测性:容易暴露业务量,存在安全风险
分布式限制:单数据库有效,分库分表时难以保证全局唯一
依赖数据库:高并发时可能成为瓶颈
迁移困难:合并数据时可能发生冲突

适用场景

单机数据库应用
不需要隐藏业务规模的内部系统
对ID连续性有强需求的场景

例子

create table `user`
(id int primary key auto_increment,`name` char(20)
);

UUID

UUID(Universally Unique Identifier)是一个128位的全局唯一标识符,有多个版本,最常用的是版本4(随机生成)

优点

全局唯一:几乎不可能重复(理论上有但概率极低)
无需协调:任何节点可独立生成
信息安全:随机性强,无法预测
无中心依赖:不依赖数据库或任何服务

缺点

存储空间大:128位,字符串形式36字节
无序性:导致数据库索引效率低下
可读性差:对人不友好
传输开销:在网络传输中占用更多带宽

适用场景

分布式系统需要快速生成唯一ID
临时标识或一次性令牌
不关心排序且ID不频繁查询的场景

例子

Java标准库(java.util.UUID)提供了完整的UUID生成和解析功能,无需任何第三方依赖

import java.util.UUID;
public class Main {public static void main(String[] args) {UUID uuid = UUID.randomUUID();System.out.println(uuid);}
}

雪花算法(Snowflake)

优点

分布式友好:通过workerId支持分布式部署
趋势递增:利于数据库索引
时间有序:ID中包含时间信息
高性能:本地生成无网络开销
可控长度:64位长整型,存储高效

缺点

时钟依赖:系统时钟回拨会导致异常
workerId分配:需要额外系统管理workerId
时间溢出:41位时间戳约69年后会耗尽
不完全连续:同一毫秒内连续,跨毫秒不连续

适用场景

分布式系统需要有序唯一ID
需要ID中包含时间信息的场景
高性能ID生成需求

例子

MyBatis-Plus的IdWorker实现

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
public class Main {public static void main(String[] args) {long id = IdWorker.getId(); // 使用默认workerIdSystem.out.println(id);}
}

Redis生成

Redis作为高性能的内存数据库,非常适合用来生成分布式ID

优点

极其简单
保证原子性和唯一性
高性能(Redis单节点可达10万+/秒)

缺点

纯数字可预测
单点故障风险
无时间等额外信息

高并发场景

分段缓存方案

例子

(时间戳+计数)方案实现

@Component
public class RedisIdWorker 
{@AutowiredRedisTemplate redisTemplate;//开始时间搓public static final long BEGIN_TIMESTAMP;static {LocalDateTime time = LocalDateTime.of(2025,1,1,0,0,0);BEGIN_TIMESTAMP = time.toEpochSecond(ZoneOffset.UTC);}private static final String INC_KEY = "inc:";private static final int COUNT_BITS = 32; public long nextId(String keyPrefix){//1.生成时间搓LocalDateTime now = LocalDateTime.now();long nowTime = now.toEpochSecond(ZoneOffset.UTC);long timeStamp = nowTime - BEGIN_TIMESTAMP;//2.生成序列号//获取当前日期,精确到天String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));//自增长long increment = redisTemplate.opsForValue().increment(INC_KEY + keyPrefix + ":" + date);//3.拼接并返回return timeStamp << 32 | increment;}

结果:
在这里插入图片描述
在这里插入图片描述

http://www.lryc.cn/news/587174.html

相关文章:

  • ​[Dify]-基础入门7- 探索 Dify 知识库:打造专属知识大脑
  • 一些git命令
  • 系统设计 --- 双重检查锁定
  • 前端基础知识TypeScript 系列 - 04(TypeScript 中接口的理解)
  • 深度学习图像分类数据集—角膜溃疡识别分类
  • php生成二维码
  • 人工智能之数学基础:神经网络的矩阵参数求导
  • ABP VNext + 多级缓存架构:本地 + Redis + CDN
  • Redis集群方案——哨兵机制
  • 前端工程化-构建打包
  • Java 8 异步编程和非阻塞操作工具 CompletableFuture
  • DVWA CSRF漏洞分析与利用
  • C语言---自定义类型(上)(结构体类型)
  • 更换docker工作目录
  • 4. 关于CEF3 使用的一些记录及仓颉端封装的情况
  • [2025CVPR]DenoiseCP-Net:恶劣天气下基于LiDAR的高效集体感知模型
  • Android事件分发机制完整总结
  • 《Python JSON 数据解析全指南:从基础到实战(含 jsonpath 与 Schema 验证)》
  • 002大模型基础知识
  • Opencv---blobFromImage
  • Llama系列:Llama1, Llama2,Llama3内容概述
  • 互联网大厂Java面试:从Spring Boot到微服务的场景应用
  • RHCIA第二次综合实验:OSPF
  • anaconda常用命令
  • 动态规划理论基础,LeetCode 509. 斐波那契数 LeetCode 70. 爬楼梯 LeetCode 746. 使用最小花费爬楼梯
  • 编译器优化——LLVM IR,零基础入门
  • 基础数论学习笔记
  • 每天学习一个Python第三方库之jieba库
  • vue中 js-cookie 用法
  • 深度学习算法:开启智能时代的钥匙