Mam proste pytanie, które pojawiło się, gdy chciałem zapisać wynik skrótu SHA1 w bazie danych MySQL:
Jak długo powinno być pole VARCHAR, w którym przechowuję wynik skrótu?
Mam proste pytanie, które pojawiło się, gdy chciałem zapisać wynik skrótu SHA1 w bazie danych MySQL:
Jak długo powinno być pole VARCHAR, w którym przechowuję wynik skrótu?
Odpowiedzi:
Używałbym VARCHAR
do danych o zmiennej długości, ale nie do danych o stałej długości. Ponieważ wartość SHA-1 ma zawsze długość 160 bitów, po VARCHAR
prostu zmarnuje dodatkowy bajt na długość pola o stałej długości .
Nie chciałbym też przechowywać wartości, którą SHA1
zwraca. Ponieważ wykorzystuje tylko 4 bity na znak, a zatem wymagałoby 160/4 = 40 znaków. Ale jeśli używasz 8 bitów na znak, potrzebujesz tylko pola o długości 160/8 = 20 znaków.
Dlatego polecam użycie BINARY(20)
i UNHEX
funkcję do konwersji SHA1
wartości na binarną.
Porównałem wymagania dotyczące przechowywania dla BINARY(20)
i 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
);
Z milionem rekordów binary(20)
zajmuje 44,56 mln, podczas gdy char(40)
zajmuje 64,57 mln.
InnoDB
silnik.
UNHEX()
ręcznie plik sql.
Skrót SHA1 ma 40 znaków!
Odniesienie zaczerpnięte z tego bloga:
Poniżej znajduje się lista algorytmów haszujących wraz z wymaganymi rozmiarami bitów:
Utworzono jedną przykładową tabelę z wymaganym 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)
);
Tak więc długość wynosi od 10 16-bitowych znaków do 40 cyfr szesnastkowych.
W każdym razie zdecyduj, jaki format chcesz przechowywać, i ustaw pole o stałym rozmiarze na podstawie tego formatu. W ten sposób nie będziesz miał zmarnowanej przestrzeni.
Możesz nadal używać VARCHAR w przypadkach, gdy nie zawsze przechowujesz hash dla użytkownika (np. Uwierzytelnianie kont / zapomnienie adresu URL logowania). Gdy użytkownik uwierzytelnił / zmienił swoje dane logowania, nie powinien być w stanie użyć skrótu i nie powinien mieć powodu do tego. Możesz utworzyć oddzielną tabelę do przechowywania tymczasowego skrótu -> skojarzenia użytkowników, które można usunąć, ale nie sądzę, aby większość ludzi przejmowała się tym.
Jeśli potrzebujesz indeksu w kolumnie sha1, sugeruję CHAR (40) ze względu na wydajność. W moim przypadku kolumna sha1 jest tokenem potwierdzającym e-mail, więc na landing page zapytanie wchodzi tylko z tokenem. W tym przypadku moim zdaniem najlepszym wyborem jest CHAR (40) z INDEXEM :)
Jeśli chcesz zastosować tę metodę, pamiętaj o pozostawieniu $ raw_output = false.