sql >> Database >  >> RDS >> Mysql

MySQL converteert CHAR (32) datatype naar BINARY (16) zonder gegevens te verliezen

Het klinkt alsof u een UUID wilt weergeven als een reeks hexadecimale cijfers. Deze hebben normaal gesproken vier streepjes, dus de lengte is eigenlijk 36 tekens. Maar als u de streepjes verwijdert, kunnen het 32 ​​tekens lang zijn.

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

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

Maar in een hexadecimale tekenreeks vertegenwoordigen elke twee tekens gegevens die kunnen worden gecodeerd in één byte aan binaire gegevens. FF is bijvoorbeeld de hexadecimale waarde voor 255, wat de maximale waarde van één byte is. Daarom nemen hex-strings twee keer zoveel bytes in beslag als de equivalente gegevens in binair. Als de ruimte beperkt is, wilt u misschien uw UUID-waarden converteren naar binair, zodat u ze in de helft van de ruimte kunt opslaan.

U kunt dit doen met de UNHEX() functie .

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

Binaire gegevens zijn niet prettig om weer te geven of in te typen in mensgerichte interfaces, omdat sommige bytes overeenkomen met niet-afdrukbare tekens.

Maar toen je ALTER TABLE table_name MODIFY device_uuid BINARY(16) deed , je hebt de hexadecimale tekenreeksen niet gedecodeerd met UNHEX() . In het beste geval zorgde dit ervoor dat de eerste 16 bytes aan hexadecimale ASCII-tekens werden toegewezen aan de 16 bytes van uw BINARY (16)-kolom, en op dat moment werd de tekenreeks afgekapt. Het is alsof je dit bij elke rij hebt gedaan:

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

De eerste 16 bytes zijn nog steeds hexadecimale cijfers. De bytes zijn ASCII-waarden voor die cijfers, niet het binaire equivalent van elk paar cijfers. De laatste 16 bytes van elke string werden afgekapt en niet opgeslagen. Als die gegevens belangrijk waren, hoop ik dat je een back-up van je database hebt, want het terugzetten van die back-up is nu de enige manier waarop je die gegevens kunt herstellen.

Wat u had moeten doen is het volgende:

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. Ontmoet Michal Bar en mij bij Microsoft Ignite!

  2. as3, MySQL PHP-verbinding

  3. Niet-gespecificeerde runtime-fout tijdens het uitvoeren van vba-script

  4. MySQL Store-relatie (stam)boom