sql >> Databasteknik >  >> RDS >> Mysql

MySQL konverterar CHAR(32) datatyp till BINARY(16) utan att förlora data

Det låter som att du vill ha ett UUID representerat som en sträng av hexadecimala siffror. Dessa har normalt fyra streck i sig så längden är faktiskt 36 tecken. Men om du tar bort strecken kan det vara 32 tecken.

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

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

Men i en hexadecimal sträng representerar varje två tecken data som kan kodas i en byte med binär data. Till exempel är FF hex-värdet för 255, vilket är det maximala värdet på en byte. Därför tar hexsträngar dubbelt så många byte som motsvarande data i binärt format. Om utrymmet är begränsat kanske du vill konvertera dina UUID-värden till binära så att du kan lagra dem på halva utrymmet.

Du kan göra detta med UNHEX()-funktionen .

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

Binär data är inte trevlig att visa eller skriva i mänskligt orienterade gränssnitt, eftersom vissa bytes motsvarar tecken som inte går att skriva ut.

Men när du gjorde ALTER TABLE table_name MODIFY device_uuid BINARY(16) , du avkodade inte hexsträngarna med UNHEX() . I bästa fall orsakade detta att de första 16 byten av ASCII hexadecimala tecken mappades till de 16 byten i din BINARY(16) kolumn, och det trunkerade strängen vid den punkten. Det är som om du gjorde detta på varje rad:

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

De första 16 byten är fortfarande hexadecimala siffror. Byten är ASCII-värden för dessa siffror, inte den binära ekvivalenten för varje par av siffror. De senare 16 byten av varje sträng trunkerades och lagrades inte. Om den informationen var viktig hoppas jag att du har en säkerhetskopia av din databas, för att återställa den säkerhetskopian nu är det enda sättet du kan återställa den informationen.

Vad du borde ha gjort är följande:

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. Kan inte ansluta till lokal MySQL-server i docker-compose

  2. Räkna antalet på varandra följande besök

  3. Det är möjligt att skapa en .jks från en .crt- och .key-fil

  4. Ta bort samma rad som infogats i en tabell med trigger i mysql