Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL преобразува типа данни CHAR(32) в BINARY(16) без загуба на данни

Изглежда, че искате да имате 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;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да разширя Joomla! към моя персонализиран PHP файл

  2. Възможно ли е да се предаде променлива към извикване на съхранена процедура в mysql?

  3. Въведете моя php в mysql без повторение?

  4. Как да подобрим ефективността на заявката с подреждане по, групиране по и присъединяване

  5. MySQL показва състоянието - активни или общи връзки?