【杂谈】主键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,需要 ...
随机推荐
- 关于被static修饰还可序列化的问题
今天为了验证一下被static修饰的变量到底可不可以序列化,出现了以下的情况: 然后找到一条评论,豁然开朗 把序列化的内容注释掉,直接从序列化文件读取对象,就发现没有获取到
- Echarts 基本使用
1.Echarts简介 ECharts 是一个使用 JavaScript 实现的开源可视化库,涵盖各行业图表,满足各种需求. ECharts 包含了以下特性: (1)丰富的可视化类型: 常规的折线图. ...
- 强网杯2023 谍影重重2.0 wp
题目描述 小明是某间谍组织的一员,他终日监听着我国某重点军事基地的飞行动态,妄图通过分析参数找到我国飞的最快的飞机.我国费尽千辛万苦抓住了他,并在他的电脑上找到了一段他监听的信息,请分析出这段信息中飞 ...
- WinForm(C/S)项目中使用矢量字体(FontAwsome、Elegant)图标
1.介绍 字体图标在Web应用中最为常见,字体图标是矢量的,矢量图意味着每个图标都能在所有大小的屏幕上完美呈现,可以随时更改大小和颜色,而且不失真.字体图标常见的有Font Awesome和Elega ...
- Java框架 —— MyBatis
MyBatis 简介 持久层框架,半自动映射,支持自定义SQL.高级映射.存储过程,免除了JDBC代码.参数设置.获取结果集的工 作,可以通过XML或注解方式配置.映射接口,以及实体类在数据库中的记 ...
- Ant Design Pro项目ProTable怎么获取搜索表单值
前情 公司有经常需要做一些后台管理页面,我们选择了Ant Design Pro,它是基于 Ant Design 和 umi 的封装的一整套企业级中后台前端/设计解决方案. 产品效果图 最新接到的一个后 ...
- 12C++循环结构-for循环(2)——教学
一.循环变量为字符型 (第32课 26个兄弟姐妹)参考视频1 试编一程序,按字典顺序输出26个字母. 流程图: 思考:先顺序输出26个小写英文字母,再逆序输出26个大写英文字母. 循环可以是递增型循环 ...
- 鼠标事件:mouseout、mouseover事件会不断触发
mouseover 和 mouseenter mouseenter不会冒泡,而mouseover会冒泡 mouseover:指针进入事件监听的元素内 或者 其他的子元素内 都会触发mouseover ...
- 龙哥量化:期货软件中红红绿绿的"多开,空开,空平,多平,多换,空换,双开,双平,换手"是什么意思?(转载的)
期货投资者在看盘时,会看到红红绿绿的"多开,空开,空平,多平,多换,空换,双开,双平,换手",以快期专业版为例,如下图1所示: 图1.红绿开平数据(快期专业版) 这些数据里面的红色 ...
- 手写 PromiseA+ 实现,轻松通过 872 条用例
手写 Promise/A+ 实现,轻松通过 872 条用例 规范参考:Promise/A+ 规范 - 中文版本 测试工具:https://github.com/promises-aplus/promi ...