MySQL将字符(32)数据类型转换为二进制(16),而不会丢失数据
您好,我有一个表,其中有一列带有MySQL将字符(32)数据类型转换为二进制(16),而不会丢失数据,mysql,Mysql,您好,我有一个表,其中有一列带有char(32)datatype,我需要将其转换为BINARY(16)datatype。我尝试过仅仅改变列类型,但这会删除列中的所有数据 ALTER TABLE table_name MODIFY device_uuid BINARY(16) 下面的代码是我如何更新列的数据类型的。这导致我丢失了列中的所有数据 ALTER TABLE table_name MODIFY device_uuid BINARY(16) 是否有一种方法可以更改列的数据类型,并将所有数
char(32)
datatype,我需要将其转换为BINARY(16)
datatype。我尝试过仅仅改变列类型,但这会删除列中的所有数据
ALTER TABLE table_name MODIFY device_uuid BINARY(16)
下面的代码是我如何更新列的数据类型的。这导致我丢失了列中的所有数据
ALTER TABLE table_name MODIFY device_uuid BINARY(16)
是否有一种方法可以更改列的数据类型,并将所有数据转换为新的数据类型,而不会丢失任何数据
我这样做的原因是因为我试图检索此表中丢失的数据。我需要将数据导入到的表完全相同,但列类型是BINARY(16)
而不是CHAR(32)
如果您能够提供帮助,请提前向您表示感谢。听起来您希望将UUID表示为十六进制数字字符串。它们通常有四个破折号,因此长度实际上是36个字符。但是如果删除破折号,它可以是32个字符
mysql> SELECT UUID();
+--------------------------------------+
| UUID() |
+--------------------------------------+
| b4d841ec-5220-11e9-901f-a921a9eb9f5b |
+--------------------------------------+
mysql> SELECT REPLACE(UUID(), '-', '');
+----------------------------------+
| REPLACE(UUID(), '-', '') |
+----------------------------------+
| d3dbd450522011e9901fa921a9eb9f5b |
+----------------------------------+
但在十六进制字符串中,每两个字符表示可以在二进制数据的一个字节中编码的数据。例如,FF是255的十六进制值,它是一个字节的最大值。因此,十六进制字符串占用的字节数是二进制中等效数据的两倍。如果空间受限,您可能希望将UUID值转换为二进制,以便将它们存储在一半的空间中
你可以用这个
二进制数据在面向人的界面中显示或键入并不愉快,因为有些字节对应于不可打印的字符
mysql> SELECT UUID();
+--------------------------------------+
| UUID() |
+--------------------------------------+
| b4d841ec-5220-11e9-901f-a921a9eb9f5b |
+--------------------------------------+
mysql> SELECT REPLACE(UUID(), '-', '');
+----------------------------------+
| REPLACE(UUID(), '-', '') |
+----------------------------------+
| d3dbd450522011e9901fa921a9eb9f5b |
+----------------------------------+
但是,当您更改TABLE TABLE\u name MODIFY device\u uuid BINARY(16)时,您没有使用UNHEX()
对十六进制字符串进行解码。充其量,这会导致ASCII十六进制字符的前16个字节映射到二进制(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;
如果您采用Karwin给出的算法,并对位进行一些洗牌,您将得到一个按时间顺序排列的UUID。由于是半有序的,而不是“随机的”,因此这对性能来说通常要好得多 我在我的博客中讨论了这一点。指出MySQL 8.0的标准函数中提供了等价的代码 另外,请注意,此“技巧”仅适用于“类型1”UUID,这正是MySQL/MariaDB所使用的