2013-04-13 15 views

risposta

10

L'hash MD5 come bytea utilizzerà solo 16 byte invece di 32 per la rappresentazione hexa:

create table t (d bytea); 
insert into t (d) values 
    (digest('my_string', 'md5')), 
    (decode(md5('my_string'), 'hex')); 

Entrambe le forme sopra funzioneranno ma per utilizzare la funzione di semplice digest è necessario installare l'estensione pgcrypto come superutente:

create extension pgcrypto; 

utilizzare la funzione digest o la combinazione di decode e md5 come sopra per la ricerca di una certa stringa:

select 
    octet_length(d) ba_length, 
    pg_column_size(d) ba_column, 
    encode(d, 'hex') hex_representation, 
    octet_length(encode(d, 'hex')) h_length, 
    pg_column_size(encode(d, 'hex')) h_column 
from t 
where d = digest('my_string', 'md5') 
; 
ba_length | ba_column |  hex_representation  | h_length | h_column 
-----------+-----------+----------------------------------+----------+---------- 
     16 |  17 | 3d212b21fad7bed63c1fb560c6a5c5d0 |  32 |  36 
     16 |  17 | 3d212b21fad7bed63c1fb560c6a5c5d0 |  32 |  36 

Il valore pg_column_size è la dimensione di archiviazione. È meno della metà dello bytea rispetto alla rappresentazione hexa.

1

bytea ha un sovraccarico di un byte, ma con il riempimento a otto byte ciò comporterà uno spreco significativo.

Invece, considerare l'utilizzo del tipo uuid, che utilizza solo 16 byte. Dovrai usare qualcosa come REPLACE(md5::text, '-', '') as md5 quando lo selezioni, ma dovrebbe essere un'operazione veloce.

+0

Avete un riferimento per 'riempimento a 8 byte'? Tutti [i documenti dicono] (http://www.postgresql.org/docs/9.4/static/datatype-binary.html) è quella dimensione di archiviazione = "1 o 4 byte più la stringa binaria effettiva" –

+0

Due problemi: un) stai memorizzando 1 + 16 = 17 byte, la colonna successiva sarà riempita per typalign in [pg_type] (http://www.postgresql.org/docs/9.0/static/catalog-pg-type.html), b) vedi [questa domanda] (http://stackoverflow.com/questions/2966524/calculating-and-saving-space-in-postgresql) per quanto riguarda MAXALIGN e il [riferimento al layout di pagina] (http://www.postgresql.org /docs/9.4/static/storage-page-layout.html) per l'allineamento * riga *. ["I dati utente effettivi (colonne della riga) iniziano con l'offset indicato da t_hoff, che deve sempre essere un multiplo della distanza MAXALIGN per la piattaforma." == 8 su x64]. – GreenReaper

+0

In questo caso specifico, l'utilizzo dello spazio di riga sarebbe probabilmente 23 + 1 (intestazione di riga + intestazione nulla per un massimo di 8 colonne) + 4 (lunghezza_bass) + 4 (colonna_big) + 1 + 16 (rappresentazione_esempio) + 3 (riempimento di allineamento per h_length) + 4 (h_length) + 4 (h_column) = 60 + 4 (row padding). Ecco come ottieni 1 + 3 + 4 = 8 byte in più rispetto a uuid. In conclusione: se ti interessa lo spazio, devi preoccuparti del layout della tua riga. Di solito, mettere prima i campi grandi è vicino a quello ottimale, anche se è maggiore di 8 byte potresti riconsiderare. – GreenReaper

Problemi correlati