如何从 MySQL/MariaDB 中的二进制列格式化 uuid 字符串
How to format uuid string from binary column in MySQL/MariaDB
在 MySQL/MariaDB 中,存储 uuid 的最有效方法是在 BINARY(16) 列中。但是,有时您希望将其作为格式化的 uuid 字符串获取。
给定以下 table 结构,我如何以默认格式获取所有 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 中
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;
MySQL 8 加 two new UUID functions:
- UUID_TO_BIN
- BIN_TO_UUID - 这就是您要找的人
所以:
SELECT BIN_TO_UUID(uuid) FROM foo
在早期(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 但不是正确的。
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
如您所见,它们是不同的。
如果您正在寻找相反的方法,即如何将字符串转换为二进制,也许要进行连接或其他操作,请参见此处:Convert UUID to/from binary in Node
这篇 SQL 运行 在 Mysql 5.7 上帮助我锁定了概念:
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)
))
根据这张 Jira 票证,https://jira.mariadb.org/browse/MDEV-15854 UUID_TO_BIN 和 BIN_TO_UUID 没有进入 Mariadb 服务器版本 10.5。如果您使用的是 Mariadb 服务器的这个版本和以下版本,您将不得不使用上面提到的自定义实现。
在 MySQL/MariaDB 中,存储 uuid 的最有效方法是在 BINARY(16) 列中。但是,有时您希望将其作为格式化的 uuid 字符串获取。
给定以下 table 结构,我如何以默认格式获取所有 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 中
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;
MySQL 8 加 two new UUID functions:
- UUID_TO_BIN
- BIN_TO_UUID - 这就是您要找的人
所以:
SELECT BIN_TO_UUID(uuid) FROM foo
在早期(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 但不是正确的。
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
如您所见,它们是不同的。
如果您正在寻找相反的方法,即如何将字符串转换为二进制,也许要进行连接或其他操作,请参见此处:Convert UUID to/from binary in Node
这篇 SQL 运行 在 Mysql 5.7 上帮助我锁定了概念:
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)
))
根据这张 Jira 票证,https://jira.mariadb.org/browse/MDEV-15854 UUID_TO_BIN 和 BIN_TO_UUID 没有进入 Mariadb 服务器版本 10.5。如果您使用的是 Mariadb 服务器的这个版本和以下版本,您将不得不使用上面提到的自定义实现。