Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL将字符(32)数据类型转换为二进制(16),而不会丢失数据_Mysql - Fatal编程技术网

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所使用的