MySQL使用UUID_SHORT()的問題解決
問題說明
表app_msg
的主鍵id 設(shè)置的類型為:bigint 20
使用插入語句:INSERT INTO
app_msg(
id,...) VALUES (UUID_SHORT(),...)
然而系統(tǒng)報錯:[Err] 1264 - Out of range value for column 'id' at row 1
在測試環(huán)境使用時沒有問題,但是在準(zhǔn)生產(chǎn)數(shù)據(jù)庫使用時報錯了
簡單分析解決
分析
在兩個數(shù)據(jù)庫查看UUID_SHORT()生成的情況:
select UUID_SHORT() --結(jié)果1:26047177025388691 這里生成了17位的UUID_SHORT --結(jié)果2:18040425909390934036 這里生成了20位的UUID_SHORT
結(jié)果1為17位沒問題,結(jié)果2位20位導(dǎo)致報錯的時候超過最大值
解決
這里可以知道原因是在字段類型上面,bigint 20 對應(yīng)的類型是 long long 類型 【長度為:(-2^63 ~ 2^63-1) 10^18 19位數(shù)字】;
而UUID_SHORT() 返回的是 unsigned long long 類型【長度為:(0 ~ 2^64-1) 10^19 20位數(shù)字】
所以,原因是在MySQL設(shè)置的時候沒有**勾選無符號****這個選項導(dǎo)致的,勾選上就解決了。╮(╯▽╰)╭ 就是這么的簡單的地方。
臨時解決方式,使用時間錯手動生成了一個19位以內(nèi)的隨機id:
FLOOR(REPLACE(unix_timestamp(current_timestamp(3)),'.',''))*10000+FLOOR(RAND()*10000)
認(rèn)真查了一些詳細(xì)的資料
官方資料
版本:MySQL 5.7
UUID_SHORT()
將“ 短 ”通用標(biāo)識符作為64位無符號整數(shù)返回。返回的值 UUID_SHORT()與UUID()函數(shù)返回的字符串格式128位標(biāo)識符 不同,并且具有不同的唯一性屬性。UUID_SHORT()如果滿足以下條件,則保證值 是唯一的:
- 在server_id當(dāng)前服務(wù)器的值介于0和255之間,您的設(shè)置主從服務(wù)器中是唯一的
- 您不會在mysqld restarts 之間設(shè)置服務(wù)器主機的系統(tǒng)時間
- UUID_SHORT()在mysqld重啟 之間, 你平均每秒調(diào)用的次數(shù)少于1600萬次
該UUID_SHORT()返回值的構(gòu)造是這樣的:
(server_id & 255) << 56 + (server_startup_time_in_seconds << 24) + incremented_variable++;
mysql> SELECT UUID_SHORT(); -> 92395783831158784
UUID_SHORT() 不適用于基于語句的復(fù)制。
按照以上官方的說法,UUID_SHORT返回的值為64位無符號整數(shù),也就是unsigned long long類型。而且,由于使用到了時間搓,這個的初始值會很大(通常都會到17位數(shù)字)。
但是,這并不保證其不會返回18,19,20位的數(shù)據(jù),只能保證在2^64-1以內(nèi)(最大達到20位數(shù)字);
目前沒有查到說可以調(diào)整或初始設(shè)置UUID_SHORT() 的配置
補充BUG–Java數(shù)據(jù)接收錯誤
在數(shù)據(jù)庫使用了無符號bigint類型之后,使用UUID_SHORT()進行生產(chǎn)id的時候,數(shù)據(jù)庫是可以插入,沒有問題的。
**但是,**由于使用的是JAVA的Long類型進行數(shù)據(jù)接收,這里有可能是會超出長度的。【數(shù)據(jù)為無符號long類型這里差了1位】
因為,JAVA本身的基本類型是不支持無符號類型的,所以這里的轉(zhuǎn)換會有問題。
而且,由于是已經(jīng)遇到了,上面開始的那個BUG,這里是肯定是會超出的。【UUID_SHORT的值是在mysql啟動的時候自動配置的,所以相當(dāng)?shù)臒o奈╮(╯_╰)╭】
所以這里,特別說明記錄一下,這個問題。
解決辦法:目前還是使用 【自定義的ID生成】,或者 上面 的臨時解決方式【時間戳拼接】其實最好的還是使用32位的UUID比較的好
到此這篇關(guān)于MySQL使用UUID_SHORT()的問題解決的文章就介紹到這了,更多相關(guān)MySQL UUID_SHORT()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql按照天統(tǒng)計報表當(dāng)天沒有數(shù)據(jù)填0的實現(xiàn)代碼
這篇文章主要介紹了mysql按照天統(tǒng)計報表當(dāng)天沒有數(shù)據(jù)填0的實現(xiàn)方法,需要的朋友可以參考下2018-01-01MySQL從命令行導(dǎo)入SQL腳本時出現(xiàn)中文亂碼的解決方法
這篇文章主要介紹了MySQL從命令行導(dǎo)入SQL腳本時出現(xiàn)中文亂碼的解決方法,分析了中文亂碼出現(xiàn)的原因并給出了兩種解決方法供大家參考,需要的朋友可以參考下2016-09-09Windows7下Python3.4使用MySQL數(shù)據(jù)庫
這篇文章主要為大家詳細(xì)介紹了Windows7下Python3.4使用MySQL數(shù)據(jù)庫,MySQL Community Server的安裝步驟,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07