如何解決MySQL自增ID用完的問題

本篇內(nèi)容介紹了“如何解決MySQL自增ID用完的問題”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

蒼溪網(wǎng)站建設公司成都創(chuàng)新互聯(lián)公司,蒼溪網(wǎng)站設計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為蒼溪上1000家提供企業(yè)網(wǎng)站建設服務。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢,請找那個售后服務好的蒼溪做網(wǎng)站的公司定做!

如何解決MySQL自增ID用完的問題

自增id

說到自增id,相信你的第一反應一定是在設計表結(jié)構(gòu)的時候自定義一個自增id字段,那么就有一個問題啦,在插入數(shù)據(jù)時有可能唯一主鍵沖、sql事務回滾、批量插入的時候,批量申請自增值等原因?qū)е伦栽鰅d是不連續(xù)的。

表定義的自增值達到上線后的邏輯是:再申請下一個id的時候,獲取的是同一個值(最大值)。大家可以插入sql設置id是最大值,再insert一條不主動設置id的語句就可以驗證這一結(jié)論啦。這個時候如果再插入就是報主鍵沖突咯~

這里提醒一下:232-1(4294967295)不是一個特別大的數(shù),對于一個頻繁插入刪除數(shù)據(jù)的表來說,是可能會被用完的。因此在建表的時候你需要考察你的表是否有可能達到這個上限,如果有可能,就應該創(chuàng)建成 8 個字節(jié)的 bigint unsigned。

InnoDB系統(tǒng)自增row_id

如果你創(chuàng)建的 InnoDB 表沒有指定主鍵,那么 InnoDB 會給你創(chuàng)建一個不可見的,長度為 6 個字節(jié)的 row_id。InnoDB 維護了一個全局的 dict_sys.row_id 值,所有無主鍵的 InnoDB 表,每插入一行數(shù)據(jù),都將當前的 dict_sys.row_id 值作為要插入數(shù)據(jù)的 row_id,然后把 dict_sys.row_id 的值加 1。

實際上,在代碼實現(xiàn)時 row_id 是一個長度為8字節(jié)的無符號長整型 (bigint unsigned)。但是,InnoDB 在設計時,給 row_id 留的只是 6 個字節(jié)的長度,這樣寫到數(shù)據(jù)表中時只放了最后 6 個字節(jié),所以 row_id 能寫到數(shù)據(jù)表中的值,就有兩個特征:

row_id 寫入表中的值范圍,是從 0 到 248-1;

當 dict_sys.row_id=2^48時,如果再有插入數(shù)據(jù)的行為要來申請 row_id,拿到以后再取最后 6 個字節(jié)的話就是 0。

雖然,2^48這個數(shù)字已經(jīng)很大了,但是大家要知道 一個系統(tǒng)是可以跑很久的,那么還是可能達到上限的,這時候再申請就會覆蓋原來的記錄了。因此,盡量不要選擇這種方式!

Xid

MySQL中redo log 和 binlog 相配合的時候,它們有一個共同的字段叫作 Xid。它在 MySQL 中是用來對應事務的。

MySQL 內(nèi)部維護了一個全局變量 global_query_id,每次執(zhí)行語句的時候?qū)⑺x值給 Query_id,然后給這個變量加 1。如果當前語句是這個事務執(zhí)行的第一條語句,那么 MySQL 還會同時把 Query_id 賦值給這個事務的 Xid。而 global_query_id 是一個純內(nèi)存變量,重啟之后就清零了。所以在同一個數(shù)據(jù)庫實例中,不同事務的 Xid 也是有可能相同的。

Innodb trx_id

InnoDB 內(nèi)部維護了一個 max_trx_id 全局變量,每次需要申請一個新的 trx_id 時,就獲得 max_trx_id 的當前值,然后并將 max_trx_id 加 1。

InnoDB 數(shù)據(jù)可見性的核心思想是:每一行數(shù)據(jù)都記錄了更新它的 trx_id,當一個事務讀到一行數(shù)據(jù)的時候,判斷這個數(shù)據(jù)是否可見的方法,就是通過事務的一致性視圖與這行數(shù)據(jù)的 trx_id 做對比。但是這個過程有臟讀存在,那么這個id就不會是原子性的,存在重復的可能性。

thread_id

其實,線程 id 才是 MySQL 中最常見的一種自增 id。平時我們在查各種現(xiàn)場的時候,show processlist 里面的第一列,就是 thread_id。

thread_id 的邏輯很好理解:系統(tǒng)保存了一個全局變量 thread_id_counter,每新建一個連接,就將 thread_id_counter 賦值給這個新連接的線程變量。

thread_id_counter 定義的大小是 4 個字節(jié),因此達到 232-1 后,它就會重置為 0,然后繼續(xù)增加。結(jié)果跟row_id一樣,就會覆蓋原有記錄了。

上面介紹了幾種MySQL自身的一些自增id,其實,實際運用中,我們也可能會選擇外部的自增主鍵,然后持久化到數(shù)據(jù)庫,以此來代替數(shù)據(jù)庫自身的自增id。下面來說說吧。

redis自增主鍵

其實外部自增主鍵的生成方式有很多,為什么我要介紹redis呢?因為我自己在實際應用中使用發(fā)現(xiàn)它的很多優(yōu)點。

redis自身是原子性的,因此高并發(fā)也是線程安全的。假設主鍵字段長度20,我們以時間+自增數(shù)來構(gòu)成主鍵,例如:8位日期+12自增數(shù)。那么,根據(jù)業(yè)務性質(zhì)可以決定時間取年月日或者到毫秒級,那么在毫秒之間自增數(shù)的重復概率是極小極小的,基本的業(yè)務都能適用。

“如何解決MySQL自增ID用完的問題”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

當前名稱:如何解決MySQL自增ID用完的問題
轉(zhuǎn)載來源:http://muchs.cn/article24/gphcje.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設計公司、品牌網(wǎng)站建設、軟件開發(fā)、網(wǎng)站導航微信小程序、服務器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運營