雪花算法生成的主键存在哪些问题,为什么不能使用自增ID或者UUID做MySQL的主键

MySQL 分布式架构中的主键选择:自增ID、UUID与雪花算法

为什么MySQL分布式架构中不能使用自增主键?

在分布式架构中,自增主键存在以下问题:

  1. 主键冲突风险:多个数据库实例同时生成自增主键会导致ID重复
  2. 分片不均匀
    • 采用范围分片时会出现"尾部热点"现象,压力集中在某个分片
    • 无法实现负载均衡,新数据只能写入当前分片
  3. 数据合并困难:合并多个数据库时,自增主键会重复
  4. 性能瓶颈:自增锁在高并发场景下会成为性能瓶颈
  5. 安全性问题:自增ID容易被猜测,可能被用于恶意爬取数据

UUID作为主键的优缺点

优点

全局唯一性:几乎可以保证全球范围内的唯一性
分布式友好:无需协调即可在不同节点生成
安全性:随机生成的UUID难以被猜测

缺点

存储空间大:16字节(128位),是自增ID(通常4字节)的4倍
索引性能差
• 无序插入导致B+树频繁分裂和平衡
• 增加索引大小,降低缓存命中率
可读性差:长字符串形式不利于人工识别和调试
碎片化问题:随机插入导致磁盘碎片化

MySQL 8.0优化:可使用UUID_TO_BIN函数将UUID转换为16字节二进制并排序,性能接近自增ID

雪花算法(SnowFlake)详解

原理

雪花算法生成64位长整型ID,结构如下:

0 | 0000000 00000000 00000000 00000000 00000000 | 00000 | 00000 | 00000000 0000
  1. 1位符号位:固定为0(正数)
  2. 41位时间戳:毫秒级时间,可用69年(从1970算起)
  3. 10位机器标识
    • 5位数据中心ID(32个可能值)
    • 5位工作机器ID(32个可能值)
  4. 12位序列号:同一毫秒内的计数器(4096个值/ms/机器)

优势

  1. 全局唯一:通过时间戳+机器ID+序列号组合保证
  2. 有序递增:基于时间戳,有利于索引和排序
  3. 高性能:本地生成,每秒可生成数百万ID
  4. 不依赖第三方:算法简单,内存中完成
  5. 分布式友好:支持最多1024个节点(10位机器标识)

不足与解决方案

  1. 时钟回拨问题
    问题:服务器时间被调回导致重复ID
    解决方案
    ◦ 直接抛出异常,停止服务
    ◦ 记录最近时间戳,回拨时等待
    ◦ 使用扩展位记录时钟序列(3位时钟序列+7位机器ID)
    ◦ 采用Leaf、UidGenerator等改进方案

  2. 机器ID限制
    问题:10位仅支持1024个节点
    解决方案
    ◦ 预分配ID(适合固定节点)
    ◦ 动态分配(使用Redis/Zookeeper存储ID)
    ◦ 扩展位数(牺牲部分时间戳或序列号位)

  3. 时间戳耗尽
    问题:41位时间戳约69年后耗尽
    解决方案:调整起始时间(如使用系统上线时间而非1970)

代码示例(Java)

public class SnowflakeIdGenerator {private final long twepoch = 1577836800000L; // 自定义起始时间(2020-01-01)private final long workerIdBits = 5L;private final long datacenterIdBits = 5L;private final long maxWorkerId = -1L ^ (-1L << workerIdBits);private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);private final long sequenceBits = 12L;private final long workerIdShift = sequenceBits;private final long datacenterIdShift = sequenceBits + workerIdBits;private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;private final long sequenceMask = -1L ^ (-1L << sequenceBits);private long workerId;private long datacenterId;private long sequence = 0L;private long lastTimestamp = -1L;public SnowflakeIdGenerator(long workerId, long datacenterId) {// 参数校验this.workerId = workerId;this.datacenterId = datacenterId;}public synchronized long nextId() {long timestamp = timeGen();// 处理时钟回拨if (timestamp < lastTimestamp) {throw new RuntimeException("Clock moved backwards");}if (lastTimestamp == timestamp) {sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;return ((timestamp - twepoch) << timestampLeftShift)| (datacenterId << datacenterIdShift)| (workerId << workerIdShift)| sequence;}// 其他辅助方法...
}

总结对比

