Tengo una pregunta simple que ocurrió cuando quería almacenar el resultado de un hash SHA1 en una base de datos MySQL:
¿Cuánto tiempo debe estar el campo VARCHAR en el que almaceno el resultado del hash?
Tengo una pregunta simple que ocurrió cuando quería almacenar el resultado de un hash SHA1 en una base de datos MySQL:
¿Cuánto tiempo debe estar el campo VARCHAR en el que almaceno el resultado del hash?
Respuestas:
Lo usaría VARCHAR
para datos de longitud variable, pero no con datos de longitud fija. Debido a que un valor SHA-1 siempre tiene una longitud de 160 bits, VARCHAR
simplemente desperdiciaría un byte adicional para la longitud del campo de longitud fija .
Y tampoco almacenaría el valor que SHA1
está devolviendo. Porque usa solo 4 bits por carácter y, por lo tanto, necesitaría 160/4 = 40 caracteres. Pero si usa 8 bits por carácter, solo necesitaría un campo largo de 160/8 = 20 caracteres.
Por lo tanto, le recomiendo que use BINARY(20)
y la UNHEX
función para convertir el SHA1
valor a binario.
Comparé los requisitos de almacenamiento para BINARY(20)
y CHAR(40)
.
CREATE TABLE `binary` (
`id` int unsigned auto_increment primary key,
`password` binary(20) not null
);
CREATE TABLE `char` (
`id` int unsigned auto_increment primary key,
`password` char(40) not null
);
Con millones de registros binary(20)
toma 44.56M, mientras que char(40)
toma 64.57M.
InnoDB
motor.
UNHEX()
manualmente al sql.
¡Un hash SHA1 tiene 40 caracteres de largo!
Referencia tomada de este blog:
A continuación se muestra una lista de algoritmos de hash junto con su tamaño de bit requerido:
Se creó una tabla de muestra con require CHAR (n):
CREATE TABLE tbl_PasswordDataType
(
ID INTEGER
,MD5_128_bit CHAR(32)
,SHA_160_bit CHAR(40)
,SHA_224_bit CHAR(56)
,SHA_256_bit CHAR(64)
,SHA_384_bit CHAR(96)
,SHA_512_bit CHAR(128)
);
INSERT INTO tbl_PasswordDataType
VALUES
(
1
,MD5('SamplePass_WithAddedSalt')
,SHA1('SamplePass_WithAddedSalt')
,SHA2('SamplePass_WithAddedSalt',224)
,SHA2('SamplePass_WithAddedSalt',256)
,SHA2('SamplePass_WithAddedSalt',384)
,SHA2('SamplePass_WithAddedSalt',512)
);
Por lo tanto, la longitud es de entre 10 caracteres de 16 bits y 40 dígitos hexadecimales.
En cualquier caso, decida el formato que va a almacenar y haga que el campo tenga un tamaño fijo basado en ese formato. De esa manera no tendrá ningún espacio desperdiciado.
Es posible que aún desee utilizar VARCHAR en casos en los que no siempre almacena un hash para el usuario (es decir, autenticación de cuentas / URL de inicio de sesión olvidada). Una vez que un usuario ha autenticado / cambiado su información de inicio de sesión, no debería poder usar el hash y no debería tener ninguna razón para hacerlo. Podría crear una tabla separada para almacenar hash temporal -> asociaciones de usuarios que podrían eliminarse, pero no creo que la mayoría de las personas se molesten en hacer esto.
Si necesita un índice en la columna sha1, sugiero CHAR (40) por razones de rendimiento. En mi caso, la columna sha1 es un token de confirmación de correo electrónico, por lo que en la página de destino la consulta solo ingresa con el token. En este caso CHAR (40) con INDEX, en mi opinión, es la mejor opción :)
Si desea adoptar este método, recuerde dejar $ raw_output = false.