MySQL UUID

UUID 是 RFC 4122 指定的通用唯一标识符(它是通用唯一标识符 URN 命名空间)和 128 位长值。它的设计方式使其生成一个根据空间和时间在全球范围内唯一的数字。如果我们连续调用两个 UUID,我们会得到两个不同的值,甚至它们是在两个没有连接的独立设备上执行的。

注意:虽然 UUID() 总是生成唯一值,但它们是不可猜测或不可预测的。这意味着它总是返回一个随机数。

一、UUID的结构

MySQL中的 UUID返回一个 128 位长的值。它以人类可读的格式表示为以下格式的五个十六进制数字的 UTF8 字符串:

aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeeee  
  • 前三个数字作为时间戳格式的一部分生成,例如低、中和高。这里,高位部分包含 UUID 版本号。
  • 第四个数字负责在时间戳值失去单调性时保持时间唯一性。
  • 第五个数字代表 IEEE 802 节点号,表示空间唯一性。如果字母不可用,它将替换不保证空间唯一性的随机数。

以下是 MySQL 中 UUID 值的有效字符串格式,它是32 位十六进制格式和四个连字符 (-) 的排列: 

a2720191-1cc6-11eb-9a2c-107d1a24f935  
185e6dfd-1cc8-11eb-9a2c-107d1a24f935  

我们可以使用以下函数在 MySQL 中生成 UUID 值:

mysql> SELECT UUID();  

上述函数返回一个与 RFC 4122 中描述的 UUID 版本 1 一致的 UUID 值。成功执行上述语句后,它将生成 UUID 值,如下所示:

二、MySQL UUID 与 AUTO_INCREMENT PRIMARY KEY

MySQL 中的 UUID 是 AUTO_INCREMENT PRIMARY KEY 的一个很好的替代品。以下是 UUID 相对于 AUTO_INCREMENT PRIMARY KEY 的优势:

UUID的优势

以下是使用 UUID 作为主键的优点:

  • MySQL 中的 UUID 值在表、数据库和服务器之间是唯一的。它允许我们跨服务器合并来自分布式/不同数据库的行。
  • UUID 值不提供有关我们数据的信息,这意味着很难猜测。因此在 URL 中使用是安全的。
  • UUID 值可以离线生成,这意味着我们可以在任何地方生成它,而无需与数据库服务器交换信息。
  • 它还简化了复制(应用程序中的逻辑)。比如我们要往父表和子表中插入数据,就必须先往父表中插入数据,得到生成的id,再往子表中填充记录。使用 UUID,我们可以生成父表的 PRIMARY KEY 值并将行同时插入到两个表中。

UUID的缺点

除了优点之外,以下是使用 UUID 作为主键的缺点:

  • 如果我们将 UUID(16 字节)值存储在数据库中,它会比整数(4 字节)或大整数(8 字节)占用更多的空间/存储空间。
  • 它使调试更加困难。例如,我们可以想象表达式 WHERE id = '185e6dfd-1cc8-11eb-9a2c-107d1a24f935' 而不是 WHERE id = 5。
  • 由于无序值及其大小,它还可能导致性能问题。

三、MySQL UUID 缺陷弥补方案 

我们可以通过使用下面给出的函数来克服 MySQL 中的这些问题。这些函数允许我们以紧凑的格式 (BINARY) 存储 UUID 值,并以人类可读的格式 (VARCHAR) 显示它们。函数的名称是:

  • UUID_TO_BIN
  • BIN_TO_UUID
  • IS_UUID

注意:需要注意的是,这些功能仅在 MySQL 8.0 或更高版本中可用。 

UUID_TO_BIN ()函数:用于将 UUID 值从人类可读格式转换为紧凑格式,以便将其存储在数据库中。

BIN_TO_UUID ()函数:用于将 UUID 从紧凑格式转换为人类可读的格式以供显示。

IS_UUID ()函数:用于验证 UUID 的字符串格式。它在参数有效时返回 1,对于无效参数返回 0。如果参数为 NULL,它将返回 NULL。

四、MySQL UUID 示例

让我们通过示例了解如何使用 UUID。首先,我们将使用以下语句创建一个名为employee的新表:

CREATE TABLE employee (  
    emp_id BINARY(16) PRIMARY KEY,  
    name VARCHAR(255)  
);  

接下来,我们需要将值插入到表中。此外,如果我们想将 UUID 值添加到emp_id 列中,我们必须使用 UUID() 和 UUID_TO_BIN() 函数,如下所示:

INSERT INTO employee (emp_id, name)  
VALUES (UUID_TO_BIN(UUID()),'John Doe'),  
      (UUID_TO_BIN(UUID()),'Johnny Dope'),  
      (UUID_TO_BIN(UUID()),'Jason Gillespie');  

现在,执行SELECT 语句验证插入的记录。

最后,我们将使用 BIN_TO_UUID() 函数从 UUID 列中查询数据,该函数将二进制格式转换为人类可读的格式。请参阅以下声明:

mysql> SELECT BIN_TO_UUID(emp_id) AS ID, name FROM employee;  

我们将得到如下输出:

五、MySQL UUID 与 UUID(short)

UUID() 和 UUID(short) 在 MySQL 中都是不同的函数。下面的比较图表讨论了它们之间的基本区别:

UUID UUID(short)
UUID 是由 RFC 4122 指定的通用唯一标识符,128 位长值表示为五个十六进制数字的 UTF8 字符串。 此函数生成一个 64 位无符号整数的短通用唯一标识符,它不同于 UUID() 函数生成的字符串格式的 128 位标识符。
它产生一个符合 16 字节版本 1 UUID 的值。版本 1 UUID 是服务器 ID 的按位组合、当前时间戳、几个字节和实用程序位。 它的返回值包含一个服务器 ID 的按位聚合、一个相当静态的时间分量和一个按顺序递增的 24 位整数。
在 UUID 中,服务器 ID 为 6 个字节长,这使得空间是唯一的。 在UUID(short)中,服务器ID只有一个字节;这就是它失去空间唯一性的原因。

热门文章

优秀文章