MySQL 数据库主键用了字符串的 UUID 怎么办?

2021-09-05 17:16:36 +08:00
 Geekerstar

最近参与到一个老项目中:

MySQL 数据库主键 id varchar 64,如 00cfad279bf14e60a9c39c91e7dd8770

这种还有救么??目前系统线上运行着,不太可能停掉来修改,有没有什么好的优化办法呢?

另外,这是个 Java 项目,数据库字段下划线,实体接收也用下划线,没有用驼峰,看着不习惯,用什么理由能劝说大家用驼峰呢。。。

9770 次点击
所在节点    MySQL
79 条回复
lzfnb
2021-09-06 11:18:22 +08:00
做事要有边界,不要做这种费力不讨好的事
qdzzyb
2021-09-06 11:22:58 +08:00
问题不大 我司存链上数据 主键都是随机的 hash 值 最大的表几亿条数据了
tairan2006
2021-09-06 11:38:57 +08:00
数据库字段本来就应该用下划线,因为很多数据库不区分大小写

uuid 一般造成不了性能问题,除非规模非常大
zealinux
2021-09-06 11:41:14 +08:00
@wolfie

我们也用过 snowflake 只是用来生成业务 ID
(当然会加上前缀,不同的业务不同前缀)。

而数据库 ID,新的是用的 UUID,老系统用的 INT ID 。

也就是说,MySQL 里订单一条记录中,即有 UUID,也要有业务 ID 。
(其中 UUID 对用户不可见。)
levon
2021-09-06 11:48:18 +08:00
@lizuoqiang 一口一个逗比,你还会不会说话。
我还真就知道现在国内的某大公司,他们的项目就是 uuid 作为主键,而且很多表数据都超过 1 个亿的记录了,不也活的好好的。
我自己做过的项目也很多是 uuid 主键,几百万记录,也没碰过什么明显的性能问题。
chenqh
2021-09-06 11:54:26 +08:00
有个问题,一般不是再定义一个主键 id 比如 `oid` 这个吗? 原来的`id` 还是自增的吗?
IvanLi127
2021-09-06 12:15:45 +08:00
mysql 用 单调递增的 uuid 做主键没啥问题,是不是字符串性能问题也不算大吧。
我觉得,尽量想办法不参与比较实际,不然说服大家是一回事,谁负责重构之前代码又是一回事
belin520
2021-09-06 12:19:28 +08:00
拥有强迫症的空降技术小领导?
那你说的算,改!
lei2j
2021-09-06 13:34:04 +08:00
UUID 主键索引不好
RichardYyf
2021-09-06 14:07:45 +08:00
可以看下这篇文章关于主键的部分:
提炼下观点:
- 自增主键只推荐用在非核心业务表,甚至应避免使用;
- 核心业务表推荐使用 UUID 或业务自定义主键;
自增主键的坑真的是到一定数据量之后你想要优化的时候才能感知到的。

http://learn.lianglianglee.com/%E4%B8%93%E6%A0%8F/MySQL%E5%AE%9E%E6%88%98%E5%AE%9D%E5%85%B8/05%20%20%E8%A1%A8%E7%BB%93%E6%9E%84%E8%AE%BE%E8%AE%A1%EF%BC%9A%E5%BF%98%E8%AE%B0%E8%8C%83%E5%BC%8F%E5%87%86%E5%88%99.md
Nich0la5
2021-09-06 14:09:09 +08:00
https://www.cnblogs.com/goody9807/p/7608213.html 关于实际性能影响有多大我去查了一下翻到了这么一篇文章,性能上确实有差距但这点差距要不要优化还是看实际业务需求了。
改主键挺蛋疼的 各种关联表都要动一遍
huiyadanli
2021-09-06 14:12:55 +08:00
数据库多活的情况下。。uuid 反倒是更加好的方案
kelvin_fly
2021-09-06 14:35:11 +08:00
当遇到数据迁移等情况时,自增主键的坑就出来了
2i2Re2PLMaDnghL
2021-09-06 16:05:09 +08:00
@levon 我怎么看都不觉得 youtube 是字符串主键
你看到的 v= 参数很明显是 base64_url 出来的( URL 变种中用 -_ 替换 +/ )
至于 amazon 的 dp* 编号,也是递增系,跟 uuid 的随机系完全不一样。

这里我们要明确一个问题:有两个正交的区分:
字符串 vs 数字
递增 vs 随机
实际上 uuid 的意义在于随机,实际上它完全可以存为 int-like 或者 char()

字符串和数字作主键实际上没有很明显的差异,因为主键是直接查 B+ tree 的,O(log n) 几百到几亿也不过翻倍,查主键性能有差异已经不是正常数据库范畴了。
而递增和随机有明显的差异:随机在插入时会导致页分裂,但因为是随机的关系,实际上越大的库越不容易发生页分裂。数据局部性的问题,也就是扫全表的时候,顺序读取 vs 随机读取,实际上 SSD 下影响不大。
实际上真正碰到问题是自增 int 直接当字符串写,打个比方,写完了 1-9,然后你会发现你 10-19 全都在同一个位置插入,导致增加记录时有单一热点,越大的表越糟糕。

当然,两个维度都不是非黑即白的,twitter 还不是搞出了雪花这种半递增半随机的 int64 但以字符串形式传递的,堪称最四不像的主键。

不过,再说一遍,在座 80% 的人是遇不到因为具体范式选择导致的性能问题的,就好比不会因为用了 Python 导致一个请求花十秒,发生的情况都是因为错误的写法。
zeff
2021-09-06 16:17:36 +08:00
UUID 就是个垃圾,B+Tree 简历索引最好自增,这样效率会高,Twitter 的雪花算法自增数据量庞大的时候效率更高,建议说好的了解一下 B+Tree
xupefei
2021-09-06 18:25:55 +08:00
没想到讨论了这么久。
我对你讲,uuid 做主键只有一种情况会可能有性能问题:range query 。
B+树在 uuid 上没有任何问题。
levon
2021-09-06 20:55:09 +08:00
@2i2Re2PLMaDnghL 应该是,你分析的很专业,学习了。
dr1q65MfKFKHnJr6
2021-09-07 09:22:18 +08:00
好些人都是被互联网大厂技术给带偏了, 自己业务表 本来最多几万条数据,硬是要学别人几百万数据的做法,有必要吗?
了解学习一下没问题,强行改得不偿失
wangritian
2021-09-07 10:03:34 +08:00
uuid 全面代替 int 主键有 3,4 年了,当然要用时间戳开头的生成算法,好处太多

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/799982

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX