浅谈MySQL主键

常用主键

常用主键
1)自增
int、bigint等,顺序递增。
2)雪花
雪花算法是因为有时间参数,所以是有序地,而且都是由数字组成。雪花id最大为64位,符合java中long的长度64位,适用于大规模分布式场景。
3)UUID
在一定的范围内唯一的机器生成的标识符,通用唯一标识符

优劣分析

1)UUID

优势:
随机生成,永不重复。

缺点:
uuid中带有字符串,32位字符串会占用更大的空间,无序的字符串作数据库主键,每次插入数据库的时候,MySQL为了维护B+树结构,需要频繁调整节点顺序,影响性能。

2)雪花

优势:
2.1引入了时间戳,保证ID能够按照时间有序生成,索引效率高。
2.2 分布式系统不会产生ID碰撞,并且效率较高。
2.3高性能高可用:不依赖第三方库或者中间件,完全在内存中生成,可用性强
2.4 容量大:每秒中能生成数百万的自增ID。

缺点:
依赖与系统时间的一致性,如果系统时间被回调,或者改变,可能会造成id冲突或者重复。

3)自增

优势:
3.1 InnoDB为聚集索引,索引查询效率更高。
3.2 存储和索引文件占用磁盘空间更少(500W数据,UUID占5.4G,自增ID占2.5G,该数据有待验证)
3.3 表读写效率高

缺点:
3.1分布式架构,多个Mysql实例ID重复问题控制不方便。
3.2 容易被外界猜测业务实际数据量。如:文章内容aritle?id=3,易被篡改为aritle?id=5,从而获取id为5的内容。
3.3 对于分库操作id自增控制不方便。

自增溢出问题

有人或许会担心自增id用完后又如何?

先说结论:不必担心。

再说原因:

MySQL常用数字及其占用字节与其范围:


其中bigint有符号值:-9223372036854775808 到9223373036854775807(- 2 ^ 63 到 2 ^ 63-1)

无符号值:0到18446744073709551615(0到2^64 – 1)

创建表时 自增长字段 选择无符号bigint,那么自增长最大值是 18446744073709551615

如果达到最大值后,不主动设置主键则报错,如果主动设置后重复同样报错。

业务概念

一秒增加的记录条数大约多少年后才会用完
1/秒584942417355 年
1万/秒58494241 年
100万/秒584942 年
1亿/秒5849年

每秒1亿的数据量,需要五千年才能用完,五千年什么概念?中华上下五千年吗?^_^
每秒1亿数据量又是什么概念,网络不会有瓶颈??MySQL单表数据量分库的上限是多少??读写瓶颈的上限又是多少??2KW纯读已不可接受,1亿能忍??在此之前网络、读写瓶颈恐怕早已出现。

无主键又如何

如果在创建表没有显示申明主键,InnoDB会自动帮你创建一个不可见的、长度为6字节的row_id,而且InnoDB 维护了一个全局的 dictsys.row_id,所以未定义主键的表都共享该row_id,每次插入一条数据,都把全局row_id当成主键id,然后全局row_id加1,该全局row_id在代码实现上使用的是bigint unsigned类型,但实际上只给row_id留了6字节,这种设计就会存在一个问题:如果全局row_id一直涨,一直涨,直到2的48幂次-1时,这个时候再+1,row_id的低48位都为0,结果在插入新一行数据时,拿到的row_id就为0,存在主键冲突的可能性,但也不必担心,原因见上述bigint业务量说明。

但是,实际开发中每个表都必须定主键。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值