社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

在MySQL中用UUID当主键,被组长给喷了!

Hollis • 1 年前 • 302 次点击  
△Hollis, 一个对Coding有着独特追求的人△

这是Hollis的第 432 篇原创分享
作者 l Hollis
来源 l Hollis(ID:hollischuang)

我们在使用MySQL的时候,主键的选择上一般有两种,那就是UUID和自增主键ID,使用这两个做主键各自都有哪些优缺点呢?为什么建议优先使用自增主键ID呢?


UUID唯一吗

UUID(Universally Unique Identifier)全局唯一标识符,是指在一台机器上生成的数字,它的目标是保证对在同一时空中的所有机器都是唯一的。

UUID 的生成是基于一定算法,通常使用的是随机数生成器或者基于时间戳的方式,生成的 UUID 由 32 位 16 进制数表示,共有 128 位(标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12),共32个字符)

由于 UUID 是由 MAC 地址、时间戳、随机数等信息生成的,因此 UUID 具有极高的唯一性,可以说是几乎不可能重复,但是在实际实现过程中,UUID有多种实现版本,他们的唯一性指标也不尽相同。

UUID在具体实现上,有多个版本,有基于时间的UUID V1,基于随机数的 UUID V4等。(我出了一份Java面试宝典,覆盖80%左右的技术面试题

Java中的java.util.UUID生成的UUID是V3和V4两种:

Version 4 这种是最简单的(也是我们最常用的),只是基于随机数生成的,但是也是最不靠谱的。适合数据量不是特别大的场景下。

Version 3是基于名称空间的,所以在一定范围内是唯一的,而且如果有需要生成重复UUID的场景的话,这两种是可以实现的。



UUID的好处

很多人选择UUID作为主键,其实也是有一定道理的,那就是UUID有几何好处:

  • 全局唯一:使用不同的算法生成,虽然不能100%保证唯一,但是在非并发场景下几乎可以保证在全球范围内唯一,避免了多台机器之间主键冲突的问题。

  • 不可预测性:随机生成的 UUID 很难被猜测出来,对于需要保密性的应用场景较为适用。

  • 分布式:由于可以在不同的机器上生成 UUID,因此可以用于分布式系统中,如分库分表场景。



UUID的缺点

但是,如果只是因为这几个好处就选择UUID当做主键ID的话,那么也不是很好的方案,因为他的缺点也比较明显,如:

存储空间比较大:UUID 通常以字符串形式存储,占用的存储空间比较大。

不适合范围查询因为不是自增的,所以在做范围查询的时候是不支持的。

不方便展示:主键ID有的时候会需要在系统间、或者前台页面展示,如果是UUID的话,就因为比较长、并且没有任何业务含义,所以不方便展示。

查询效率低

在UUID列上创建索引,因为他很长,所以索引的大小会变得非常大。大的索引会占用更多的磁盘空间,导致缓存命中率下降,进而增加了磁盘I/O的需求。此外,大的索引还会导致查询时的内存开销增加。我出了一份Java面试宝典,覆盖80%左右的技术面试题

当使用UUID进行排序时,新的UUID值通常会插入到叶子节点的中间位置。这可能导致B+树的页分裂和平衡操作频繁进行,从而增加了写入的开销。每次分裂或平衡都涉及到数据的重新排序和移动,这会影响查询的性能。



自增ID

在 MySQL 中,可以通过设置 AUTO_INCREMENT 属性实现ID的自增长,通常可以用来作为主键ID。

使用自增ID做主键的好处是:

  • 存储空间:ID是数字,所以占用的位数要比UUID小多了,所以在存储空间上也节省很多。

  • 查询效率:ID 是递增的,因此在使用 B+Tree 索引时,查询效率较高。

  • 方便展示:因为ID比较短,方便展示。

  • 分页方便:因为ID是连续自增的,所以在分页的时候,可以通过ID解决深度分页的问题。

但是,使用自增主键做主键ID也存在一定的问题

  • 分库分表:当我们做分库分表的时候,就没办法依赖一张表的自增主键来做主键ID了,这样就会发生重复导致冲突的问题

  • 可预测:因为ID是顺序自增的,所以是可以预测的,这就给系统带来了一定的安全风险。

  • 可能用尽:自增id的话可能是int、bigint等,但是他们都是有范围的,有可能会用尽



总结

所以,在实际选型过程中,大家需要结合自己的实际业务做选择。

简单的业务场景,数据量不大,增删改查也不频繁,可以选择用UUID。

内部系统,数据量增删改查频繁,有频繁的分页查询和展示等需求,优先选择自增主键ID。我出了一份Java面试宝典,覆盖80%左右的技术面试题

对外系统,数据量不大,也可以选用自增主键ID。

对外系统,数据量大,分库分表,则考虑使用雪花算法生成全局唯一ID。



本文内容节选自我最近出的Java面试宝典,类似的问题及答案还有700多道题。从工作0年到工作8年左右,看了都一定满满收获。


我们会持续更新内容,争取做到全网最新、最全、最准确的Java后端面试宝典。


之前已经推出有一段时间了,大家评价都很好,基本没有差评。我在抖音上的店铺评分是满分的,可以说品质是嘎嘎有保障的。



大家都知道程序员有多难,这侧面证明了这个内容的价值了!



很多人也通过这份宝典上岸了(目前已知最高的拿到年包80的Offer,很多人上岸阿里、美团、快手、华为、滴滴、携程、小红书等中大厂),趁现在还未涨价(原价169,现在有70元优惠券,到手99,后续会不断涨价。。。),有需要的抓紧上车吧。


在线课程,文字形式,永久更新。


八股文面试宝典详细介绍:Java面试宝典介绍


下单后,不满意3天内可以无条件退款!只要你觉得它是任何一个市面上可以看到的面试题库可以比拟的,不管别人卖多少钱,只要你有这种感觉了,都直接来退款!就是这么自信!!


(下单后按照短信提示申请权限并联系客服审批即可)

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/160907
 
302 次点击