MySQL使用UUID_SHORT()的問題解決
問題說明
表app_msg
的主鍵id 設(shè)置的類型為:bigint 20
使用插入語句:INSERT INTO
app_msg(
id,...) VALUES (UUID_SHORT(),...)
然而系統(tǒng)報(bào)錯(cuò):[Err] 1264 - Out of range value for column 'id' at row 1
在測試環(huán)境使用時(shí)沒有問題,但是在準(zhǔn)生產(chǎn)數(shù)據(jù)庫使用時(shí)報(bào)錯(cuò)了
簡單分析解決
分析
在兩個(gè)數(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)致報(bào)錯(cuò)的時(shí)候超過最大值
解決
這里可以知道原因是在字段類型上面,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è)置的時(shí)候沒有**勾選無符號****這個(gè)選項(xiàng)導(dǎo)致的,勾選上就解決了。╮(╯▽╰)╭ 就是這么的簡單的地方。
臨時(shí)解決方式,使用時(shí)間錯(cuò)手動(dòng)生成了一個(gè)19位以內(nèi)的隨機(jī)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ù)器中是唯一的
- 您不會(huì)在mysqld restarts 之間設(shè)置服務(wù)器主機(jī)的系統(tǒng)時(shí)間
- 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類型。而且,由于使用到了時(shí)間搓,這個(gè)的初始值會(huì)很大(通常都會(huì)到17位數(shù)字)。
但是,這并不保證其不會(huì)返回18,19,20位的數(shù)據(jù),只能保證在2^64-1以內(nèi)(最大達(dá)到20位數(shù)字);
目前沒有查到說可以調(diào)整或初始設(shè)置UUID_SHORT() 的配置
補(bǔ)充BUG–Java數(shù)據(jù)接收錯(cuò)誤
在數(shù)據(jù)庫使用了無符號bigint類型之后,使用UUID_SHORT()進(jìn)行生產(chǎn)id的時(shí)候,數(shù)據(jù)庫是可以插入,沒有問題的。
**但是,**由于使用的是JAVA的Long類型進(jìn)行數(shù)據(jù)接收,這里有可能是會(huì)超出長度的。【數(shù)據(jù)為無符號long類型這里差了1位】
因?yàn)?,JAVA本身的基本類型是不支持無符號類型的,所以這里的轉(zhuǎn)換會(huì)有問題。
而且,由于是已經(jīng)遇到了,上面開始的那個(gè)BUG,這里是肯定是會(huì)超出的。【UUID_SHORT的值是在mysql啟動(dòng)的時(shí)候自動(dòng)配置的,所以相當(dāng)?shù)臒o奈╮(╯_╰)╭】
所以這里,特別說明記錄一下,這個(gè)問題。
解決辦法:目前還是使用 【自定義的ID生成】,或者 上面 的臨時(shí)解決方式【時(shí)間戳拼接】其實(shí)最好的還是使用32位的UUID比較的好
到此這篇關(guān)于MySQL使用UUID_SHORT()的問題解決的文章就介紹到這了,更多相關(guān)MySQL UUID_SHORT()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql按照天統(tǒng)計(jì)報(bào)表當(dāng)天沒有數(shù)據(jù)填0的實(shí)現(xiàn)代碼
這篇文章主要介紹了mysql按照天統(tǒng)計(jì)報(bào)表當(dāng)天沒有數(shù)據(jù)填0的實(shí)現(xiàn)方法,需要的朋友可以參考下2018-01-01MySQL從命令行導(dǎo)入SQL腳本時(shí)出現(xiàn)中文亂碼的解決方法
這篇文章主要介紹了MySQL從命令行導(dǎo)入SQL腳本時(shí)出現(xiàn)中文亂碼的解決方法,分析了中文亂碼出現(xiàn)的原因并給出了兩種解決方法供大家參考,需要的朋友可以參考下2016-09-09MySQL CHAR和VARCHAR存儲、讀取時(shí)的差別
這篇文章主要介紹了MySQL CHAR和VARCHAR存儲的差別,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下2020-11-11MySQL數(shù)據(jù)庫遠(yuǎn)程連接開啟方法
有時(shí)候需要遠(yuǎn)程連接mysql數(shù)據(jù)庫,默認(rèn)是不可以的,大家可以參考下面的方法,解決下。2010-08-08小心陷阱!MySQL中處理Null時(shí)需注意兩點(diǎn)
這篇文章主要為大家介紹了MySQL中處理Null時(shí)需注意的兩點(diǎn),很關(guān)鍵的兩點(diǎn),大家千萬要小心2016-06-06Windows7下Python3.4使用MySQL數(shù)據(jù)庫
這篇文章主要為大家詳細(xì)介紹了Windows7下Python3.4使用MySQL數(shù)據(jù)庫,MySQL Community Server的安裝步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07