2015-01-31 5 views
7

Non capisco il motivo per cuiInserimento e UUID selezione come binario (16)

SELECT UUID(); 

Restituisce qualcosa di simile:

3f06af63-a93c-11e4-9797-00505690773f 

Ma se lo inserisco in un campo binario (16) (la UUID() la funzione), con per esempio un trigger Inserisci prima ed eseguire una selezione, restituisce qualcosa come:

0782ef48-a439-11 

si noti che questi due UUID non sono T lui stesso dati.

Realizzo binari e una stringa UUID non sembra identica, ma i dati selezionati non dovrebbero essere altrettanto lunghi? Altrimenti, come può essere altrettanto probabile che sia unico?

È meglio memorizzarlo come char (36)? Ho solo bisogno che sia unico per prevenire inserimenti duplicati. Non viene mai selezionato o utilizzato per i join.

EDIT:

prima grilletto sarebbe come:

BEGIN 

if NEW.UUID IS NULL THEN 

NEW.UUID = UUID(); 

END IF 

END 
+0

Mostrare come si sta facendo il 'INSERT'. – Barmar

+0

'BINARY (16)' può contenere solo 16 caratteri. Quindi conterrà i primi 16 caratteri dell'UUID in cui ci si archivia. – Barmar

+0

Secondo http://stackoverflow.com/questions/10950202/how-to-store-uuid-as-number che non è il caso. Anche http://stackoverflow.com/questions/17726682/read-mysql-binary16-uuid-with-java – nickdnk

risposta

25

Così, come una risposta ai commenti. Il modo corretto di memorizzare un UUID 36 char come binario (16) è quello di eseguire l'inserto in modo analogo:

INSERT INTO sometable (UUID) VALUES (UNHEX(REPLACE("3f06af63-a93c-11e4-9797-00505690773f", "-",""))) 

UNHEX perché un UUID è già un valore hexed. Tagliamo (REPLACE) i trattini nell'istruzione per portare la lunghezza a 32 caratteri ASCII (i nostri 16 byte rappresentati come HEX). Puoi farlo in qualsiasi momento prima di memorizzarlo, ovviamente, quindi non deve essere gestito dal database.

Si può recuperare l'UUID in questo modo:

SELECT HEX(UUID) FROM sometable; 

Solo nel caso qualcuno si imbatte in questa discussione e non è sicuro come funziona.

E ricordate: se si sta selezionando una riga usando l'UUID, uso UNHEX() a condizione:

SELECT * FROM sometable WHERE UUID = UNHEX('3f06af63a93c11e4979700505690773f'); 

E non HEX() sulla colonna:

SELECT * FROM sometable WHERE HEX(UUID) = '3f06af63a93c11e4979700505690773f'; 

Il la seconda soluzione, mentre funziona, richiede che MySQL HEX es tutti gli UUID prima che possa determinare quali righe corrispondono. È molto inefficiente.

6

partire da MySQL 8 è possibile utilizzare due nuovi UUID functions:

  • BIN_TO_UUID

    SELECT BIN_TO_UUID(uuid, true) AS uuid FROM foo; 
    -- 3f06af63-a93c-11e4-9797-00505690773f 
    
  • UUID_TO_BIN

    INSERT INTO foo (uuid) VALUES (UUID_TO_BIN('3f06af63-a93c-11e4-9797-00505690773f', true)); 
    

Questo metodo supporta anche riorganizzare il t componente dell'uu per migliorare le prestazioni dell'indicizzazione (ordinandolo cronologicamente), basta impostare il secondo argomento su true - questo funziona solo per UUID1.

Se si sta utilizzando il flag true sul flag UUID_TO_BIN per l'indicizzazione (consigliato), è necessario impostarlo su BIN_TO_UUID altrimenti non verrà convertito correttamente.

Vedere la documentazione per ulteriori dettagli.

+0

Dopo molte ricerche, abbiamo deciso di migrare da MySQL a PostgreSQL perché hanno un tipo di dati UUID (proprio come l'incremento automatico, si inserisce automaticamente e, soprattutto, puoi leggerlo direttamente usando una stringa). Altrimenti dobbiamo rifattorizzare la nostra intera codebase ovunque abbiamo un aggiornamento o una lettura usando un id con mysql 5.7 o 8. – friek108

+0

@ friek108 MySQL ha anche una funzione UUID() per quello scopo specifico. Sebbene non sia un tipo di dati, equivale a binario (16) e genera UUID sequenziali (non casuali) inseribili facilmente. – nickdnk

+0

Grazie a @nickdnk - ma alla fine vorremmo dire che dobbiamo aggiornare ogni singola query nell'intera codebase per includere questa funzione. – friek108