[轉載]MySQL UUID() 函數

目錄

文/溫國兵html

一 引子

在 MySQL 中,能夠有以下幾種途徑實現惟一值:mysql

  • 自增序列
  • UUID() 函數
  • 程序自定義

UUID 基於 16 進制,由 32 位小寫的 16 進制數字組成,以下:linux

aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeesql

好比123e4567-e89b-12d3-a456-426655440000就是一個典型的 UUID。bash

MySQL 實現了 UUID,而且提供 UUID() 函數方便用戶生成 UUID。在 MySQL 的 UUID() 函數中,前三組數字從時間戳中生成,第四組數字暫時保持時間戳的惟一性,第五組數字是一個 IEEE 802 節點標點值,保證空間惟一。使用 UUID() 函數,能夠生成時間、空間上都獨一無二的值。聽說只要是使用了 UUID,都不可能看到兩個重複的 UUID 值。固然,這個只是在理論狀況下。服務器

二 MySQL UUID() 函數

mysql -uroot -proot
mysql> SHOW VARIABLES LIKE '%version%'; +-------------------------+------------------------------+ | Variable_name | Value | +-------------------------+------------------------------+ | innodb_version | 5.5.40 | | protocol_version | 10 | | slave_type_conversions | | | version | 5.5.40-log | | version_comment | MySQL Community Server (GPL) | | version_compile_machine | x86_64 | | version_compile_os | linux2.6 | +-------------------------+------------------------------+ 7 rows in set (0.00 sec) mysql> SELECT UUID(), UUID(), LENGTH(UUID()), CHAR_LENGTH(UUID()) \G *************************** 1. row *************************** UUID(): 19a87b1a-a298-11e4-aa3c-08002735e4a4 UUID(): 19a87b26-a298-11e4-aa3c-08002735e4a4 LENGTH(UUID()): 36 CHAR_LENGTH(UUID()): 36 1 row in set (0.00 sec) mysql> SELECT UUID(), UUID(), LENGTH(UUID()), CHAR_LENGTH(UUID()) \G *************************** 1. row *************************** UUID(): 450e1572-a298-11e4-aa3c-08002735e4a4 UUID(): 450e157c-a298-11e4-aa3c-08002735e4a4 LENGTH(UUID()): 36 CHAR_LENGTH(UUID()): 36 1 row in set (0.00 sec) 

能夠看到,同一個 SQL 語句中,多處調用 UUID() 函數獲得的值不相同。也就是說每次調用 UUD 函數都會生成一個惟一的值。而且屢次調用或執行獲得的後兩組值相同。另外,自己 UUID 是 32 位,由於 MySQL 生成的 UUID 有四個中劃線,因此在 utf8 字符集裏,長度爲 36 位。markdown

咱們關閉 MySQL,而後啓動。ide

/etc/init.d/mysqld stop Shutting down MySQL. [ OK ] /etc/init.d/mysqld start Starting MySQL.. [ OK ] 

再次調用 UUID() 函數。函數

mysql> SELECT UUID(), UUID(), LENGTH(UUID()), CHAR_LENGTH(UUID()) \G *************************** 1. row *************************** UUID(): 586546b2-a298-11e4-b0fc-08002735e4a4 UUID(): 586546c5-a298-11e4-b0fc-08002735e4a4 LENGTH(UUID()): 36 CHAR_LENGTH(UUID()): 36 1 row in set (0.00 sec) 

能夠看到,第四組的值與重啓以前發生變化,直到下一次重啓 MySQL。測試

咱們鏈接到另外一臺服務器,再次調用 UUID() 函數。

mysql> SELECT UUID(), UUID(), LENGTH(UUID()), CHAR_LENGTH(UUID()) \G *************************** 1. row *************************** UUID(): 8fa81275-a298-11e4-8302-0800276f77f9 UUID(): 8fa81291-a298-11e4-8302-0800276f77f9 LENGTH(UUID()): 36 CHAR_LENGTH(UUID()): 36 1 row in set (0.00 sec) 

能夠看到跟以前的數據不一樣,包括第五組數據。由於第五組的值跟機器相關,因此,同一臺機器第五組值不變,不一樣機器則變。

三 複製中的 UUID()

3.1 實驗環境介紹

主機 IP地址 主機名 備註
rhel-01: 10.10.2.231 rhel-01 master
rhel-02: 10.10.2.227 rhel-02 slave

操做系統版本:RHEL 6.5 

所須要的軟件包:mysql-5.5.40-linux2.6-x86_64.tar.gz

3.2 搭建複製環境

在此不贅述,請參考:MySQL AB 複製

3.3 基於 STATEMENT 模式

rhel-01 中作以下設置,設置爲 STATEMENT 模式。

mysql> SET tx_isolation="REPEATABLE-READ"; Query OK, 0 rows affected (0.00 sec) mysql> SET binlog_format="STATEMENT"; Query OK, 0 rows affected (0.00 sec) 

rhel-02 也作以下設置:

mysql> SET tx_isolation="REPEATABLE-READ"; Query OK, 0 rows affected (0.00 sec) mysql> SET binlog_format="STATEMENT"; Query OK, 0 rows affected (0.00 sec) 

rhel-01 建立測試表,插入測試數據。在插入數據以後,還能夠看到一個警告。

