2009-11-11 1 views
13

Stavo pensando a come sto memorizzando le password nel mio database: stringhe SHA1 appropriatamente salate in un campo CHAR (40). Tuttavia, dal momento che i dati del carattere in là sono in realtà solo una rappresentazione esadecimale di un numero di 160 bit, ho pensato che sarebbe stato meglio memorizzarlo come BINARY (20).Memorizzazione di valori esadecimali come binari in MySQL

CREATE TABLE users (
    password BINARY(20) 
    /* snip */ 
); 

INSERT INTO users (password) VALUES (UNHEX(SHA1('mypassword')); 

come la vedo io, uno dei vantaggi di questo approccio è che dimezza le dimensioni di quel campo, ma posso immaginare che probabilmente c'è anche alcuni aspetti negativi.

Qual è la tua opinione?

+0

si sarebbe salvando solo pochi byte per la password. Ne vale la pena? – pavium

+1

beh, questo è quello che mi sto chiedendo. I vantaggi potrebbero essere scarsi, ma quali sono i costi? – nickf

+0

OK, sembra che ci sia un accordo generale, i benefici sono lievi e di nessuno hanno suggerito eventuali costi significativi. Se hai apportato la modifica, i backup futuri sarebbero compatibili con i backup precedenti? Qualche codice deve essere cambiato? – pavium

risposta

26

Abbiamo usato binari per una tonnellata di ID diversi nel nostro database per risparmiare spazio, poiché la maggior parte dei nostri dati consisteva di questi ID. Dal momento che non sembra che tu abbia bisogno di risparmiare spazio (dato che si tratta solo di password, non di qualche altro oggetto enorme in scala), non vedo alcun motivo per usare binari qui.

Il problema più grande che abbiamo avuto era costantemente, fastidiosamente, avendo i dati binari appaiono nella console (ogni volta che si digita selezionare * si sente un milione di segnali acustici), e si deve fare sempre selezionare HEX() o inserire UNHEX (), che è un dolore.

Infine, se si mescolano e partita (per errore) binario e HEX/UNHEX e di unirsi a questo valore, si potrebbe abbinare record mai inteso.

+0

+1 e accettato per dare alcuni problemi e intuizioni del mondo reale. Grazie! – nickf

+0

Amo il tuo uso di 'BINARY' per risparmiare spazio! Pensi che potresti aiutarmi ad andare sulla strada giusta qui? http://stackoverflow.com/questions/15539540/convert-c-int-to-varbinary-and-back-again –

2

Il risparmio di spazio su disco rigido di memorizzazione delle password con hash come binario anziché varchar è probabilmente insignificante. Quanti utenti è probabile avere in questa tabella? Moltiplicare questo per la differenza di spazio tra BINARY(20) e VARCHAR(n) e penso che troverete non si tratta di un risparmio significativo. Personalmente, preferirei la rappresentazione esadecimale perché almeno posso scriverlo in una query se sto facendo qualche operazione ad-hoc durante lo sviluppo o scrivendo un test unitario per convalidare le operazioni relative alla password. L'esadecimale è un po 'più leggibile di un file binario se mi capita di caricare un dump di dati in un editor di testo, ecc. La mia linea di fondo è che la rappresentazione esadecimale sarebbe più comoda durante il ciclo di sviluppo.

+0

si può sempre chiamare HEX (myBinaryField) per visualizzare come esadecimale. – nickf

+0

@nickf: Certo, potresti. Sarebbe solo meno conveniente. – Asaph

7

Qui è la mia ripartizione:

  1. Se si utilizzano le stringhe invece di binario, utilizzare un campo di lunghezza fissa. Dato che gli aloni di hashing emettono tutti una lunghezza fissa, puoi risparmiare spazio.
  2. Poiché si sta eseguendo un confronto di uguaglianza, non è necessario per gli indici. I campi binari non hanno alcun tipo di collazione o set di caratteri.
  3. I tipi di colonna BINARY non presentano avvertimenti di memorizzazione dispari come i BLOB.
  4. Ogni carattere esadecimale rappresenta 4 bit negli 8 (o 7) bit che consuma. Ciò significa che l'archiviazione binaria è due volte più efficiente.
  5. MOLTO IMPORTANTE: a meno che non si stia lavorando in un sistema integrato in cui ogni byte conta, non farlo. Avere una rappresentazione dei caratteri ti consentirà un debugging migliore. Inoltre, ogni volta che uno sviluppatore sta lavorando su un problema come questo, mi chiedo perché. Ogni decisione architettonica come questa ha dei compromessi e questo non sembra aggiungere valore al tuo progetto.
  6. È sempre possibile convertire in BINARY in seguito con un semplice script SQL.

In breve, utilizzare un campo di testo a lunghezza fissa. Non c'è alcun vantaggio nel contare i byte nel mondo attuale, specialmente quando il cambiamento è facile da ottenere.

Spero che questo aiuti.

0

Perché reinventare la ruota? Perché non usare la tabella CHAR(41) come "mysql.user"? È un formato noto, quindi i futuri manutentori non si gratteranno sul tuo schema speciale? Rendi tutto più semplice con tutti, semplicemente annotando "proprio come le password MySQL".

2

Se volete un modo semplice per memorizzare binario in SQL ... è possibile convertire in esadecimale prima. Check out questa pagina: http://kekoav.com/blog/36-computers/58-uuids-as-primary-keys-in-mysql.html

Converti in esadecimale, togliere il "-" e mettere "0x" davanti alla stringa. Mysql capirà come contenuto di un byte.

Esempio: INSERT INTO utenti SET password = 0x1e8ef774581c102cbcfef1ab81872213

2

Questa è una vecchia questione, ma ho notato che nessuno ha menzionato la convalida dei dati come un vantaggio a una colonna binaria. Nello specifico, è possibile memorizzare un valore non valido in una colonna CHAR (40) utilizzando i caratteri che non sono cifre esadecimali (0-9, a-f).

È ancora possibile inserire il valore errato nella colonna BINARY (ad esempio, se si dimentica di chiamare UNHEX), ma non sarà necessario prendere in considerazione la lettura di un valore dal database che non analizza correttamente.