Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL konwertuje typ danych CHAR(32) na BINARY(16) bez utraty danych

Wygląda na to, że chcesz, aby identyfikator UUID był reprezentowany jako ciąg cyfr szesnastkowych. Zwykle mają w sobie cztery myślniki, więc długość wynosi w rzeczywistości 36 znaków. Ale jeśli usuniesz myślniki, może to być 32 znaki.

mysql> SELECT UUID();
+--------------------------------------+
| UUID()                               |
+--------------------------------------+
| b4d841ec-5220-11e9-901f-a921a9eb9f5b |
+--------------------------------------+

mysql> SELECT REPLACE(UUID(), '-', '');
+----------------------------------+
| REPLACE(UUID(), '-', '')         |
+----------------------------------+
| d3dbd450522011e9901fa921a9eb9f5b |
+----------------------------------+

Ale w ciągu szesnastkowym każde dwa znaki reprezentują dane, które można zakodować w jednym bajcie danych binarnych. Na przykład FF jest wartością szesnastkową dla 255, co jest maksymalną wartością jednego bajtu. Dlatego ciągi szesnastkowe zajmują dwa razy więcej bajtów niż równoważne dane w postaci binarnej. Jeśli przestrzeń jest ograniczona, możesz chcieć przekonwertować swoje wartości UUID na binarne, aby móc przechowywać je w połowie miejsca.

Możesz to zrobić za pomocą funkcji UNHEX() .

mysql> SELECT UNHEX(REPLACE(UUID(), '-', ''));
+---------------------------------+
| UNHEX(REPLACE(UUID(), '-', '')) |
+---------------------------------+
| $S,vR!??!??[                      |
+---------------------------------+

Dane binarne nie są przyjemne do wyświetlania lub wpisywania w interfejsach zorientowanych na człowieka, ponieważ niektóre bajty odpowiadają znakom niedrukowalnym.

Ale kiedy zrobiłeś ALTER TABLE table_name MODIFY device_uuid BINARY(16) , nie zdekodowałeś ciągów szesnastkowych za pomocą UNHEX() . W najlepszym przypadku spowodowało to odwzorowanie pierwszych 16 bajtów znaków szesnastkowych ASCII na 16 bajtów kolumny BINARY(16) i obcięcie ciągu w tym momencie. To tak, jakbyś robił to w każdym rzędzie:

mysql> SELECT LEFT(REPLACE(UUID(), '-', ''), 16);
+------------------------------------+
| LEFT(REPLACE(UUID(), '-', ''), 16) |
+------------------------------------+
| 364e6db8522211e9                   |
+------------------------------------+

Pierwsze 16 bajtów to nadal cyfry szesnastkowe. Bajty są wartościami ASCII dla tych cyfr, a nie binarnym odpowiednikiem każdej pary cyfr. Ostatnie 16 bajtów każdego ciągu zostało obciętych i nie zostało zapisanych. Jeśli te dane były ważne, mam nadzieję, że masz kopię zapasową swojej bazy danych, ponieważ przywrócenie tej kopii zapasowej jest teraz jedynym sposobem na odzyskanie tych danych.

Co powinieneś zrobić, to:

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. Błąd:mysqladmin:odświeżenie nie powiodło się; błąd:„Nieznany błąd”

  2. Pole oddzielone przecinkami w MySQL

  3. MYSQL i RDBMS

  4. Jak mieć dynamiczny SQL w procedurze przechowywanej MySQL?

  5. Jak mogę zasymulować instrukcję print w MySQL?