[转载]MySQL UUID() 函数
目录
文/温国兵
一 引子
在 MySQL 中,可以有如下几种途径实现唯一值:
- 自增序列
- UUID() 函数
- 程序自定义
UUID 基于 16 进制,由 32 位小写的 16 进制数字组成,如下:
aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
比如123e4567-e89b-12d3-a456-426655440000就是一个典型的 UUID。
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 位。
我们关闭 MySQL,然后启动。
/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许可证)
[转载]MySQL UUID() 函数的更多相关文章
- MySQL UUID函数的详解(转)
MySQL UUID函数的详解 MySQL中可以有二类用于生成唯一值性质的工具:UUID()函数和自增序列,那么二者有何区别呢?我们就此对比下各自的特性及异同点: l 都可以实现生成唯一值的功能: ...
- [转载]MySQL concat函数的使用
MySQL concat函数是MySQL数据库中众多的函数之一,下文将对MySQL concat函数的语法和使用进行说明,供您参考和学习. MySQL concat函数使用方法:CONCAT(str1 ...
- mysql常用函数参考
mysql常用函数参考 对于针对字符串位置的操作,第一个位置被标记为1. ASCII(str) 返回字符串str的最左面字符的ASCII代码值.如果str是空字符串,返回0.如果str是NULL, ...
- 【数据库】MySql常用函数梳理
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5866388.html MySql常用函数梳理: 1:数学函数 使用格式:一般用于插入.修改语句中,直接 函数( ...
- [php基础]Mysql日期函数:日期时间格式转换函数详解
在PHP网站开发中,Mysql数据库设计中日期时间字段必不可少,由于Mysql日期函数输出的日期格式与PHP日期函数之间的日期格式兼容性不够,这就需要根据网站实际情况使用Mysql或PHP日期转换函数 ...
- MySQL常用函数介绍
MySQL常用函数介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.操作符介绍 1>.操作符优先级 mysql; +----------+ | +----------+ ...
- [转]MySQL中函数CONCAT及GROUP_CONCAT
一.CONCAT()函数 CONCAT()函数用于将多个字符串连接成一个字符串. 使用数据表Info作为示例,其中SELECT id,name FROM info LIMIT 1;的返回结果为 +-- ...
- MySQL日期函数、时间函数总结(MySQL 5.X)
一.获得当前日期时间函数 1.1 获得当前日期+时间(date + time)函数:now() select now(); # :: 除了 now() 函数能获得当前的日期时间外,MySQL 中还有下 ...
- mysql uuid使用
java中可以使用UUID类来生成uuid,使用mysql也可以使用UUID函数来获取uuid,如 select UUID(); 也可以对查询的结果做一些处理,比如说将"-"替换成 ...
随机推荐
- 什么是Dubbo
1. Dubbo是什么? Dubbo是: 一款分布式服务框架 高性能和透明化的RPC远程服务调用方案 SOA服务治理方案 每天为2千多个服务提供大于30亿次访问量支持,并被广泛应用于阿里巴巴集团的各成 ...
- UI性能优化
我的思路 在移动设备上打开UI界面卡顿,等待时间长,页面白块,等等体验是很不好的.本文记录我在工作中解决UI卡顿的方法. 我主要从以下方面入手 资源量 界面打开做的操作 界面自身的逻辑 IO的读写(包 ...
- 源生js惯性滚动与回弹效果
在写移动端的APP或者页面时,经常会遇到惯性滚动与回弹效果.用插件iscroll可以轻松解决这个问题,大多数的移动框架也能轻松解决这个问题,它们内部都封装了这个效果. 一直好奇这个效果原生JS是怎么实 ...
- MySQL存储过程之游标实战
MySQL存储过程之游标实战 博主日前在解决一个项目需求时,没有什么好的方法,于是就来学习存储过程了,之前也是接触过,奈何年少贪玩,竟是全部又还给了大学老师-苦不堪言呐-. 先说一下业务需求吧 ...
- 关于close和shutdown
我们知道TCP是全双工的,可以在接收数据的同时发送数据.假设有主机A在和主机B通信,可以认为是在两者之间存在两个管道.就像这样:A ---------> BA <--------- B 1 ...
- margin相关
1.图片与文字对齐问题 如果图片和文字差不多大时,使用兼容性强的margin负值方法. 方法:img{margin:0 3px -3px 0;} 2.div嵌套后margin出现失效(转移)问题 原因 ...
- 小白的Python之路 day2 文件操作
文件操作 对文件操作流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 现有文件如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 ...
- 栈stack(1):栈的数组实现
定义 栈(stack),是一个只允许在表尾端进行删除插入操作的线性表,是一种后进先出(LIFO,last in first out)的数据结构. 因此,对于栈来说,我们规定进行删除插入操作的表尾端称为 ...
- Java并发编程之ThreadLocal源码分析
## 1 一句话概括ThreadLocal<font face="微软雅黑" size=4> 什么是ThreadLocal?顾名思义:线程本地变量,它为每个使用该对象 ...
- bzoj 1196: [HNOI2006]公路修建问题
Description OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Association组织 ...