【杂谈】主键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,需要 ...
随机推荐
- DevEco Studio 实战第一节:字符串拼接与组件构建
DevEco Studio 实战第一节:字符串拼接与组件构建 引言 在现代软件开发中,TypeScript 提供了强类型的优势,而 DevEco Studio 作为华为推出的开发集成环境,提供了便捷的 ...
- 试了下Cursor,感觉程序员工种危险了
大家好,我是汤师爷~ 今年8月份,AI 编程工具 Cursor 在开发者社区彻底火了.在 Twitter 平台上,Cloudflare 副总裁分享了一段视频,展示了一个令人震惊的案例.他年仅 8 岁的 ...
- AE错误代码
错误代码 错误描述 错误名称 HRESULT:0x80040201 "Failed to load a resource (string, icon, bitmap, etc)." ...
- QTabWidget的高度取决于当前选项卡的高度
QTabWidget的高度自适应当前选项卡的高度,可以通过设置其他选项卡的QSizePolicy为Ignored, connect(ui->tabWidget,SIGNAL(currentCha ...
- Linux系统 tcpdump 抓包命令使用教程
tcpdump 是Linux系统下的一个强大的命令,可以将网络中传送的数据包完全截获下来提供分析.它支持针对网络层.协议.主机.网络或端口的过滤,并提供and.or.not等逻辑语句来帮助你去掉无用的 ...
- 【转载】 Locust 官方文档
链接:https://www.jianshu.com/p/40102e9a24cb 安装 一般直接通过 pip 就可以安装: $ pip install locust 注意: Locust 1.x 版 ...
- Win10正式专业版激活方法
首先,我们先查看一下Win10正式专业版系统的激活状态: 点击桌面左下角的"Windows"按钮,从打开的扩展面板中依次点击"设置"-"更新和安全 ...
- IM开发干货分享:我是如何解决大量离线消息导致客户端卡顿的
1.引言 好久没写技术文章了,今天这篇不是原理性文章,而是为大家分享一下由笔者主导开发实施的IM即时通讯聊天系统,针对大量离线消息(包括消息漫游)导致的用户体验问题的升级改造全过程. 文章中,我将从如 ...
- IM通讯协议专题学习(七):手把手教你如何在NodeJS中从零使用Protobuf
1.前言 Protobuf是Google开源的一种混合语言数据标准,已被各种互联网项目大量使用. Protobuf最大的特点是数据格式拥有极高的压缩比,这在移动互联时代是极具价值的(因为移动网络流量到 ...
- (四).NET6.0程序部署到Docker上
1.确保安装Docker 2.把需要部署到Docker上面的项目,咱们先添加Docker的支持,启动项目右键 -> 添加 -> Docker支持,选择 Linux 然后会自动生成Docke ...