特性自增IDUUID雪花算法
唯一性单机唯一全局唯一全局唯一
有序性严格有序完全无序时间有序
存储空间4-8字节16字节8字节
分布式支持不支持支持支持
生成方式数据库生成应用生成应用生成
性能影响自增锁瓶颈索引分裂时钟依赖
适用场景单机MySQL简单分布式系统高并发分布式系统

推荐选择
• 单机系统:自增ID
• 简单分布式系统:MySQL 8.0的有序UUID
• 高并发分布式系统:雪花算法或其改进版(如Leaf)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/74256.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RapidJSON 处理 JSON(高性能 C++ 库)(四)

第四部分:RapidJSON 处理 JSON(高性能 C++ 库) 📢 快速掌握 JSON!文章 + 视频双管齐下 🚀 如果你觉得阅读文章太慢,或者更喜欢 边看边学 的方式,不妨直接观看我录制的 RapidJSON 课程视频!🎬 视频里会用更直观的方式讲解 RapidJSON 的核心概念、实战技巧,并配有…

chromem-go + ollama + bge-m3 进行文档向量嵌入和查询

Ollama 安装 https://ollama.com/download Ollama 运行嵌入模型 bge-m3:latest ollama run bge-m3:latestchromem-go 文档嵌入和查询 package mainimport ("context""fmt""runtime""github.com/philippgille/chromem-go" )func ma…

【LeetCode 题解】数据库:180. 连续出现的数字

一、问题描述 给定一个Logs表&#xff0c;包含自增 ID 和数字字段&#xff1a; CREATE TABLE Logs (id INT PRIMARY KEY AUTO_INCREMENT,num VARCHAR(50) );要求编写 SQL 查询&#xff0c;找出所有至少连续出现三次的数字。例如&#xff1a; --------- | id | num | -------…

MaxEnt模型进阶:基于R语言自动化与GIS空间建模的物种栖息地精准预测

生物多样性的空间分布规律及其对环境变化的响应机制&#xff0c;是生态学与地理学研究的前沿议题。在气候变化加剧和人类活动干扰的双重压力下&#xff0c;如何精准预测物种潜在分布范围、识别关键环境驱动因子&#xff0c;已成为制定生物保护策略的核心科学问题。物种分布模型…

缓存雪崩解决方案:二级缓存VS随机TTL

背景 在学习缓存雪崩的时候&#xff0c;了解到有二级缓存和随机TTL两个解决方案&#xff0c;但是在学习之后&#xff0c;个人认为二级缓存本质上还是利用两层缓存的过期时间不一致来实现缓存过期时间随机化&#xff0c;这不就是和随机TTL一样吗&#xff0c;故有了这篇思考&…

Android View事件分发机制深度解析

在Android面试中&#xff0c;关于View事件分发机制的考察往往不仅限于基础流程&#xff0c;更关注底层原理、性能优化和实际应用场景。以下是针对面试的全面回答策略&#xff1a; 一、基础回答框架 核心三要素&#xff1a; 传递流程 "事件分发遵循Activity → Window →…

2829. k-avoiding 数组的最小总和

2829. k-avoiding 数组的最小总和 题目链接&#xff1a;2829. k-avoiding 数组的最小总和 代码如下&#xff1a; class Solution { public:int minimumSum(int n, int k) {int m min(k / 2, n);return (m * (m 1) (k * 2 n - m - 1) * (n - m)) / 2;} };

phpStorm2021.3.3在windows系统上配置Xdebug调试

开始 首先根据PHP的版本下载并安装对应的Xdebug扩展在phpStorm工具中找到设置添加服务添加php web page配置完信息后 首先根据PHP的版本下载并安装对应的Xdebug扩展 我使用的是phpStudy工具&#xff0c;直接在php对应的版本中开启xdebug扩展&#xff0c; 并在php.ini中添加如下…

LabVIEW永磁同步电机性能测试系统

开发了一种基于LabVIEW的永磁同步电机&#xff08;PMSM&#xff09;性能测试系统的设计及应用。该系统针对新能源汽车使用的电机进行稳态性能测试&#xff0c;解决了传统测试方法成本高、效率低的问题&#xff0c;实现了测试自动化&#xff0c;提高了数据的准确性和客观性。 ​…

谷粒商城:Redisson

目录 Redisson 整合Redisson RLock RReadWriteLock RSemaphore RCountDownLatch 优化三级分类缓存 缓存一致性问题 双写模式 失效模式 脏数据解决 Redisson 提供redis分布式锁&#xff08;Distributed locks with Redis&#xff09;的java客户端 整合Redisson 引入 …

