你好,歡迎進(jìn)入江蘇優(yōu)軟數(shù)字科技有限公司官網(wǎng)!
發(fā)布時(shí)間:2024-01-14
瀏覽次數(shù):0
大家好,我是雷哥。
如果你使用過(guò)或了解MySQL,你一定知道自增主鍵。 每個(gè)自增ID都定義了一個(gè)初始值,然后按照指定的步長(zhǎng)(默認(rèn)步長(zhǎng)為1)遞增。 雖然自然數(shù)沒(méi)有上限,但我們?cè)谠O(shè)計(jì)表結(jié)構(gòu)時(shí),通常會(huì)指定字段長(zhǎng)度。 然后intellij idea 重置默認(rèn)視圖,id有一個(gè)上限。 既然有上限,那么總會(huì)有用完的時(shí)候。 ID用完了怎么辦? 今天我們一起來(lái)學(xué)習(xí)一下。
自增id
說(shuō)到自增id,相信大家的第一反應(yīng)一定是在設(shè)計(jì)表結(jié)構(gòu)的時(shí)候自定義一個(gè)自增id字段。 那么有一個(gè)問(wèn)題。 插入數(shù)據(jù)時(shí),可能存在唯一主鍵沖突、SQL事務(wù)回滾、批量插入時(shí)、批??量申請(qǐng)自增等原因?qū)е伦栽鯥D不連續(xù)。
注意
文末:3625頁(yè)各大互聯(lián)網(wǎng)公司面試題
表中定義的自增值上線后的邏輯是:申請(qǐng)下一個(gè)ID時(shí),會(huì)得到相同的值(最大值)。 可以插入sql將id設(shè)置為最大值,另外一個(gè)不主動(dòng)設(shè)置id的語(yǔ)句可以驗(yàn)證這個(gè)結(jié)論。 如果這個(gè)時(shí)候再插入就會(huì)報(bào)主鍵沖突~
這里提醒一下:232-1()并不是一個(gè)特別大的數(shù)字。 對(duì)于一張頻繁插入、刪除數(shù)據(jù)的表,可能會(huì)被用完。 因此,在建表的時(shí)候,需要考察一下你的表是否有可能達(dá)到這個(gè)上限。 如果可能的話,應(yīng)該用 8 個(gè)字節(jié)來(lái)創(chuàng)建。
系統(tǒng)自增
如果您創(chuàng)建的表沒(méi)有指定主鍵,則會(huì)為您創(chuàng)建一個(gè)不可見的、長(zhǎng)度為6字節(jié)的主鍵。 一個(gè)全球性的. 值得以維持。 對(duì)于所有沒(méi)有主鍵的表,每插入一行數(shù)據(jù),當(dāng)前的 . value作為要插入的數(shù)據(jù),然后 的值。 增加了 1。
事實(shí)上,代碼實(shí)現(xiàn)時(shí),是一個(gè)長(zhǎng)度為8個(gè)字節(jié)的無(wú)符號(hào)長(zhǎng)整型( )。 但設(shè)計(jì)時(shí)只留下了6個(gè)字節(jié)的長(zhǎng)度,所以寫入數(shù)據(jù)表時(shí)只放最后6個(gè)字節(jié)。 因此,可以寫入數(shù)據(jù)表的值有兩個(gè)特點(diǎn):
寫入表中的取值范圍為0~248-1; 當(dāng).=2^48時(shí),如果有另外申請(qǐng)插入數(shù)據(jù),則獲取后最后6個(gè)字節(jié)為0。
雖然2^48這個(gè)數(shù)字已經(jīng)很大了,但是要知道一個(gè)系統(tǒng)可以運(yùn)行很長(zhǎng)時(shí)間,所以達(dá)到上限還是有可能的。 此時(shí)再次申請(qǐng)會(huì)覆蓋原來(lái)的記錄。 所以,盡量不要選擇這個(gè)選項(xiàng)!
西德
當(dāng)重做日志和重做日志在MySQL中組合在一起時(shí),它們有一個(gè)共同的字段,稱為Xid。 它用來(lái)對(duì)應(yīng)MySQL中的事務(wù)。
MySQL內(nèi)部維護(hù)了一個(gè)全局變量,每次執(zhí)行語(yǔ)句的時(shí)候都會(huì)給它賦值,然后這個(gè)變量加1。 如果當(dāng)前語(yǔ)句是該事務(wù)執(zhí)行的第一條語(yǔ)句,MySQL也會(huì)同時(shí)將該值賦給該事務(wù)的Xid。 它是一個(gè)純內(nèi)存變量,重啟后會(huì)被清除。 因此,在同一個(gè)數(shù)據(jù)庫(kù)實(shí)例中,不同事務(wù)的Xid可能是相同的。
全局變量在內(nèi)部維護(hù)。 每次需要申請(qǐng)新的時(shí)候,就獲取當(dāng)前的值,然后加1。
數(shù)據(jù)可見性的核心思想是:每一行數(shù)據(jù)都記錄對(duì)其的更新。 當(dāng)事務(wù)讀取一行數(shù)據(jù)時(shí),判斷該數(shù)據(jù)是否可見的方法是比較事務(wù)的一致性視圖與該行數(shù)據(jù)。 。 但是這個(gè)過(guò)程中存在臟讀,所以ID不會(huì)是原子的intellij idea 重置默認(rèn)視圖,存在重復(fù)的可能。
事實(shí)上,線程ID是MySQL中最常見的自增ID。 通常當(dāng)我們查看各種場(chǎng)景時(shí),顯示的第一欄是。
邏輯很容易理解:系統(tǒng)保存了一個(gè)全局變量,每次創(chuàng)建一個(gè)新連接時(shí),都會(huì)將其賦值給這個(gè)新連接的線程變量。
定義的大小是 4 字節(jié),因此一旦達(dá)到 232-1,它就會(huì)重置為 0 并繼續(xù)增加。 結(jié)果是一樣的,原來(lái)的記錄會(huì)被覆蓋。
上面介紹了MySQL自帶的一些自增ID。 其實(shí)在實(shí)際應(yīng)用中,我們也可以選擇外部自增主鍵,然后持久化到數(shù)據(jù)庫(kù)中,來(lái)代替數(shù)據(jù)庫(kù)自身的自增ID。 下面我們就來(lái)談?wù)劙伞?/p>
Redis自增主鍵
事實(shí)上,生成外部自增主鍵的方法有很多種。 為什么要引入redis? 因?yàn)槲以趯?shí)際應(yīng)用中發(fā)現(xiàn)了它的很多優(yōu)點(diǎn)。
Redis本身是原子的,所以高并發(fā)也是線程安全的。 假設(shè)主鍵字段長(zhǎng)度為20,我們使用時(shí)間+自增數(shù)組成主鍵,例如:8位日期+12位自增數(shù)。 然后根據(jù)業(yè)務(wù)性質(zhì),可以將時(shí)間確定為年、月、日、毫秒級(jí)別。 那么毫秒之間重復(fù)自增數(shù)的概率極小,可以應(yīng)用于基礎(chǔ)業(yè)務(wù)。
總結(jié)
上面介紹了幾種自增ID。 每個(gè)自增ID都有自己的應(yīng)用場(chǎng)景,達(dá)到上限后的表現(xiàn)也不同:
1、表的自增ID達(dá)到上限后,再次申請(qǐng)時(shí)其值不會(huì)改變,這會(huì)導(dǎo)致繼續(xù)插入數(shù)據(jù)時(shí)出現(xiàn)主鍵沖突的錯(cuò)誤。
2、達(dá)到上限后,會(huì)返回0,然后再次遞增。 如果出現(xiàn)同樣的情況,后面寫入的數(shù)據(jù)會(huì)覆蓋前面的數(shù)據(jù)。
3、Xid只需避免同一個(gè)文件中出現(xiàn)重復(fù)值即可。雖然理論上可能會(huì)出現(xiàn)重復(fù)值,但概率極小,可以忽略不計(jì)。
4. 每次MySQL重啟時(shí)都會(huì)保存增加的值,所以我們文章中提到的臟讀示例是一個(gè)不可避免會(huì)出現(xiàn)的bug。 幸運(yùn)的是,留給我們的時(shí)間還很充裕。
5、是我們使用的最常見、最好處理的自增ID邏輯。
6.Redis外部自增,毫秒級(jí),理論上會(huì)出現(xiàn)重復(fù)值,但概率極小,可以忽略
7、其實(shí)每個(gè)自增ID都有其適用的場(chǎng)景。 您可以根據(jù)日常使用的具體場(chǎng)景進(jìn)行選擇。 但要未雨綢繆,因?yàn)楸仨毧紤]系統(tǒng)運(yùn)行時(shí)間和數(shù)據(jù)存儲(chǔ)。 綜合考慮,選擇在系統(tǒng)運(yùn)行過(guò)程中不會(huì)立即重復(fù)的一項(xiàng)。 你學(xué)會(huì)了嗎?
近期熱門技術(shù)文章
過(guò)去推薦的
第三版:各大互聯(lián)網(wǎng)公司面試題
包括Java集合、JVM、多線程、并發(fā)編程、設(shè)計(jì)模式、算法調(diào)優(yōu)、全家桶、Java、Dubbo、Redis、MySQL、Kafka、Linux、Netty、HTML、CSS、Vue、React、大數(shù)據(jù)、阿里巴巴等大公司面試題等等,還有其他技術(shù)棧!
如有侵權(quán)請(qǐng)聯(lián)系刪除!
Copyright ? 2023 江蘇優(yōu)軟數(shù)字科技有限公司 All Rights Reserved.正版sublime text、Codejock、IntelliJ IDEA、sketch、Mestrenova、DNAstar服務(wù)提供商
13262879759
微信二維碼