MySQL конвертирует тип данных CHAR (32) в BINARY (16) без потери данных - PullRequest
1 голос
/ 29 марта 2019

Привет, у меня есть таблица, в которой есть столбец с типом данных char(32), мне нужно преобразовать его в тип данных BINARY(16).Я попытался просто изменить тип столбца, но он удаляет все данные в столбце.

Следующий код показывает, как я обновил тип данных столбца.Это привело к тому, что я потерял все данные в столбце.

ALTER TABLE table_name MODIFY device_uuid BINARY(16)

Есть ли способ изменить тип данных столбца и преобразовать все данные в новый тип данных без потери каких-либо данных.

Причина, по которой я это делаю, заключается в том, что я пытаюсь восстановить потерянные данные, которые находятся в этой таблице.Таблица, в которую мне нужно импортировать данные, точно такая же, но тип столбца BINARY(16), а не CHAR(32).

Заранее благодарим вас, если вам удастся помочь с этим.

Ответы [ 2 ]

1 голос
/ 29 марта 2019

Звучит так, как будто вы хотите, чтобы 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(). В лучшем случае это привело к тому, что первые 16 байтов шестнадцатеричных символов ASCII были сопоставлены с 16 байтами столбца BINARY (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;
0 голосов
/ 17 апреля 2019

Если вы возьмете алгоритм, заданный Карвином, и перемешаете некоторые биты, вы получите упорядоченный по времени UUID. Это часто намного лучше для производительности из-за полуупорядоченности, а не «случайности».

Я обсуждаю это в моем блоге здесь . Это указывает на то, что эквивалентный код был предоставлен в стандартных функциях в MySQL 8.0.

Также обратите внимание, что этот «трюк» применяется только к uuids типа 1, что и используется MySQL / MariaDB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...