Tak. Często skrót skrótu jest przechowywany jako reprezentacja ASCII cyfr szesnastkowych, na przykład MD5 słowa „hasz” to:
0800fc577294c34e0b28ad2839435945
To jest 32-znakowy ciąg ASCII.
Ale MD5 naprawdę tworzy 128-bitową binarną wartość skrótu. To powinno wymagają przechowywania tylko 16 bajtów jako wartości binarnych zamiast cyfr szesnastkowych. Możesz więc zwiększyć wydajność przestrzeni, używając ciągów binarnych.
CREATE TABLE test.foobar (
id BINARY(16) NOT NULL PRIMARY KEY
);
INSERT INTO test.foobar (id) VALUES (UNHEX(MD5('hash')));
Odnośnie. Twoje uwagi, że bardziej zależy Ci na wydajności niż na wydajności przestrzeni:
Nie znam żadnego powodu, dla którego typ danych BINARY byłby szybszy niż CHAR.
Zmniejszenie o połowę wielkości może być korzystne dla wydajności, jeśli efektywnie korzystasz z buforów pamięci podręcznej. Oznacza to, że dana ilość pamięci podręcznej może przechowywać dwa razy więcej wierszy danych BINARY, jeśli łańcuch jest o połowę mniejszy od CHAR potrzebnego do przechowywania tej samej wartości w postaci szesnastkowej. Podobnie pamięć podręczna dla indeksu w tej kolumnie może przechowywać dwa razy więcej.
Rezultatem jest bardziej efektywna pamięć podręczna, ponieważ losowe zapytanie ma większą szansę trafienia w buforowane dane lub indeks, zamiast wymagać dostępu do dysku. Wydajność pamięci podręcznej jest ważna dla większości aplikacji bazodanowych, ponieważ zwykle wąskim gardłem jest dyskowe operacje wejścia/wyjścia. Jeśli możesz użyć pamięci podręcznej do zmniejszenia częstotliwości operacji wejścia/wyjścia na dysku, jest to o wiele większy zwrot z inwestycji niż wybór między jednym a drugim typem danych.
Jeśli chodzi o różnicę między ciągiem skrótu przechowywanym w BINARY a BIGINT, wybrałbym BIGINT. Wydajność pamięci podręcznej będzie jeszcze większa, a na procesorach 64-bitowych arytmetyka liczb całkowitych i porównania powinny być bardzo szybkie.
Nie mam pomiarów na poparcie powyższych twierdzeń. Korzyści netto wynikające z wyboru jednego typu danych w stosunku do innego zależą w dużej mierze od wzorców danych i typów zapytań w bazie danych i aplikacji. Aby uzyskać najdokładniejszą odpowiedź, musisz wypróbować oba rozwiązania i zmierzyć różnicę.
Odnośnie. Twoje przypuszczenie, że porównywanie ciągów binarnych jest szybsze niż domyślne porównywanie ciągów bez uwzględniania wielkości liter, wypróbowałem następujący test:
mysql> SELECT BENCHMARK(100000000, 'foo' = 'FOO');
1 row in set (5.13 sec)
mysql> SELECT BENCHMARK(100000000, 'foo' = BINARY 'FOO');
1 row in set (4.23 sec)
Zatem porównanie ciągów binarnych jest o 17,5% szybsze niż porównywanie ciągów bez uwzględniania wielkości liter. Ale zauważ, że po przeanalizowaniu tego wyrażenia 100 milionów razy całkowita różnica jest nadal mniejsza niż 1 sekunda. Chociaż możemy zmierzyć względną różnicę prędkości, bezwzględna różnica prędkości jest naprawdę nieznaczna.
Więc powtórzę:
- Mierz, nie zgaduj ani nie przypuszczaj. Twoje wykształcone domysły będą często błędne. Mierz przed każdą wprowadzoną zmianą i po niej, aby wiedzieć, jak bardzo to pomogło.
- Zainwestuj swój czas i uwagę tam, gdzie uzyskasz największy zwrot z każdej zainwestowanej złotówki.
- Nie przejmuj się drobiazgami. Oczywiście niewielka różnica sumuje się przy wystarczającej liczbie iteracji, ale biorąc pod uwagę te iteracje, nadal preferowana jest poprawa wydajności z większą bezwzględną korzyścią.