自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

跟同事杠上了!用雪花算法生成的id做主鍵對MySQL性能有影響?

數(shù)據(jù)庫 MySQL
今天我們來分析一下,用雪花算法生成的ID做主鍵,對MySQL性能到底有沒有影響?MySQL必須使用連續(xù)遞增的主鍵才能發(fā)揮最大性能?

公司最近開發(fā)了一個新項目,設計表時由于有些字段需要對外展示,所以使用了雪花算法生成的id做主鍵。

不過有位同事對此提出了異議,認為雪花算法生成的id不是順序遞增的,會對MySQL的性能造成影響。

經(jīng)過交流,發(fā)現(xiàn)持有這種認知的還有好幾位同事,估摸著對此有疑問的朋友也不少,所以今天我們來分析一下,用雪花算法生成的id做主鍵,對MySQL性能到底有沒有影響?MySQL必須使用連續(xù)遞增的主鍵才能發(fā)揮最大性能?

既然要分析不同主鍵的性能,那么就得先了解一下MySQL的數(shù)據(jù)是如何存儲的。

相信只要稍微了解過MySQL的朋友估計都知道,MySQL的InnoDB引擎采用B+樹來存儲數(shù)據(jù),為了數(shù)據(jù)的安全性,這些數(shù)據(jù)最終會持久化到磁盤上。

那么我們在查詢或者修改數(shù)據(jù)時,如果每次都把數(shù)據(jù)全部從磁盤加載到內(nèi)存好像不太現(xiàn)實,每次只讀一條數(shù)據(jù)又太浪費IO,那怎么辦呢?

于是設計MySQL的這些大神們提出了頁的概念,即將數(shù)據(jù)保存到很多個頁上面,內(nèi)存和磁盤交互時以頁為單位。

默認情況下,一個頁的大小是16KB,也就是說,每次從磁盤會最少加載16KB的數(shù)據(jù)到內(nèi)存里。反過來,每次最少把16KB的數(shù)據(jù)從內(nèi)存中持久化到磁盤。

這樣,時間和空間都利用到了,最大化的保證了性能。

當然,頁的種類也有很多,比如保存表空間信息的頁,undo日志頁,存放數(shù)據(jù)的數(shù)據(jù)頁等,本文中我們只討論數(shù)據(jù)頁和目錄頁。

下圖就是一個InnoDB數(shù)據(jù)頁的結構,大家心里有一個印象即可。

User Records就是用來真正保存我們的數(shù)據(jù)的,我們看一下數(shù)據(jù)是如何在頁中保存的。

需要特別注意的是,為了性能,這些記錄是按照主鍵的大小按從小到大順序排放的,最終組成一個單向鏈表。另外每個數(shù)據(jù)頁都會生成一個頁目錄,通過主鍵查找某一條記錄時通過二分查找法即可快速找到需要的數(shù)據(jù)。

上面我們提過,一個頁默認只有16KB,也就是說存儲的數(shù)據(jù)是有限的,所以當要存儲很多數(shù)據(jù)時,就需要申請很多數(shù)據(jù)頁,如下所示:

從上圖中我們可以看到,每個數(shù)據(jù)頁都保存了很多條記錄,相鄰頁之間還通過雙向鏈表保存著聯(lián)系。

需要注意的是,這些數(shù)據(jù)頁在物理空間上不一定是連續(xù)的地址。

到這里我們知道了MySQL通過數(shù)據(jù)頁來存儲數(shù)據(jù),但是隨著表數(shù)據(jù)的增多,會帶來一個很明顯的問題:頁太多了不好管理。

所以InnoDB的大神們又設計了目錄頁(目錄頁+數(shù)據(jù)頁就組成了一顆索引樹)。

看名字也知道,目錄頁只是一個目錄,不會存儲具體的數(shù)據(jù)。

它保存的數(shù)據(jù)其實特別簡單:主鍵和頁號。

從上圖中我們可以看到,頁30是一個目錄頁(可以把他當做樹的根節(jié)點),頁10、頁28、頁9、頁20是真正存放數(shù)據(jù)的數(shù)據(jù)頁。

在目錄頁中,會存放每一個數(shù)據(jù)頁的最小主鍵id以及對應的頁號,并且按照主鍵id排序。

在數(shù)據(jù)頁中,數(shù)據(jù)也是按照主鍵從小到大排序的,并且后一個頁的最小記錄會比上一個頁的最大記錄大,總體來說,這些頁的數(shù)據(jù)是遞增的。

注意!是遞增,但是并沒有要求順序遞增。

因為對于二分查找法來說,只要數(shù)據(jù)是有序遞增的,就可以保證其快速查找到我們需要的數(shù)據(jù)了。

以查找id=8的記錄為例,首先在根節(jié)點通過二分查找法找到記錄5,對應的頁號是28,然后找到頁28,通過二分法找到主鍵為8的記錄。

現(xiàn)在回到我們的問題,雪花算法生成的id會對MySQL性能造成影響嗎?

雪花算法的一大特性是什么呢?

大致遞增。

換句話說,只要是遞增的,哪怕我們用JAVA的AtomicInteger或者通過redis的incrmentBy來生成主鍵id也沒問題。

雪花算法就不過多介紹了,有想了解的朋友可以看一下這篇文章。??雪花算法介紹??。

另外再多說一句:MySQL自增主鍵雖然申請時是表級全局遞增的,但是最后保存到表中就不一定了。

舉個簡單的例子,批量保存10條數(shù)據(jù),由于某些原因,這個事務操作回滾了。當你再插入一條數(shù)據(jù)時,你會發(fā)現(xiàn)上次申請的10個id已經(jīng)被浪費掉了,表中的id是從11開始的。

MySQL的數(shù)據(jù)結構和索引是一個龐大的系統(tǒng),很難通過一篇簡單的文章將其徹底講清楚,如果你對本文有不同見解,也歡迎在評論區(qū)交流。

責任編輯:姜華 來源: 今日頭條
相關推薦

2019-09-05 13:06:08

雪花算法分布式ID

2020-04-01 16:32:55

SQL數(shù)據(jù)庫MySQL

2021-11-25 06:54:54

NginxHTTP服務器

2022-04-28 08:52:40

懶加載Web

2022-02-23 07:09:30

分布式ID雪花算法

2018-08-08 15:34:09

功率電源性能

2023-12-12 07:13:39

雪花算法分布式ID

2010-10-11 11:31:27

MySQL主鍵

2009-11-19 10:27:07

路由器設置

2015-02-12 09:14:41

2020-08-31 11:20:53

MySQLuuidid

2024-12-04 09:36:37

2024-12-25 15:32:29

2024-12-04 08:38:29

2022-11-17 08:00:18

JavaScript錯誤性能

2020-10-27 09:42:26

戴爾VMware分拆VMware

2022-12-15 08:00:38

JavaScript錯誤性能

2024-02-02 10:57:12

Java分布式算法

2012-05-07 08:18:42

程序日志性能

2022-06-14 18:35:01

ID生成器語言
點贊
收藏

51CTO技術棧公眾號