2012-06-08 13 views
71

Sulla base della risposta della domanda, UUID performance in MySQL, la persona che risponde suggerire per memorizzare UUID come un numero e non come una stringa. Non sono così sicuro di come possa essere fatto. Qualcuno potrebbe suggerirmi qualcosa? Come si comporta il mio codice rubino?Come memorizzare uuid come numero?

+5

I problemi di prestazioni sorgono solo quando si utilizza l'UUID come chiave primaria, poiché gli UUID non sono chiavi primarie molto efficienti. Perché hai bisogno degli UUID? Potresti mantenere gli UUID e usare solo un autoincremento come chiave primaria? –

+3

@ThomSmith Re "Gli UUID non sono chiavi primarie molto efficienti" .. cura di citare una fonte che spiega perché? – Pacerier

+1

È una porzione di dati più grande e in genere richiede più istruzioni per il confronto. Non è sequenziale, quindi il sovraccarico dell'indicizzazione è solo un po 'più alto. E, naturalmente, se lo stai memorizzando come stringa anziché come numero a 128 bit, come sembra fare l'OP, la situazione peggiora. Non è una chiave terribile, ma non la userei a meno che non ci fosse un motivo esterno per farlo. –

risposta

99

Se ho capito bene, si sta utilizzando UUID nella colonna primaria? La gente dirà che una chiave primaria regolare (integer) sarà più veloce, ma c'è un altro modo di usare il lato oscuro di MySQL. In effetti, MySQL è più veloce usando il binario di qualsiasi altra cosa quando sono richiesti gli indici.

Poiché UUID è di 128 bit e viene scritto come esadecimale, è molto facile per accelerare e memorizzare l'UUID.

In primo luogo, nel linguaggio di programmazione rimuovere i trattini

Da 110E8400-E29B-11D4-A716-446655440000-110E8400E29B11D4A716446655440000.

Ora è 32 caratteri (come un hash MD5, che funziona anche con).

Poiché un singolo BINARY in MySQL ha una dimensione di 8 bit, BINARY(16) ha la dimensione di un UUID (8 * 16 = 128).

È possibile inserire utilizzando:

INSERT INTO Table (FieldBin) VALUES (UNHEX("110E8400E29B11D4A716446655440000"))

e query utilizzando:

SELECT HEX(FieldBin) AS FieldBin FROM Table

Ora nel tuo linguaggio di programmazione, reinserire i trattini nelle posizioni 9, 14, 19 e 24 per abbinare il tuo UUID originale. Se le posizioni sono sempre diverse, puoi memorizzare quelle informazioni in un secondo campo.

esempio completa:

CREATE TABLE `test_table` (
    `field_binary` BINARY(16) NULL , 
    PRIMARY KEY ( `field_binary`) 
) ENGINE = INNODB ; 

INSERT INTO `test_table` (
    `field_binary` 
) 
VALUES (
    UNHEX( '110E8400E29B11D4A716446655440000') 
); 

SELECT HEX(field_binary) AS field_binary FROM `test_table` 

Se si desidera utilizzare questa tecnica con qualsiasi stringa esadecimale, sempre fare length/2 per la lunghezza del campo. Quindi per uno sha512, il campo sarebbe BINARY (64) poiché una codifica sha512 è lunga 128 caratteri.

+0

usa la funzione unhex per rendere il risultato umano illeggibile. – Chamnap

+0

@Chamnap La funzione UNHEX convertirà HEX in BINARY nel tuo database. È quindi possibile utilizzare gli indici su di esso senza problemi e con un guadagno di prestazioni (sì sì!). Quindi leggi i dati con la funzione 'HEX' come nel mio esempio. Quindi no, non puoi leggere il risultato da 'UNHEX', ma puoi usare if 'HEX'. Ricorda che il computer è fatto di binario, sempre più veloce. –

+3

@Chamnap Diciamo che hai 10.000 file nel tuo database e sono state aggiunte usando la funzione UNHEX e vuoi cercare l'UUID '110E8400-E29B-11D4-A716-446655440000'. Basta fare qualcosa del tipo: 'SELECT * FROM test_table WHERE field_binary LIKE CONCAT ("% ", UNHEX ('110E8400E29B11D4A716446655440000'),"% ")' –

0

non credo che la sua una buona idea di utilizzare un binario.

Diciamo che si desidera interrogare un certo valore:

SELECT HEX(field_binary) AS field_binary FROM `test_table` 

Se stiamo tornando diversi valori allora stiamo chiamando la funzione HEX più volte.

Tuttavia, il problema principale è quello seguente:

SELECT * FROM `test_table` 
    where field_binary=UNHEX('110E8400E29B11D4A716446655440000') 

E utilizzando una funzione all'interno della quale, ignora semplicemente l'indice.

anche

SELECT * FROM `test_table` 
    where field_binary=x'[email protected]#*#(&#@$9' 

Potrebbe porta a molti problemi.

Problemi correlati