mysql> USE test; Database changed mysql> CREATE TABLE user -> (name VARCHAR(36), -> en_name VARCHAR(20), -> job VARCHAR(10), -> addr VARCHAR(20) -> ) DEFAULT CHARSET=utf8 ENGINE=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO user(name, en_name, job, addr) \ VALUES(UUID(), "robin", "dba", "GZ"); Query OK, 1 row affected, 1 warning (0.01 sec) mysql> SHOW WARNINGS; | Level | Code | Message | +-------+------+-----------------------------------------------------+ | Note | 1592 | Unsafe statement written to the binary log using statement \ format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because \ it uses a system function that may return a different value on the slave. | +-------+------+-----------------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM user \G *************************** 1. row *************************** name: 24d785a2-a29c-11e4-b0fc-08002735e4a4 en_name: robin job: dba addr: GZ 1 row in set (0.00 sec) 

rhel-02 查看複製的數據。

mysql> USE test; Database changed mysql> SELECT * FROM user \G *************************** 1. row *************************** name: 24cd38fe-a29c-11e4-8302-0800276f77f9 en_name: robin job: dba addr: GZ 1 row in set (0.00 sec) 

能夠看到,rhel-01 中的 UUID 值爲24d785a2-a29c-11e4-b0fc-08002735e4a4,rhel-02 中的值爲 24cd38fe-a29c-11e4-8302-0800276f77f9,兩個值竟然不相同,亦即主從不一致。那這樣的複製是沒有什麼意義的。由於 UUID() 函數屬於不肯定函數,因此不支持 STATEMENT 模式。

3.4 基於 MIXED 模式

rhel-01 中作以下設置,設置爲 MIXED 模式。

mysql> SET binlog_format="MIXED"; Query OK, 0 rows affected (0.00 sec) 

rhel-02 中作以下設置:

mysql> SET binlog_format="MIXED"; Query OK, 0 rows affected (0.00 sec) 

rhel-01 插入測試數據。

mysql> INSERT INTO user(name, en_name, job, addr) \ VALUES(UUID(), "Wentasy", "dba", "GZ"); Query OK, 1 row affected (0.06 sec) mysql> SELECT * FROM user \G *************************** 1. row *************************** name: 24d785a2-a29c-11e4-b0fc-08002735e4a4 en_name: robin job: dba addr: GZ *************************** 2. row *************************** name: 8dc2c93c-a29c-11e4-b0fc-08002735e4a4 en_name: Wentasy job: dba addr: GZ 2 rows in set (0.00 sec) 

rhel-02 查看複製的數據。能夠看到 MIXED 模式下,兩臺服務器的 UUID 相同,亦即主從一致。

mysql> SELECT * FROM user \G *************************** 1. row *************************** name: 24cd38fe-a29c-11e4-8302-0800276f77f9 en_name: robin job: dba addr: GZ *************************** 2. row *************************** name: 8dc2c93c-a29c-11e4-b0fc-08002735e4a4 en_name: Wentasy job: dba addr: GZ 2 rows in set (0.00 sec) 

3.5 基於 ROW 模式

rhel-01 中作以下設置,設置爲 ROW 模式。

mysql> SET binlog_format="ROW"; Query OK, 0 rows affected (0.00 sec) 

rhel-02 也作以下設置,
bash mysql> SET binlog_format="ROW"; Query OK, 0 rows affected (0.00 sec)

rhel-01 插入測試數據。

mysql> INSERT INTO user(name, en_name, job, addr) \ VALUES(UUID(), "dbarobin", "dba", "GZ"); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM user \G *************************** 1. row *************************** name: 24d785a2-a29c-11e4-b0fc-08002735e4a4 en_name: robin job: dba addr: GZ *************************** 2. row *************************** name: 8dc2c93c-a29c-11e4-b0fc-08002735e4a4 en_name: Wentasy job: dba addr: GZ *************************** 3. row *************************** name: d8123587-a29c-11e4-b0fc-08002735e4a4 en_name: dbarobin job: dba addr: GZ 3 rows in set (0.00 sec) 

rhel-02 查看複製的測試數據。

mysql> SELECT * FROM user \G *************************** 1. row *************************** name: 24cd38fe-a29c-11e4-8302-0800276f77f9 en_name: robin job: dba addr: GZ *************************** 2. row *************************** name: 8dc2c93c-a29c-11e4-b0fc-08002735e4a4 en_name: Wentasy job: dba addr: GZ *************************** 3. row *************************** name: d8123587-a29c-11e4-b0fc-08002735e4a4 en_name: dbarobin job: dba addr: GZ 3 rows in set (0.00 sec) 

能夠看到,在 ROW 模式下,複製的數據和主服務器相同,亦即主從一致。

四 UUID_SHORT() 函數

在 MySQL 5.1 以後的版本,提供 UUID_SHORT() 函數,生成一個 64 位無符號整數。另外,須要注意的是,server_id 的範圍必須爲 0-255,而且不支持 STATEMENT 模式複製。

mysql> SELECT UUID_SHORT(); +-------------------+ | UUID_SHORT() | +-------------------+ | 95914352036544514 | +-------------------+ 1 row in set (0.00 sec) 

五 小結

  • 同一個 SQL 語句中,多處調用 UUID() 函數獲得的值不相同,屢次調用或執行獲得的後兩組值相同。
  • 同一臺服務器,重啓 MySQL 先後的 UUID() 第四組值發生變化,第五組值不變;
  • MySQL 中,utf8 字符集下,生成的 UUID 長度爲 36 位;
  • 不一樣機器生成的 UUID 不一樣,包括第五組值;
  • 在複製環境中,使用到 UUID() 函數,則必定要使用基於行或者基於混合模式複製方式。

六 Ref

–EOF–

版權聲明:自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證)

相關文章
相關標籤/搜索