听起来您想要一个表示为十六进制数字字符串的 UUID。这些通常包含四个破折号,因此长度实际上是 36 个字符。但如果去掉破折号,则可以是 32 个字符。
mysql> SELECT UUID();
+--------------------------------------+
| UUID() |
+--------------------------------------+
| b4d841ec-5220-11e9-901f-a921a9eb9f5b |
+--------------------------------------+
mysql> SELECT REPLACE(UUID(), '-', '');
+----------------------------------+
| REPLACE(UUID(), '-', '') |
+----------------------------------+
| d3dbd450522011e9901fa921a9eb9f5b |
+----------------------------------+
但在十六进制字符串中,每两个字符代表可以编码为一个字节的二进制数据的数据。例如,FF 是 255 的十六进制值,它是一个字节的最大值。因此,十六进制字符串占用的字节数是二进制中等效数据的两倍。如果空间有限,您可能需要将 UUID 值转换为二进制,以便可以将它们存储在一半的空间中。
您可以使用UNHEX() 函数.
mysql> SELECT UNHEX(REPLACE(UUID(), '-', ''));
+---------------------------------+
| UNHEX(REPLACE(UUID(), '-', '')) |
+---------------------------------+
| $S,vR!??!??[ |
+---------------------------------+
二进制数据在面向人的界面中显示或键入并不令人愉快,因为某些字节对应于不可打印的字符。
但当你这么做的时候ALTER TABLE table_name MODIFY device_uuid BINARY(16)
,你没有解码十六进制字符串UNHEX()
。最好的情况是,这会导致 ASCII 十六进制字符的前 16 个字节映射到 BINARY(16) 列的 16 个字节,并在此时截断字符串。就好像你对每一行都这样做了:
mysql> SELECT LEFT(REPLACE(UUID(), '-', ''), 16);
+------------------------------------+
| LEFT(REPLACE(UUID(), '-', ''), 16) |
+------------------------------------+
| 364e6db8522211e9 |
+------------------------------------+
前 16 个字节仍然是十六进制数字。这些字节是这些数字的 ASCII 值,而不是每对数字的等效二进制值。每个字符串的后 16 个字节被截断,并且不被存储。如果该数据很重要,我希望您有数据库的备份,因为恢复该备份现在是恢复该数据的唯一方法。
您应该做的如下:
ALTER TABLE table_name ADD COLUMN device_uuid_bin BINARY(16);
UPDATE table_name SET device_uuid_bin = UNHEX(device_uuid);
...check the data to make sure the conversion worked...
...test any applications work with the binary data...
ALTER TABLE table_name DROP COLUMN device_uuid;