解決mysql的int型主鍵自增問(wèn)題
引入
我們?cè)谑褂胢ysql數(shù)據(jù)庫(kù)時(shí),習(xí)慣使用int型作為主鍵,并設(shè)置為自增,這既能夠保證唯一,使用起來(lái)又很方便,但int型的長(zhǎng)度是有限的,如果超過(guò)長(zhǎng)度怎么辦呢?
暴露問(wèn)題
我們先創(chuàng)建一個(gè)測(cè)試表,創(chuàng)建語(yǔ)句如下:
CREATE TABLE test1 ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20) )
然后我們插入兩條數(shù)據(jù):
INSERT INTO test1 VALUES(NULL,'小牛'); INSERT INTO test1 VALUES(NULL,'大牛');
查詢表顯示正常:
int型的有符號(hào)的范圍為231 -1 = 2147483647,我們直接插入一條數(shù)據(jù)id為2147483647,如下:
INSERT INTO test1 VALUES(2147483647 ,'小華')
結(jié)果顯示正常:
此時(shí)自增ID已達(dá)到了int型的上限,如果我再插入數(shù)據(jù),就會(huì)報(bào)錯(cuò):
INSERT INTO test1 VALUES(NULL,'母牛');
此時(shí)主鍵已無(wú)法自增,插入的id仍然是2147483647,就違反了主鍵唯一的條件,所以報(bào)錯(cuò)。
解決問(wèn)題
(1)使用更大的數(shù)據(jù)類型bigint
bigint的范圍是263-1,所謂指數(shù)爆炸,此時(shí)的大小達(dá)到了9,223,372,036,854,775,807的可怕量級(jí),簡(jiǎn)單來(lái)說(shuō)就是用bigint 一天100w條數(shù)據(jù)也得存200億年才能自增爆炸,所以在當(dāng)前場(chǎng)景,幾乎不用擔(dān)心bigint會(huì)自增滿
我們修改數(shù)據(jù)類型為bigint,如圖
再執(zhí)行插入語(yǔ)句:
INSERT INTO test1 VALUES(NULL,'母牛');
又能夠正常插入了:
(2)使用UUID作為主鍵
我們都知道,UUID會(huì)根據(jù)當(dāng)前系統(tǒng)性能,時(shí)間戳等一系列參數(shù)經(jīng)過(guò)運(yùn)算得到一個(gè)全世界唯一的字符串,并且mysql提供了生成UUID的方法,用它作為主鍵能夠保證數(shù)據(jù)的唯一性。
利用如下代碼可以生成32位的UUID:
-- 生成32位UUID SELECT REPLACE(UUID(),'-','') AS UUID;
然后咱們?cè)賱?chuàng)建一個(gè)測(cè)試表:
CREATE TABLE test2( id VARCHAR(50) PRIMARY KEY, NAME VARCHAR(20) NOT NULL )
插入一條數(shù)據(jù):
-- 插入U(xiǎn)UID INSERT INTO test2 VALUES(REPLACE(UUID(),'-',''),'老王');
但這樣寫插入語(yǔ)句每次都要手寫UUID函數(shù),貌似有點(diǎn)太麻煩了,咱們可以寫一個(gè)觸發(fā)器,讓觸發(fā)器自動(dòng)為我們?cè)O(shè)置ID:
-- 創(chuàng)建觸發(fā)器 DELIMITER $$ CREATE TRIGGER auto_id -- 名稱 BEFORE INSERT -- 觸發(fā)時(shí)機(jī) ON test2 FOR EACH ROW -- 作用于test2表,對(duì)每行數(shù)據(jù)生效 BEGIN IF new.id = '' THEN -- 當(dāng)id為空字符串時(shí)設(shè)置UUID SET new.id = REPLACE(UUID(),'-',''); END IF; END$$
插入一條數(shù)據(jù):
-- 插入一條數(shù)據(jù) INSERT INTO test2 VALUES('','小王');
結(jié)果能正常添加
總結(jié)
(1) 用int型和bigInt型增刪改查速度較UUID更快,并且更節(jié)省空間。
(2) 用UUID更方便。
為何要使用自增int作為主鍵
相信大家都知道要使用無(wú)符號(hào)自增int作為主鍵的數(shù)據(jù)類型,可你知道為何要使自用增int而不是使用varchar、text、varchar等類型嗎?
大家也能說(shuō)出一些優(yōu)點(diǎn):對(duì)上層業(yè)務(wù)透明,插入數(shù)據(jù)時(shí)無(wú)需顯示指定;數(shù)據(jù)類型簡(jiǎn)單,更便于存儲(chǔ)維護(hù)表結(jié)構(gòu)
其實(shí),使用自增int作為主鍵好處多多,今天我們就來(lái)一起學(xué)習(xí)一下,并強(qiáng)烈建議大家在實(shí)際開(kāi)發(fā)中使用自增int作為主鍵。
優(yōu)點(diǎn):
1、int 相比varchar、char、text使用更少的存儲(chǔ)空間,而且數(shù)據(jù)類型簡(jiǎn)單,可以節(jié)約CPU的開(kāi)銷,更便于表結(jié)構(gòu)的維護(hù)
2、默認(rèn)都會(huì)在主鍵上建立主鍵索引,使用整形作為主鍵可以將更多的索引載入內(nèi)存,提高查詢性能
3、對(duì)于InnoDB存儲(chǔ)引擎而言,每個(gè)二級(jí)索引都會(huì)使用主鍵作為索引值的后綴,使用自增主鍵可以減少索引的長(zhǎng)度(大?。?,方便更多的索引數(shù)據(jù)載入內(nèi)存
4、可以使索引數(shù)據(jù)更加緊湊,在數(shù)據(jù)插入、刪除、更新時(shí)可以做到索引數(shù)據(jù)盡可能少的移動(dòng)、分裂頁(yè),減少碎片的產(chǎn)生(可以通過(guò)optimize table 來(lái)重建表),減少維護(hù)開(kāi)銷
5、在數(shù)據(jù)插入時(shí),可以保證邏輯相鄰的元素物理也相鄰,便于范圍查找
當(dāng)然,使用自增int作為主鍵也不是百利無(wú)一害,在高并發(fā)的情況下也可能會(huì)造成鎖的爭(zhēng)用問(wèn)題。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mysql8.0數(shù)據(jù)庫(kù)無(wú)法被遠(yuǎn)程連接問(wèn)題排查小結(jié)
本文主要介紹了mysql8.0數(shù)據(jù)庫(kù)無(wú)法被遠(yuǎn)程連接問(wèn)題排查小結(jié)2024-07-07解決Mysql服務(wù)器啟動(dòng)時(shí)報(bào)錯(cuò)問(wèn)題的方法
這篇文章主要介紹了解決Mysql服務(wù)器啟動(dòng)時(shí)報(bào)錯(cuò)問(wèn)題的方法,需要的朋友可以參考下2015-11-11MySQL數(shù)據(jù)庫(kù)中CAST與CONVERT函數(shù)實(shí)現(xiàn)類型轉(zhuǎn)換的講解
今天小編就為大家分享一篇關(guān)于MySQL數(shù)據(jù)庫(kù)中CAST與CONVERT函數(shù)實(shí)現(xiàn)類型轉(zhuǎn)換的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03win2008下mysql8.0.11升級(jí)mysql8.0.17版本詳細(xì)步驟
這篇文章主要為大家詳細(xì)介紹了win2008下mysql8.0.11升級(jí)mysql8.0.17版本詳細(xì)步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08Mysql添加用戶和設(shè)置權(quán)限的操作方法
這篇文章主要介紹了Mysql添加用戶和設(shè)置權(quán)限的操作方法,主要包括管理用戶,權(quán)限控制的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07如何通過(guò)yum方式安裝mysql數(shù)據(jù)庫(kù)
部署MySQL數(shù)據(jù)庫(kù)有多種部署方式,常用的部署方式就有三種,yum安裝、rpm安裝以及編譯安裝,這篇文章主要給大家介紹了關(guān)于如何如果通過(guò)yum方式安裝mysql數(shù)據(jù)庫(kù)的相關(guān)資料,需要的朋友可以參考下2024-01-01