mysql 存储uuid_MySQL中存储UUID的最佳实践
在 MySQL 中有一个UUID () 函数, 通常用UUID做唯一标识,需要在 数据库 中进行存储。 使用此函数可以让MySQL生成一个UUID值,并以VARCHAR(36)类型的可读形式返回。如图1:
图1
UUID值是非常随机的,因此常常被用来当做主键值(PRIMARY KEY),而且这些以UUID作为主键的数据可以很容易的从不同的数据库中汇聚到一起。但是对于像MySQL的InnoDB存储引擎来说,使用UUID作为主键(PRIMARY KEY)会带来一些问题。
1、问题阐述
问题一:UUID的长度问题
UUID的长度为36个字符。假设数据库的字符集为UTF8,那么UUID的最大长度为2+3*26=110字节。如果这样的UUID作为主键的话,不仅会是主键的尺寸很大,而且会使二级索引的尺寸变大,原因是MySQL中的二级索引的value存的是PRIMARY KEY。由于主键和二级索引的尺寸很大,所以不利于在内存中操作
问题二:UUID的格式问题
MySQL的UUID ()使用的是version 1的UUID,该类型的UUID的特点是基于时间,它是一个128位的数字,由5个十六进制数字组成的utf8字符串表示,我们以图1中的UUID值为例:
432a4ec8-3642-11e9-805a-0050568238b5,每对字符实际上是一个在00-FF范围内的十六进制数; 总共有16个数字,前三个数字432a4ec8-3642-11e9是由时间戳生成。但是,最左边的组变化最快(每微秒10次)。我们可以验证,如图2
图2
因为UUID是不连续的随机数,所以insert操作是随机的,数据被离散存储,造成innodb频繁的页分裂,使得insert的操作十分低效。
2、 结合问题定制方案
既然UUID作为主键带有这样那样的问题,难道说让我们在设计表结构时要放弃使用UUID吗?答案是否定的。我们可以通过采用binary(16)数据类型和重新安排UUID的顺序来解决之前提到的两个问题。
首先,BINARY(16) 这个二进制形式数据类型使用16个字节,比人类可读形式(“文本”形式)使用的VARCHAR(36)小的多。注意:只是二进制!没有字符集,没有排序,只有十六个字节。也许在某些应用程序中,文本形式仍然是必需的。那么我们可以使用虚拟列(MySQL5.7的新特性,虚拟列不占用存储空间)来存放文本形式的UUID。
然后,还有如何巧妙地重新排列二进制形式的字节的问题。我们在之前的问题二中已经了解到,MySQL的UUID()使用version1,最左边三个以破折号分隔的组是8字节的时间戳,最左边的第一组是时间戳的低四个字节; 第二组是中间两个字节时间戳,第三组是两个字节的高位时间戳,最左边的第一组变化最快。
因此,在我们存储UUID之前,重新安排UUID,使得快速变化的部分放到最后,例如:
把432a4ec8-3642-11e9-805a-0050568238b5重组为11e9-3642-432a4ec8-805a-0050568238b5
这种结构比起之前的结构更容易被cache缓存,同时存储上会更加连续。
3、方案验证
1)创建两张表
-- 使用原生的uuid作为主键
create table test_uuid (id_binvarchar(36) PRIMARY KEY, name varchar(200)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 使用重组后的uuid做为主键
create table test_uuid_ordered (id_bin binary(16) PRIMARY KEY, name varchar(200)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2)在mysql中创建转换函数uuidtobin
DELIMITER //
CREATE FUNCTION uuidtobin(_uuid varchar(36))
RETURNS BINARY(16)
LANGUAGE SQL DETERMINISTIC CONTAINS SQL SQL SECURITY INVOKER
RETURN
UNHEX(CONCAT(
SUBSTR(_uuid, 15, 4),
SUBSTR(_uuid, 10, 4),
SUBSTR(_uuid, 1, 8),
SUBSTR(_uuid, 20, 4),
SUBSTR(_uuid, 25) ));
//
DELIMITER ;
3)编写执行测试程序,分别使用uuid()写入数据到test_uuid中和调用函数uuidtobin(UUID())写入数据到test_uuid_ordered中,一次插入1万行数据到相应的表中
4)测试结果
数据尺寸
横轴-插入次数 x 10,000
纵轴-数据文件尺寸(单位MB)
UUID表的用varchar(36)存储的文件大小几乎比有序UUID表用BINARY(16)存储的文件大45%
实际处理时间
横轴-插入次数 x 10,000
纵轴-实际时间(单位 秒)
5)最后添加虚拟列id_text存放“未重新排列”的顺序的UUID文本,可以方便将文本格式用于一些错误日志记录,调试等。
alter table test_uuid_ordered add
id_text varchar(36) generated always as
(
insert(
insert(
insert(
insert(
hex(
concat(substr(id_bin,5,4),substr(id_bin,3,2),
substr(id_bin,1,2),substr(id_bin,9,8))
),
9,0,'-'),
14,0,'-'),
19,0,'-'),
24,0,'-')
) virtual;
mysql 存储uuid_MySQL中存储UUID的最佳实践相关推荐
- mysql用18位存储uuid_MySQL中存储UUID的最佳实践
在MySQL中有一个UUID () 函数,通常用UUID做唯一标识,需要在数据库中进行存储.使用此函数可以让MySQL生成一个UUID值,并以VARCHAR(36)类型的可读形式返回.如图1: 图1 ...
- 《大话存储__网络存储系原理精解与最佳实践》电子书下载
大话存储__网络存储系原理精解与最佳实践,经典图书 网络存储,是近二十年来的新兴行业.从纸带到硬盘再到大型磁盘阵列,存储系统经历了从简单到复杂,从单块硬盘到存储区域网络(SAN).网络存储行业目前 ...
- Java 中处理 Exception 的最佳实践
Java 中处理 Exception 的最佳实践 在Java中处理异常并不是一个简单的事情.不仅仅初学者很难理解,即使一些有经验的开发者也需要花费很多时间来思考如何处理异常,包括需要处理哪些异常,怎样 ...
- 在ASP.NET Web API中返回错误的最佳实践
本文翻译自:Best practice to return errors in ASP.NET Web API I have concerns on the way that we returns e ...
- 关于Azure存储账户中存储虚拟机VHD文件的注意事项
Joy Qiao from MSFT Thu, Mar 12 2015 3:16 PM 我们在使用Azure时经常都会在Azure存储账户中放一些文件,包括Azure虚机的VHD文件也都是放在存储 ...
- MySQL性能优化、故障排查及最佳实践秘籍,阿里云数据库专家玄惭的“武功”全记录...
为什么80%的码农都做不了架构师?>>> 文章简介 玄惭,真名罗龙九,阿里云DBA专家,负责阿里云RDS线上稳定以及专家服务团队.他经历过阿里历年双11实战考验,积累了7年对阿 ...
- 大型开发项目中 git 工作流的最佳实践
Gitflow Workflow 是一个 Git 工作流,有助于持续软件开发和实施 DevOps 实践. 它由文森特·德里森 (Vincent Driessen) 在 nvie 首次出版并广受欢迎. ...
- Spring Boot 生产中的 16 条最佳实践
来源:www.e4developer.com/2018/08/06/ Spring Boot是最流行的用于开发微服务的Java框架.在本文中,我将与你分享自2016年以来我在专业开发中使用Spring ...
- 数据安全--8--数据安全中的部分技术最佳实践
一.5A架构中的最佳实践 针对于5A架构中的技术最佳实践,总结如下: 身份认证: ● 人员身份认证(含员工.合作伙伴.用户等)使用SSO单点登录系统,并在敏感业务上启用超时退出机制: ● 非人员身份认 ...
最新文章
- 有格调的读书人,朋友圈是什么样的?
- windows installer无法启动
- web前端培训分享Electron之IPC 通信
- httpclient发起https请求以及获取https返回内容
- python装饰器补充
- HDU 5908 Abelian Period 可以直接用multiset
- .net core webapi 导出excel(两种方式EPPLUS、NPOI),返回下载地址或文件流
- python定时任务_Python定时任务
- LABVIEW详细介绍:LABVIEW是什么软件?都可以干什么?
- 只用测试号或认证服务号,实现电脑PC浏览器扫码微信扫码二维码登陆的思路,无需开放平台
- 路由器、交换机、集线器
- python 给文件加密
- 安装lux:推荐一款网页视频下载工具。并简单使用。(win)
- 1. 在 SAP ABAP 事物码 SEGW 里创建 SAP OData 项目
- linux 安装memcache 到简单使用
- mysql 不重复_Mysql 查询不重复数据
- MySQL插入表格数据的时候出现1265错误
- 三光(可见光、红外光、激光)云台产品调研
- Python从入门到精通— 初识Python
- 大数据 别让技术蛊惑