mysql 压缩uuid长度_UUID不失精度,长度改进
在使用到uuid的时候,往往头疼于它的长度(如1bfe50d8-544e-4e8a-95b8-199ceff15268),于是乎就有了改写uuid的各种方法
1.去除“-”的uuid
不觉得uuid很长,但是就是看着中间的“-”很难受,又占长度,简单直接点就是
UUID uuid = UUID.randomUUID();
uuid.toString.replace("-", "");
额,这种方法,简单粗暴不优雅,其实呢,还可以看看这个“-”是哪里来的:
public String toString() {
return (digits(mostSigBits >> 32, 8) + "-" +
digits(mostSigBits >> 16, 4) + "-" +
digits(mostSigBits, 4) + "-" +
digits(leastSigBits >> 48, 4) + "-" +
digits(leastSigBits, 12));
}
/** Returns val represented by the specified number of hex digits. */
private static String digits(long val, int digits) {
long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
源码里写的很清楚 是它自己干的,所以完全可以自己实现把“-”去掉(最终代码在后面)
2.21-22位的uuid
去掉“-”之后变成了9b8a013583ba42cba75a9f3d6471eb7a,是一个16进制的字符串,但还是太长
/*
* The most significant 64 bits of this UUID.
*
* @serial
*/
private final long mostSigBits;
/*
* The least significant 64 bits of this UUID.
*
* @serial
*/
private final long leastSigBits;
源码中的UUID类中的这两个long型属性(mostSigBits是前半部分,leastSigBits是后半部分),其实就代表了uuid,具体的字符串编码都是通过这两个long拼接起来的(不得不说,想法很鸡贼,正常看到的就是这两个的16进制字符串)。
有人说,那直接把“-”去掉使用base64转化成64进制的字符串不就短了很多了?是这样的,不过我们可以仿写base64的实现写个简单的(主要base64最后是拿“+”和“/”凑的64个,“/”在http传输中容易被误解析)
最终的UUIDUtils代码:
import java.util.Date;
import java.util.UUID;
/**
* Created by Kowalski on 2017/5/11
* Updated by Kowalski on 2017/5/11
*/
public final class UUIDUtils {
/**
* 采用URL Base64字符,即把“+/”换成“-_”
*/
private static final char[] digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_=".toCharArray();
/**21-22位UUID*/
public static String generateMost22UUID() {
UUID uid = UUID.randomUUID();
long most = uid.getMostSignificantBits();
char[] buf = new char[22];
int charPos = 22;
int radix = 1 << 6;
long mask = radix - 1;
do {
charPos--;
buf[charPos] = digits[(int)(most & mask)];
most >>>= 6;
} while (most != 0);
long least = uid.getLeastSignificantBits();
do {
charPos--;
buf[charPos] = digits[(int)(least & mask)];
least >>>= 6;
} while (least != 0);
return new String(buf, charPos, 22-charPos);
}
/**无 - UUID*/
public static String generateUUID() {
UUID uuid = UUID.randomUUID();
long most = uuid.getMostSignificantBits();
long least = uuid.getLeastSignificantBits();
return (digits(most >> 32, 8) +
digits(most >> 16, 4) +
digits(most, 4) +
digits(least >> 48, 4) +
digits(least, 12));
}
private static String digits(long val, int digits) {
long hi = 1L << (digits << 2);
return Long.toHexString(hi | (val & (hi - 1)));
}
/**22位UUID*/
public static String generateUUID22() {
UUID uuid = UUID.randomUUID();
long msb = uuid.getMostSignificantBits();
long lsb = uuid.getLeastSignificantBits();
char[] out = new char[24];
int tmp = 0, idx = 0;
// 循环写法
int bit = 0, bt1 = 8, bt2 = 8;
int mask = 0x00, offsetm = 0, offsetl = 0;
for(; bit < 16; bit += 3, idx += 4) {
offsetm = 64 - ((bit + 3) << 3);
offsetl = 0;
tmp = 0;
if(bt1 > 3) {
mask = (1 << 8 * 3) - 1;
} else if(bt1 >= 0) {
mask = (1 << 8 * bt1) - 1;
bt2 -= 3 - bt1;
} else {
mask = (1 << 8 * ((bt2 > 3) ? 3 : bt2)) - 1;
bt2 -= 3;
}
if(bt1 > 0) {
bt1 -= 3;
tmp = (int) ((offsetm < 0) ? msb : (msb >>> offsetm) & mask);
if(bt1 < 0) {
tmp <<= Math.abs(offsetm);
mask = (1 << 8 * Math.abs(bt1)) - 1;
}
}
if(offsetm < 0) {
offsetl = 64 + offsetm;
tmp |= ((offsetl < 0) ? lsb : (lsb >>> offsetl)) & mask;
}
if(bit == 15) {
out[idx + 3] = digits[64];
out[idx + 2] = digits[64];
tmp <<= 4;
} else {
out[idx + 3] = digits[tmp & 0x3f];
tmp >>= 6;
out[idx + 2] = digits[tmp & 0x3f];
tmp >>= 6;
}
out[idx + 1] = digits[tmp & 0x3f];
tmp >>= 6;
out[idx] = digits[tmp & 0x3f];
}
return new String(out, 0, 22);
}
public static void main(String... args) {
Date d5 = new Date();
for(int i = 0; i < 10000000; i++) {
generateUUID22();
}
Date d6 = new Date();
System.out.print(d6.getTime() - d5.getTime());
System.out.println("\n");
Date d1 = new Date();
for(int i = 0; i < 10000000; i++) {
generateMost22UUID();
}
Date d2 = new Date();
System.out.print(d2.getTime() - d1.getTime());
System.out.println("\n");
}
}
这种实现方式比用replace后再用base64转换速度要更快(接近一倍),这里都是为了保证uuid的精度实现的,对uuid精度要求较低的也可以使用其他位数更少的uuid变体,有更好方案的小伙伴来交流~
mysql 压缩uuid长度_UUID不失精度,长度改进相关推荐
- mysql 压缩uuid长度_如何压缩UUID长度?
小型工厂企业网站究竟该怎么做好SEO优化,从而带来更多订单? 中 小企业以及小型工厂做好SEO工作,每年从SEO带来的订单量还是很可观的,随着互联网的蓬勃发展,越来越多的小型工厂型企业网站开始逐渐走向 ...
- MySQL 4种text类型的最大长度
MySQL 4种text类型的最大长度如下 TINYTEXT 256 bytes TEXT 65,535 bytes ~64kb MEDIUMTEXT 16,777,215 bytes ~16MB ...
- mysql中修改表字段名/字段长度/字段类型详解
在mysql中我们对数据表字段的修改命令只要使用alter就可以了,下面我来给大家详细介绍mysql中修改表字段名/字段长度/字段类型等等一些方法介绍,有需要了解的朋友可参考. 先来看看常用的方法 M ...
- mysql gtid寻找位置_【MySQL】UUID与GTID以及如何根据GTID找寻filename和position
Open Group于1997年10月发布,UUID遵从此协议. UUID被设计成一个在空间和时间上的唯一值.两次调用的UUID将产生两个不同的值,即使这些调用是在两个不连接的,彼此独立的计算机. 由 ...
- mysql的uuid获取
mysql> SELECT UUID(); mysql> c2cb8f66-351f-11e7-b3ed-00163e0429b6 mysql> SELECT REPLACE(UUI ...
- oracle数据库的double类型长度,数据库double类型长度
DOUBLE(size,d) 带有浮动小数点的大数字.在括号中规定最大位数.在 d 参数中规定小数点右侧的 2页 如有你有帮助,请购买下载,谢谢! 最大位数. DECIMAL(size,d) 作为字符 ...
- mysql数据库uuid函数_[转载]MySQL UUID() 函数
目录 文/温国兵 一 引子 在 MySQL 中,可以有如下几种途径实现唯一值: 自增序列 UUID() 函数 程序自定义 UUID 基于 16 进制,由 32 位小写的 16 进制数字组成,如下: a ...
- php数据库字段设置长度,javascript - 表单字符长度与数据库字段长度
html的表单length长度是以字符个数计算的,不管是汉字还是字母,但是数据库又是按字节计算的,汉字占2个字母占1个,这样容易造成写入的时候长度超出的问题. 两个问题: 1.有没有好的方法,能够在前 ...
- Possible MySQL server UUID duplication for server
在mysql enterprise monitor监控过程中出现这样的event事件,Topic: Possible MySQL server UUID duplication for serv ...
最新文章
- Jmail 64bit 64位 不支持
- 怎样学java软件编程6_月光软件站 - 编程文档 - Java - 我学习使用java的一点体会(6)...
- Android中的音乐播放
- spring3.2 aop 搭建 (1)
- 一头扎进Node系列 - 目录
- 对比Ruby和Python的垃圾回收(2):代式垃圾回收机制
- 网络信息安全实验 — 网络攻击技术实验(Kali系统,John、lc7、arpspoof、ettercap、SQL注入...)
- 获取论坛cookie_注意:这是你成为Cookie时尚社区OG的最后机会!
- plsql 连接数据库无法解析指定的连接标识符
- u9系统的使用方法仓库_用友U9--INV库存管理手册.pdf
- C语言中期报告模板,毕业设计中期报告模板.doc
- Go语言 linux安装
- html字体随页面大小变化,字体大小随网页大小变化
- 文件夹右击一直转圈圈
- IT:后端进阶技术路线图(初级→中级→高级)、后端开发工程师(技术方向分类之后台业务开发/中间件/内核/分布式架构)基础知识简介、技术路线/技术趋势指南(如何选择自己的技术方向)之详细攻略
- 搜狗2020校招(后端)笔试第一场
- 终端连接阿里云服务器出现Permission denied (publickey)解决方法
- Android5.1 电池充电剩余时间计算
- 基于PLC的实验室设备远程监控方案
- 窗口函数:实现组内百分比、累计值、累计百分比