如何在MySQL/MariaDB中从二进制列格式化uuid字符串

如何在MySQL/MariaDB中从二进制列格式化uuid字符串,mysql,mariadb,uuid,Mysql,Mariadb,Uuid,在MySQL/MariaDB中,存储uuid的最有效方法是在二进制(16)列中。但是,有时您希望将其作为格式化的uuid字符串获取 给定下表结构,如何以默认格式获取所有UUID CREATE TABLE foo (uuid BINARY(16)); 以下内容将创建我想要的结果: SELECT LOWER(CONCAT( SUBSTR(HEX(uuid), 1, 8), '-', SUBSTR(HEX(uuid), 9, 4), '-', SUBSTR(HEX(uui

在MySQL/MariaDB中,存储uuid的最有效方法是在二进制(16)列中。但是,有时您希望将其作为格式化的uuid字符串获取

给定下表结构,如何以默认格式获取所有UUID

CREATE TABLE foo (uuid BINARY(16));

以下内容将创建我想要的结果:

SELECT
  LOWER(CONCAT(
    SUBSTR(HEX(uuid), 1, 8), '-',
    SUBSTR(HEX(uuid), 9, 4), '-',
    SUBSTR(HEX(uuid), 13, 4), '-',
    SUBSTR(HEX(uuid), 17, 4), '-',
    SUBSTR(HEX(uuid), 21)
  ))
FROM foo;
这里有一个使用concat_ws的替代方案 将原始uuid存储在变量@x中

使用CONCAT_WS和SUBSTR解析人类可读的UUID

SELECT
  LOWER(CONCAT_WS('-',
    SUBSTR(@x, 1, 8),
    SUBSTR(@x, 9, 4),
    SUBSTR(@x, 13, 4),
    SUBSTR(@x, 17, 4),
    SUBSTR(@x, 21)
  )) AS uuid;
MySQL 8补充道:

  • -这就是你要找的
因此:

在早期(8之前)版本中,您可以在MySQL中创建一个

CREATE
  FUNCTION uuid_of(uuid BINARY(16))
  RETURNS VARCHAR(36)
  RETURN LOWER(CONCAT(
  SUBSTR(HEX(uuid), 1, 8), '-',
  SUBSTR(HEX(uuid), 9, 4), '-',
  SUBSTR(HEX(uuid), 13, 4), '-',
  SUBSTR(HEX(uuid), 17, 4), '-',
  SUBSTR(HEX(uuid), 21)
));
然后在查询中简单地使用它:

SELECT
  uuid_of(id)
  name,
  age
FROM users
它产生:

(c6f5703b-fec2-43fd-8f45-45f06583d450,一些名字,20)


下面的脚本生成了正确的结果,其他脚本生成了UUID,但不是正确的结果

CONCAT(
    substr(hex(Id), 7, 2), substr(hex(Id), 5, 2), substr(hex(Id), 3, 2), substr(hex(Id), 1, 2), '-'
    , substr(hex(Id), 11, 2) , substr(hex(Id), 9, 2) , '-'
    , substr(hex(Id), 15, 2) , substr(hex(Id), 13, 2) , '-'
    , substr(hex(Id), 17, 4) , '-'
    , substr(hex(Id), 21, 12) 
    )
运行其他脚本的结果生成了错误的UUID,如下所示:

  • 预期UUID-
    2e9660c2-1e51-4b9e-9a86-6db1a2770422
  • 生成了什么-
    c260962e-511e-9e4b-9a86-6db1a2770422

正如您所看到的,它们是不同的。

如果您正在寻找相反的方法,即如何从字符串转换为二进制,可能是执行连接或其他操作,这里将介绍这一点:

这段在Mysql 5.7上运行的SQL帮助我锁定了这个概念:

SELECT
  LOWER(CONCAT(
    SUBSTR(HEX(UNHEX(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))), 1, 8), '-',
    SUBSTR(HEX(UNHEX(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))), 9, 4), '-',
    SUBSTR(HEX(UNHEX(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))), 13, 4), '-',
    SUBSTR(HEX(UNHEX(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))), 17, 4), '-',
    SUBSTR(HEX(UNHEX(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))), 21)
  ))
输出为
43d597d7-2323-325a-90fc-21fa5947b9f3

字符串->二进制

因此
UNHEX(替换('43d597d7-2323-325a-90fc-21fa5947b9f3','-','')
以在
插入期间将UUID转换为二进制,并

二进制->字符串


根据这张Jira票据,UUID_to_BIN和BIN_to_UUID没有进入Mariadb服务器10.5版。如果您使用的是Mariadb服务器的这个版本,您将不得不使用上面提到的自定义实现。

请参阅这里的另一种替代方法:请参阅Oleg Mikheev的答案,现在在mysql 8.0中使用BIN_to_UUID()更容易做到这一点。是的,如果您使用的是mysql 8.0,请不要再使用这个答案。使用下面的Oleg。优化:与其重复完整的
HEX(uuid)
操作5次,不如
SET@HEX=(选择较低的(十六进制(字节)),速度不是更快吗
首先,然后引用
@hex
5次,并跳过包含的LOWER()?很抱歉,此计算是错误的,它不反映原始UUID。在MySQL中查询时,UUID
2e9660c2-1e51-4b9e-9a86-6db1a2770422
显示为
c260962e-511e-9e4b-9a86-6db1a2770422
Workbench@Alex.H有复制品吗
从${table}中选择十六进制(uuid_列)
然后从${table}中选择(uuid_列)的uuid_
?十六进制(myId)和(uuid_列)实际上是相同的
C260962E511E9E4B9A866DB1A2770422
c260962e-511e-9e4b-9a86-6DB1A27702
,但我相信ID是不同的我的MVC应用程序正在生成并保存到数据库中。它生成
2E9660C2-1E51-4B9E-9A86-6DB1A2770422
,并保存为
C260962E511E9E4B9A866DB1A2770422
。这可能是我使用的MySQL EF适配器的问题,因为如果我从
UUID\u的
中查询任何东西,我什么也得不到,但是如果我使用我上面发布的函数中的一个,我会得到我的记录。谢谢你,我每周复制粘贴多次xaxa。我想知道你是否可以
BIN\u TO\u UUID()
,这证实了这一点。尽管如此,如果您必须这样做,您可能会将
true
标志传递到
UUID\u to\u BIN
,因此您还需要它返回正确的UUID。即
BIN\u TO\u UUID(,true)
CONCAT(
    substr(hex(Id), 7, 2), substr(hex(Id), 5, 2), substr(hex(Id), 3, 2), substr(hex(Id), 1, 2), '-'
    , substr(hex(Id), 11, 2) , substr(hex(Id), 9, 2) , '-'
    , substr(hex(Id), 15, 2) , substr(hex(Id), 13, 2) , '-'
    , substr(hex(Id), 17, 4) , '-'
    , substr(hex(Id), 21, 12) 
    )
SELECT
  LOWER(CONCAT(
    SUBSTR(HEX(UNHEX(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))), 1, 8), '-',
    SUBSTR(HEX(UNHEX(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))), 9, 4), '-',
    SUBSTR(HEX(UNHEX(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))), 13, 4), '-',
    SUBSTR(HEX(UNHEX(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))), 17, 4), '-',
    SUBSTR(HEX(UNHEX(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))), 21)
  ))
LOWER(CONCAT(
  SUBSTR(HEX(uuid), 1, 8), '-',
  SUBSTR(HEX(uuid), 9, 4), '-',
  SUBSTR(HEX(uuid), 13, 4), '-',
  SUBSTR(HEX(uuid), 17, 4), '-',
  SUBSTR(HEX(uuid), 21)
))