MySQL中可以有二類用於生成唯一值性質的工具:UUID()函數和自增序列,那麼二者有何區別呢?我們就此對比下各自的特性及異同點:
l 都可以實現生成唯一值的功能;
l UUID是可以生成時間、空間上都獨一無二的值;自增序列只能生成基於表內的唯
一值,且需要搭配使其爲唯一的主鍵或唯一索引;
l 實現方式不一樣,UUID是隨機+規則組合而成的,而自增序列是控制一個值逐步增長的;
l UUID產生的是字符串類型值,固定長度爲:36個字符,而自增序列產生的是整數類型值,長度由字段定義屬性決定;
接下來,詳細講解下UUID()函數產生的值:
oot@localhost : (none) 06:09:40> SELECT UUID(),UUID(),LENGTH(UUID()),CHAR_LENGTH(UUID())\G
*************************** 1. row ***************************
UUID(): de7ee638-4322-11e0-85ab-842b2b4a7e75
UUID(): de7ee642-4322-11e0-85ab-842b2b4a7e75
LENGTH(UUID()): 36
CHAR_LENGTH(UUID()): 36
1 row in set (0.00 sec)
從上面的執行結果部分的信息看:
l 同一個SQL語句中,多處調用UUID()函數得到的值不相同;
l 得到的隨機值由5個部分組成,且分隔符位爲:中劃線;
l 多次調用或執行得到的後2組值相同,若把mysqld服務器關閉,重新啓動之後,會發現第四組的組與未重啓前的值發生變化,然後一直不變化,只要重新啓動mysqld服務就會發生變化。另外,對於同一臺機器,第五組值始終不會發生變化;
l 字符個數爲:36,佔字節數爲:36(注:系統默認字符集編碼:utf8);
針對UUID產生的值組成部分,作如下解說:
l 前三組值是時間戳換算過來的;
l 第四組值是暫時性保持時間戳的唯一性。例如,使用夏令時;
l 第五組值是一個IEE 802的節點標識值,它是空間上唯一的。若後者不可用,則用一個隨機數字替換。假如主機沒有網卡,或者我們不知道如何在某系統下獲得機器地址,則空間唯一性就不能得到保證,即使這楊,出現重複值的機率還是非常小的。
UUID函數對複製的支持:
UUID函數屬於不確定性函數,爲此不支持MySQL 複製的STATEMENT模式,但是支持MIXED、ROW二種模式,大家可以設置2組測試模式,以5.1.系列版本爲例。
測試基於命令行模式複製:
tx_isolation = REPEATABLE-READ
binlog_format = STATEMENT
測試基於命令行/混合模式複製:
tx_isolation = REPEATABLE-READ
binlog_format = MIXED OR ROW
在主服務器上執行同一個SQL語句:
INSERT INTO test_uuid(username) VALUES(UUID());
然後再比對主從服務器上表中存儲的值,會發現基於命令行模式的:主從不一致,基於行/混合模式的:主從數據時一致;
建議:在複製模式下,需要用到UUID()函數,則一定要使用基於行/混合模式複製方式。
名詞解釋:
對於輸入參數相同,且同一時間執行或一個SQL中多處調用,而得到不同值得函數,我們就稱其爲:不確定性函數。
備註:
在MySQL 5.1.*及更高版本有一個變種的UUID()函數,名稱:UUID_SHORT(),生成一個64位無符號的整數,例如:
root@localhost : (none) 02:46:42> SELECT UUID_SHORT()\G
*************************** 1. row ***************************
UUID_SHORT(): 6218676250261585921
1 row in set (0.00 sec)
後續加註:
UUID()函數產生的值,並不適合作爲InnoDB引擎表的主鍵,至於詳細的原因,請閱讀文章InnoDB引擎表的主鍵選型。