MySQL使用UUID_SHORT()的问题解决

 更新时间:2023年08月31日 11:39:46   作者:小_杭  
MySQL的UUID_SHORT()函数是一个用于生成短UUID的函数,该函数返回一个64位的整数,可以用于唯一标识一条数据记录,本文介绍了MySQL使用UUID_SHORT()的问题解决,感兴趣的可以了解一下

问题说明

app_msg的主键id 设置的类型为:bigint 20

使用插入语句:INSERT INTOapp_msg(id,...) VALUES (UUID_SHORT(),...)

然而系统报错:[Err] 1264 - Out of range value for column 'id' at row 1

在测试环境使用时没有问题,但是在准生产数据库使用时报错了

简单分析解决

分析

在两个数据库查看UUID_SHORT()生成的情况:

select UUID_SHORT()   
--结果1:26047177025388691      这里生成了17位的UUID_SHORT
--结果2:18040425909390934036   这里生成了20位的UUID_SHORT

结果1为17位没问题,结果2位20位导致报错的时候超过最大值

解决

这里可以知道原因是在字段类型上面,bigint 20 对应的类型是 long long 类型 【长度为:(-2^63 ~ 2^63-1) 10^18 19位数字】;

而UUID_SHORT() 返回的是 unsigned long long 类型【长度为:(0 ~ 2^64-1) 10^19 20位数字】

所以,原因是在MySQL设置的时候没有**勾选无符号****这个选项导致的,勾选上就解决了。╮(╯▽╰)╭ 就是这么的简单的地方。

临时解决方式,使用时间错手动生成了一个19位以内的随机id:

FLOOR(REPLACE(unix_timestamp(current_timestamp(3)),'.',''))*10000+FLOOR(RAND()*10000)

认真查了一些详细的资料

官方资料

版本:MySQL 5.7

UUID_SHORT()

将“ 短 ”通用标识符作为64位无符号整数返回。返回的值 UUID_SHORT()与UUID()函数返回的字符串格式128位标识符 不同,并且具有不同的唯一性属性。UUID_SHORT()如果满足以下条件,则保证值 是唯一的:

  • 在server_id当前服务器的值介于0和255之间,您的设置主从服务器中是唯一的
  • 您不会在mysqld restarts 之间设置服务器主机的系统时间
  • UUID_SHORT()在mysqld重启 之间, 你平均每秒调用的次数少于1600万次

该UUID_SHORT()返回值的构造是这样的:

  (server_id & 255) << 56
+ (server_startup_time_in_seconds << 24)
+ incremented_variable++;
mysql> SELECT UUID_SHORT();
        -> 92395783831158784

UUID_SHORT() 不适用于基于语句的复制。

按照以上官方的说法,UUID_SHORT返回的值为64位无符号整数,也就是unsigned long long类型。而且,由于使用到了时间搓,这个的初始值会很大(通常都会到17位数字)。

但是,这并不保证其不会返回18,19,20位的数据,只能保证在2^64-1以内(最大达到20位数字);

目前没有查到说可以调整或初始设置UUID_SHORT() 的配置

补充BUG–Java数据接收错误

在数据库使用了无符号bigint类型之后,使用UUID_SHORT()进行生产id的时候,数据库是可以插入,没有问题的。

**但是,**由于使用的是JAVA的Long类型进行数据接收,这里有可能是会超出长度的。【数据为无符号long类型这里差了1位】

因为,JAVA本身的基本类型是不支持无符号类型的,所以这里的转换会有问题。

而且,由于是已经遇到了,上面开始的那个BUG,这里是肯定是会超出的。【UUID_SHORT的值是在mysql启动的时候自动配置的,所以相当的无奈╮(╯_╰)╭】

所以这里,特别说明记录一下,这个问题。

解决办法:目前还是使用 【自定义的ID生成】,或者 上面 的临时解决方式【时间戳拼接】其实最好的还是使用32位的UUID比较的好

到此这篇关于MySQL使用UUID_SHORT()的问题解决的文章就介绍到这了,更多相关MySQL UUID_SHORT()内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySql数据库基础之子查询详解

    MySql数据库基础之子查询详解

    所谓子查询是指在一个查询中嵌套了其他的若干查询,即在一个SELECT查询语句的WHERE或FROM子句中包含另一个SELECT查询语句,下面这篇文章主要给大家介绍了关于MySQL子查询的相关资料,需要的朋友可以参考下
    2022-09-09
  • Mac OS系统下mysql 5.7.20安装教程图文详解

    Mac OS系统下mysql 5.7.20安装教程图文详解

    这篇文章主要介绍了Mac OS系统下mysql 5.7.20安装教程图文详解,本文给大家介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
    2017-11-11
  • MySQL5.7升级MySQL8.0的完整卸载与安装及连接Navicat的步骤

    MySQL5.7升级MySQL8.0的完整卸载与安装及连接Navicat的步骤

    因为一个项目交接需要需要将mysql物理备份文件还原至MySQL5.7,并且将mysql5.7升级到MySQL8.0,下面这篇文章主要给大家介绍了关于MySQL5.7升级MySQL8.0的完整卸载与安装及连接Navicat的相关资料,需要的朋友可以参考下
    2023-03-03
  • MySQL创建和删除表操作命令实例讲解

    MySQL创建和删除表操作命令实例讲解

    这篇文章主要介绍了MySQL创建和删除表操作命令实例讲解,本文讲解了创建表、创建临时表、查看已经创建的mysql表等内容,需要的朋友可以参考下
    2014-12-12
  • MySQL5.7.03 更换高版本到MySQL 5.7.17安装过程及发现问题解决方案

    MySQL5.7.03 更换高版本到MySQL 5.7.17安装过程及发现问题解决方案

    这篇文章主要介绍了MySQL5.7.03 更换高版本到MySQL 5.7.17安装过程及发现问题解决方案,需要的朋友可以参考下
    2017-08-08
  • mysql中varchar和text的区别和比较

    mysql中varchar和text的区别和比较

    在存储字符串时可以使用char、varchar或者text类型,下面这篇文章主要给大家介绍了关于mysql中varchar和text的区别和比较的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • MySQL语句加锁的实现分析

    MySQL语句加锁的实现分析

    MySQL的加锁分析,一直是一个比较困难的话题。我在工作过程中,经常会有同事咨询这方面的问题。今天我们来简单谈谈这个问题
    2017-10-10
  • MySQL中可为空的字段设置为NULL还是NOT NULL

    MySQL中可为空的字段设置为NULL还是NOT NULL

    今天小编就为大家分享一篇关于MySQL中可为空的字段设置为NULL还是NOT NULL,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • 详细讲解安全升级MySQL的方法

    详细讲解安全升级MySQL的方法

    这篇文章主要介绍了详细讲解安全升级MySQL的方法,在此特别推荐使用Percona Toolkit来辅助升级,当然,本文示例基于Linux环境,需要的朋友可以参考下
    2015-06-06
  • mysql server is running with the --skip-grant-tables option

    mysql server is running with the --skip-grant-tables option

    今天在mysql中新建数据库提示The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement,原来是数据中配置的--skip-grant-tables,这样安全就降低了,这个一般当忘记root密码的时候需要这样操作
    2017-07-07

最新评论