sql >> Databáze >  >> RDS >> Mysql

MySQL převádí datový typ CHAR(32) na BINARY(16) bez ztráty dat

Zní to, jako byste chtěli mít UUID reprezentovaný jako řetězec hexadecimálních číslic. Obvykle mají čtyři pomlčky, takže délka je ve skutečnosti 36 znaků. Pokud však pomlčky odstraníte, může mít 32 znaků.

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

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

Ale v hexadecimálním řetězci představují každé dva znaky data, která by mohla být zakódována do jednoho bajtu binárních dat. Například FF je hexadecimální hodnota pro 255, což je maximální hodnota jednoho bajtu. Hexadecimální řetězce proto zabírají dvakrát tolik bajtů než ekvivalentní data v binárním formátu. Pokud je prostor omezený, možná budete chtít převést hodnoty UUID na binární, abyste je mohli uložit do polovičního prostoru.

Můžete to udělat pomocí funkce UNHEX() .

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

Binární data není příjemné zobrazovat nebo psát v uživatelsky orientovaných rozhraních, protože některé bajty odpovídají netisknutelným znakům.

Ale když jste provedli ALTER TABLE table_name MODIFY device_uuid BINARY(16) , nedekódovali jste hexadecimální řetězce pomocí UNHEX() . V nejlepším případě to způsobilo, že prvních 16 bajtů hexadecimálních znaků ASCII bylo mapováno na 16 bajtů vašeho sloupce BINARY(16) a v tomto bodě došlo ke zkrácení řetězce. Je to, jako byste to udělali u každého řádku:

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

Prvních 16 bajtů jsou stále hexadecimální číslice. Bajty jsou hodnoty ASCII pro tyto číslice, nikoli binární ekvivalent každého páru číslic. Posledních 16 bajtů každého řetězce bylo zkráceno a nebylo uloženo. Pokud byla tato data důležitá, doufám, že máte zálohu své databáze, protože obnovení této zálohy je nyní jediným způsobem, jak tato data obnovit.

Měli jste udělat následující:

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. Existuje způsob, jak omezit pouze spodní rozsah v mysql?

  2. Najděte chybějící data pomocí SQL

  3. Optimalizace dotazů MySQL napříč hierarchickými daty

  4. vložit do výběru v MySQL s JDBC