Linux系统调用编程

目录 一. 理解进程和线程的概念。并在Linux系统下进行相应操作 1.1概念 1.1.1进程(Process) 1.1.2 线程(Thread) 1.2操作 1.2.1用 ps -a 命令查看系统中各进程的编号pid 1.2.2用kill 命令终止一个进程pid 二. 解释Linux的“虚拟内存管理”&#xff0c;它与stm32中的 真…

25-智慧旅游系统(协同算法)三端

介绍 技术&#xff1a; 基于 B/S 架构 SpringBootMySQLLayuivue 环境&#xff1a; Idea mysql maven jdk1.8 node 管理端功能 首页展示图表&#xff1a;以数据可视化方式展示关键业务数据。 用户管理&#xff1a;管理系统用户&#xff0c;包括查看、编辑等操作。 供应商管…

【stm32--HAL库DMA+USART+空闲中断不定长收发数据】

串口通信-Hal库实现不定长度收发&#xff0c;DMAUSART DMA串口STM32CUBEMX配置&#xff08;工程创建&#xff09;基础配置时钟配置工程配置 代码编写现象 DMA 在正式配置之前&#xff0c;我们先来一起简单了解一下DMA。DMA&#xff08;Direct Memory Access&#xff0c;直接内…

沉浸式体验测评|AI Ville:我在Web3小镇“生活”了一周

最近&#xff0c;我在朋友的推荐下&#xff0c;体验了 aivillebot 的项目。起初&#xff0c;我只是抱着试试看的心态&#xff0c;心想这不就是个 Web3 版的《星露谷物语》吗&#xff1f; 但是一周下来&#xff0c;我发现这个虚拟小镇也没那么简单——里面的居民不是目前端游或链…

FPGA学习-基于 DE2-115 板的 Verilog 分秒计数器设计与按键功能实现

一、核心功能设计 按键暂停/继续&#xff1a;通过KEY1控制计时状态 按键消抖处理&#xff1a;20ms消抖周期消除机械抖动 硬件资源分配&#xff1a;符合DE2-115开发板引脚规范 二、核心模块实现详解 1. 顶层模块&#xff08;counter&#xff09; module counter(input CL…

后端开发 SpringBoot 工程模板

概述 本篇文章主要记录如何开发一个通用的 SpringBoot 工程开发框架的项目模板&#xff0c;这样后续需要开发项目时就可以直接开箱直用了&#xff0c;省区了很多重复步骤。 项目初始化 创建项目&#xff1a; 按照我的选项来选&#xff0c;然后点击 create&#xff0c;等待文…

OpenCv(五)——边缘检测

目录 边缘检测 一、sobel算子边缘检测 &#xff08;1&#xff09;原理 1、X轴方向的边缘检测 2、Y轴方向的边缘检测 &#xff08;2&#xff09;sobel算子参数 &#xff08;3&#xff09;X轴方向边缘检测代码演示 1、显示圆的图像 2、x方向上的边缘检测&#xf…

无人机数据链技术及运行方式详解!

一、无人机数据链技术要点 1. 通信传输技术 频段选择&#xff1a; 常用频段包括 L波段&#xff08;1-2 GHz&#xff09;、C波段&#xff08;4-8 GHz&#xff09;、Ku/K波段&#xff08;12-40 GHz&#xff09;&#xff0c;不同频段在传输距离、带宽和抗干扰性间权衡。 低…

AI Agent 实战:搭建个人在线旅游助手

AI Agent 实战&#xff1a;搭建个人在线旅游助手 本次实验中&#xff0c;我们将继续探索 Agent 的提示词&#xff0c;学习更加规范的提示词撰写方法。 本实验中你将掌握的知识点 使用 Dify 构建 Agent 的方法结构化的提示词撰写技巧变量的使用方法 1. 准备 在新建 Agent 之…

检索增强生成(RAG):强化 AI 智能体的知识 “武装”

技术点目录 第一章、智能体(Agent)入门第二章、基于字节Coze 构建智能体(Agent)第三章、基于其他平台构建智能体&#xff08;Agent&#xff09;第四章、国内外智能体(Agent)经典案例详解第五章、大语言模型应用开发框架LangChain入门第六章、基于LangChain的大模型API接入第七章…