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

Posted

技术标签:

【中文标题】如何从 MySQL/MariaDB 中的二进制列格式化 uuid 字符串【英文标题】:How to format uuid string from binary column in MySQL/MariaDB 【发布时间】:2016-09-07 05:14:33 【问题描述】:

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

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

CREATE TABLE foo (uuid BINARY(16));

【问题讨论】:

my uuid blog 【参考方案1】:

以下将创建我所追求的结果:

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;

【讨论】:

查看 Oleg Mikheev 的回答,现在使用 BIN_TO_UUID() 在 mysql 8.0 中更容易做到 是的,如果您使用的是 MySQL 8.0,请不要再使用此答案。使用下面的 Oleg。 优化:与其将完整的HEX(uuid)操作重复5次,不如先SET @hex = (SELECT LOWER(HEX(bytes)));,再引用@hex 5次,也跳过封闭的LOWER() ?【参考方案2】:

这是使用 concat_ws 的替代方法

将原始 uuid 存储在变量 @x 中

SELECT @x := hex(uuid)
FROM foo;

使用 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;

【讨论】:

这里还有另一种替代方法:***.com/questions/27039152/…【参考方案3】:

MySQL 8 新增two new UUID functions:

UUID_TO_BIN BIN_TO_UUID - 这就是你要找的人

所以:

SELECT BIN_TO_UUID(uuid) FROM foo

【讨论】:

我想知道你是否可以BIN_TO_UUID(<fieldName>),这证实了这一点。虽然,如果您必须这样做,您可能会将true 标志传递给UUID_TO_BIN,因此您还需要它获取正确的 UUID。 IE。 BIN_TO_UUID( <fieldName>, true ) 我收到“功能不存在”,我有最新版本【参考方案4】:

在早期(8 之前)版本中,您可以在 MySQL 中创建function,如下所示:

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, Some name, 20)

【讨论】:

很抱歉,这个计算是错误的,它没有反映原始 UUID。在 MySQL Workbench 中查询时 UUID 2e9660c2-1e51-4b9e-9a86-6db1a2770422 显示为 c260962e-511e-9e4b-9a86-6db1a2770422 @Alex.H 有没有复制? SELECT hex(uuid_column) FROM $table 然后SELECT uuid_of(uuid_column) FROM $table? hex(myId)uuid_of(uuid_column) 实际上是相同的 C260962E511E9E4B9A866DB1A2770422c260962e-511e-9e4b-9a86-6db1a2770422,但它不是我的 MVC 应用程序生成并保存到数据库的 ID(我相信)。它生成2E9660C2-1E51-4B9E-9A86-6DB1A2770422,保存为C260962E511E9E4B9A866DB1A2770422。这可能是我正在使用的 MySQL EF 适配器的问题,因为如果我使用来自 uuid_of 的 UUID 查询任何内容,我什么也得不到,但如果我使用上面发布的函数中的那个,我会获取我的记录。【参考方案5】:

正确的结果是由下面的脚本生成的,其他脚本生成了一个 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

如您所见,它们是不同的。

【讨论】:

【参考方案6】:

如果您正在寻找相反的东西,即如何从字符串转换为二进制,也许是为了进行连接或其他事情,这里介绍了这一点:Convert UUID to/from binary in Node

在 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(REPLACE('43d597d7-2323-325a-90fc-21fa5947b9f3', '-', ''))INSERT / UPDATE / JOIN / SELECT 期间将 UUID 转换为二进制,并且

二进制 -> 字符串

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)
))

【讨论】:

谢谢老兄,我每周复制粘贴多次 xaxa。【参考方案7】:

根据这张 Jira 票 https://jira.mariadb.org/browse/MDEV-15854UUID_TO_BIN 和 BIN_TO_UUID 没有进入 Mariadb 服务器版本 10.5。如果您使用的是这个版本并且在 Mariadb Server 下,您将不得不使用上面提到的自定义实现。

【讨论】:

以上是关于如何从 MySQL/MariaDB 中的二进制列格式化 uuid 字符串的主要内容,如果未能解决你的问题,请参考以下文章

数据库MySQL/mariadb知识点——日志记录二进制日志

如何从 MySQL/Mariadb 获取用户 ID?

安装MySQL&mariadb

二进制安装mysql|mariadb

入门:如何从Linux命令行直接执行MySQL/MariaDB查询

Mysql(Mariadb)数据库主从复制