【杂谈】主键ID如何选择——自增数 OR UUID?
1.生成位置如何影响选择?
数据库往返时间
使用自增数时,ID是由数据库在执行INSERT操作时生成的;而UUID则可以在应用层生成。
考虑这样的场景:
一个方法需要插入A和B两个实体。其中B的数据需要引用A的ID。
如果使用自增ID,则必须与数据库进行两次网络请求:
1.先插入A,获取A的ID;
2.然后使用A的ID构建B,再插入B。
而如果使用UUID,可以在应用层同时生成A和B的ID,之后一次性将两个实体提交给数据库,从而减少网络往返的次数,提高效率。
ID冲突
自增数在一个表内不会冲突,那两个表呢?
当业务发展到需要分库分表的时候,就不能再使用自增数作为ID了,因为两个库/表会生成相同的ID。这种ID冲突且不报错的问题,会导致数据混乱。
UUID虽然具有全球唯一性,极端情况也会有冲突,所以应用层需要想办法处理,确保ID唯一性,例如IID生成结合机器ID。
2.有序与无序如何影响选择?
ID是否有序对数据库性能有重要影响,特别是使用B-Tree索引。
有序的ID:对B-Tree索引来说,键值有序,那么连续插入的数据都会一个或少数几个节点上,这意味着,数据库只需要对少量的物理块进行I/O读写,I/O范围小,性能较好。
eg:连续插入20条数据,都在一个节点上,只要加载一个物理块。
无序的ID:键值无序,那么连续插入的数据可能随机分布在各个节点上,数据库就需要对大量的物理块进行I/O读写,性能较差。
eg:连续插入20条数据,经计算它们分布在20个不同节点上,需要加载20个物理块。
显然,自增ID是有序的,所以在大多数情况下,它的性能优于无序的UUID。
值得一提的是,UUID也有多个版本,其中一些是有序的,例如UUIDv7和雪花算法(Snowflake)
而Java JDK默认使用的UUID是v4版本,是无序的。
3.ID大小如何影响选择?
ID大小指占用的存储空间。自增数通常是INT或BIGINT,分别是4字节和8字节。UUID一般由32个字符组成,占16字节。
树的高度
在B-Tree中,对于固定大小的节点,键值大小会影响一个节点能存储的键值数量(这里就是ID数量)。影响了单个节点存储的键值,就会影响节点数量,进而影响树的高度。
而树越高,一次查询需要访问的节点就更多,查询就更慢。
内存开销
相同数量的记录,ID的大小会影响到数据库引擎的缓存(索引和数据行)。同样大小的缓存空间,单个ID越大,能缓存的数据就越少。
例如:InnoDB使用innodb_buffer_pool_size控制缓存池大小
总结
总的来说,有序的UUID(UUIDv7,雪花算法)更适合分布式服务,自增ID更适合单机服务。
但是也要看具体业务,举个例子,如果分表的数据不存在跨表访问的情况,那么ID冲突就冲突了,没有任何影响。
而且,ID策略也能混着用,一个数据库里面不同表可以用不同的ID生成策略。
【杂谈】主键ID如何选择——自增数 OR UUID?的更多相关文章
- Mysql对自增主键ID进行重新排序
Mysql数据库表的自增主键ID号经过一段时间的添加与删除之后乱了,需要重新排列. 原理:删除原有的自增ID,重新建立新的自增ID. 1,删除原有主键: ALTER TABLE `table_name ...
- Mysql自增主键ID重新排序方法详解
Mysql数据库表的自增主键ID号乱了,需要重新排列. 原理:删除原有的自增ID,重新建立新的自增ID. 1,删除原有主键: ALTER TABLE `table_name` DROP `id`; 2 ...
- 使用mybatis插入自增主键ID的数据后返回自增的ID
在开发中碰到用户注册的功能需要用到用户ID,但是用户ID是数据库自增生成的,这种情况上网查询后使用下面的方式配置mybatis的insert语句可以解决: <insert id="in ...
- Mybatis+Mysql插入数据库返回自增主键id值的三种方法
一.场景: 插入数据库的值需要立即得到返回的主键id进行下一步程序操作 二.解决方法: 第一种:使用通用mapper的插入方法 Mapper.insertSelective(record): 此方法: ...
- mybaits返回自增主键ID
mybaits两种获取自增主键ID的方法:一种是使用useGeneratedKeys,第二种是selectKey方法获取. useGeneratedKeys <insert id="i ...
- Mybatis 中获取添加的自增主键ID(针对mysql)
分享一篇博客,主要就是针对在我们使用SSM的时候,在.xml中获取<insert></insert> 时的自增主键Id,由于好久没有,这个时候使用,有点生疏,就在这里写个笔记, ...
- Mybatis 在 insert 之后想获取自增的主键 id
记录一次傻逼的问题, 自己把自己蠢哭:Mybatis 在 insert 之后想获取自增的主键 id,但却总是返回1 错误说明: 返回的1是影响的行数,并不是自增的主键id: 想要获取自增主键id,需要 ...
- 将一张表的主键(ID)重置为从1开始自增排列
如果你有一张表,你的主键是ID,然后由于测来测去的原因,你的ID不是从1开始连续的自增了. 终于有一天,使用这张表的某个系统要导入正式数据了,强迫症这时候就表现的明显了,浑身不自在, 这时候你就需要将 ...
- Java中实现MongoDB自增主键ID
1.了解MongoDB的ObjectId MongoDB的文档固定是使用“_id”作为主键的,它可以是任何类型的,默认是个ObjectId对象(在Java中则表现为字符串),那么为什么M ...
- Mybatis 在 insert 之后想获取自增的主键 id,但却总是返回1
记录一次傻逼的问题, 自己把自己蠢哭:Mybatis 在 insert 之后想获取自增的主键 id,但却总是返回1 错误说明: 返回的1是影响的行数,并不是自增的主键id: 想要获取自增主键id,需要 ...
随机推荐
- windows下python批量更新软件包
前言 相信很多小伙伴都遇到过python有些软件包版本过低导致无法安装一些模块的问题,刚好我前两天也遇到了,这里写个文章记录一下 一.更新pip版本 打开命令控制面板,输入: python -m pi ...
- uniapp使用EventBus实现页面间数据传递
前情 最近在做小程序项目,选用是当前比较火的uniapp技术栈,经常会遇到页面间消息传递的需求. 为什么要这么做? uniapp页面间数据通信方式有很多:通过url传参,状态管理库vuex/pinia ...
- Simple FOC内置通信接口学习(一):实时监控电机状态
本文参(zhao)考(chao)至官方文档https://docs.simplefoc.com/docs_chinese/monitoring 引言 在使用Simple FOC控制电机的过程中,尤其是 ...
- 06C++顺序结构与程序IPO模式
一.程序IPO模式 编程 IPO 是指输入.处理和输出(Input, Process, Output)的概念.在计算机编程中,IPO 是一种常用的设计模式,用于描述程序的基本流程.具体来说,IPO 指 ...
- R数据分析:结合APA格式作图大法讲讲ggplot2和ggsci,请收藏
之前给大家写过一篇plot的基础操作,相信同学们应该没有看过瘾.不过主流的用的多的还是ggplot2,所以今天打算结合一个形成APA样板格式图片的实例写写ggplot2的操作和图的配色. 关于APA格 ...
- 关于在VMware中安装的CentOS7系统中无法安装ntp
一.问题引言 今天在虚拟机中新安装了CentOS7,在使用yum命令时,出现如下如错误: 2.点击图片中链接,即是"2"中的红框,发现该链接竟不可达 3.于是开始找度娘,但并没有发 ...
- Qt音视频开发系列文章导航
文章 链接 1-vlc解码播放 https://qtchina.blog.csdn.net/article/details/107742836 2-vlc回调处理 https://qtchina.bl ...
- Qt开源作品33-图片开关控件
一.前言 进入智能手机时代以来,各种各样的APP大行其道,手机上面的APP有很多流行的元素,开关按钮个人非常喜欢,手机QQ.360卫士.金山毒霸等,都有很多开关控制一些操作,在WINFORM项目上,如 ...
- NetCore开源项目,适合新手学习
VerEasy.Core 介绍 这是一个基于 .NET Core 的易开发的框架,附 vue3前端框架.提供了一个高效可扩展的API程序. 支持 JWT 认证.数据库操作.日志记录.异步处理等特性,能 ...
- vue3 路由-导航守卫
假设用户登录,在地址栏输入了Login,人性化的设计应该自动回到home页面.或者用户输入不存在路由,也应该回到home页面. 这个时候需要用到vue-router的导航守卫功能. 在我们封装的rou ...