mysql创建自增uuid_Mysql主键选择之UUID和自增主键

引言

之前有段时间用postgresql 数据库,在上云之后,从自增主键变为uuid,感觉uuid全球唯一,很方便。

最近用mysql,发现mysql主键都是选择自增主键,仔细比较一下,为什么mysql选择自增主键,有什么不同。

在mysql5.0之前,如果是多个master复制的环境,无法用自增主键,因为可能重复。在5.0以及之后的版本通过配置自增偏移量解决了整个问题。

什么情况下我们希望用uuid

1. 避免重复,便于scale,这就是我们做cloud service的时候选择uuid的主要原因

2. 入库之前可以知道id

3.相对安全,不能简单的从uuid获取信息,但是如果自增,则容易暴露信息,如果一个客户id是123456,很容易猜到有客户id是123456.

UUID有什么问题

1.uuid有16个字节,比int(4 byte)和bigint(8 byte)占用更多存储空间

2.由于size和无序性,可能引起性能问题

Mysql的uuid原理

mysql的innodb存储引擎处理storage的方式是靠聚集索引。

聚集索引是指数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同。一个表只能有一个聚集索引,因为一个表的物理顺序只有一种情况

由於 UUID 在 insert 的時候,不一定會比先前的鍵值更大,也因此 InnoDB 必須要計算出適當的位置來安插新的資料。 而目標頁 (Page) 很有可能已經寫入到磁碟中,且從快取中移除,或尚未在快取內,而 InnoDB 必須在每次寫入時去做頁查找,如此行為會消耗大量的 random I/O.

不連續的插入行為,也會導致 InnoDB 必須不斷的分頁 (split pages) 來創造更多的空間來安插新的資料,也因此創建出來的 pages 會是相當稀疏且有許多碎片。

在 InnoDB 的 index 中,index 的 leaf node 不儲存 row pointer,取而代之,他儲存的是 primary key 的值,找到值之後,再用這個 primary key value 去 clustered index 找出對應的 row data。

也就是說,secondary index 的 left node 中不僅儲存了 index 本身的鍵值,還會把 primary key columns 也儲存進去。

這樣講就很明瞭了,primary key 儲存的值越大,同時會影響到所有 secondary index 的大小。 把 BINARY(16) UUID 設定為 primary key,所有的 secondary index 也都要將 BINARY(16) UUID 儲存進 index 才行。

這樣聽起來好像很無感,如果 primary key 要多存 16Bytes , secondary index 也要多存 16Bytes,這樣隨便一個 10M 個 rows 加起來就多 320MB 了,你如果用大整數 BIGINT 儲存,不僅速度快,還能省下不少空間。

如果你曾搜尋過一些 benchmarking 做 bigint auto_inc 跟 uuid insertion speed 的比較,雖能看出 I/O 效能,卻沒有確切的解釋。

而透過了解 clustered index 應該就能明暸為何 bigint auto_inc 做 insertion 速度是最快最穩。 因為,即使是透過時間序列產生的 UUID 在 insertion 的效能表現上也未如 unsigned int + auto increment 佳。

所以,即使在表格內已有 UUID,一般還是會建議在 MySQL 中另外建立一個 column ,使用 unsigned int + auto_increment 做 primary key,一方面可以穩定 insertion speed,另一方面讓索引的查詢更快、分布平均、也讓索引更小。

原理引用:

https://medium.com/corneltek/innodb-primary-key-with-uuid-and-auto-increment-integer-508d427688dc

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值