当前位置: 首页 > 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.dtcms.com/a/278093.html

相关文章:

  • 在新版本的微信开发者工具中使用npm包
  • 用信号量实现进程互斥,进程同步,进程前驱关系(操作系统os)
  • DOS下EXE文件的分析 <1>
  • MacBook Air通过VMware Fusion Pro安装Win11
  • 从代码学习深度强化学习 - DDPG PyTorch版
  • [Python 基础课程]列表
  • 【DataLoader的使用】
  • 力扣 hot100 Day43
  • Actor-Critic重要性采样原理
  • java valueOf方法
  • 【算法】贪心算法入门
  • SwiftUI 7 新 WebView:金蛇出洞,网页江湖换新天
  • 一些git命令
  • 若依框架集成阿里云OSS实现文件上传优化
  • 对于muduo我自己的理解
  • UniHttp生命周期钩子与公共参数实战:打造智能天气接口客户端
  • flask校园学科竞赛管理系统-计算机毕业设计源码12876
  • SPSSPRO:数据分析市场SaaS挑战者的战略分析
  • JAVA并发——什么是AQS?
  • Mapbox GL初探
  • 【unitrix】 5.0 第二套类型级二进制数基本结构体(types2.rs)
  • 16.使用ResNet网络进行Fashion-Mnist分类
  • css如何同时给元素设置背景和背景图?
  • 每日算法刷题Day47:7.13:leetcode 复习完滑动窗口一章,用时2h30min
  • 说实话,统计分析用Python这5个第三方库就够了
  • AutoLabor-ROS-Python 学习记录——第一章 ROS概述与环境搭建
  • PortsSwiggerLab: SSRF with blacklist-based input filter
  • JS进阶-day1 作用域解构箭头函数
  • Spring AI 项目实战(十六):Spring Boot + AI + 通义万相图像生成工具全栈项目实战(附完整源码)
  • NO.5数据结构串和KMP算法|字符串匹配|主串与模式串|KMP|失配分析|next表