Задавайте вопросы, мы ответим
Вы не зашли.
Добрый день!
md5 может существовать в разных видах:
- 16 байт (по своей природе)
- либо 2 числа BIGINT UNSIGNED (по 8 байт)
- либо 32 символа.
В связи с эти стоит вопрос - как хранить md5 в базе данных так, чтобы обеспечить максимальную скорость обработки запросов SELECT по ключу который есть md5, ну и... и по возможности минимальное использование памяти - оперативной и дисковой....
###############
Детали такие:
###############
Есть таблица desc в БД (InnoDB):
id - Primary key text - BLOB
id должно быть типа md5.
В таблице предполагается хранить... скажем 1 200 000 записей
Предполагается делать выборку данных из таблицы:
SELECT text FROM desc WHERE id = "<реальный md5 в каком то виде>"
Следовательно нужен индекс по md5.
Какой способ выбрать чтобы хранить md5 в базе?
###############
ВАРИАНТЫ
###############
Я так понимаю, существуют следующие варианты:
###
1. Классический
###
CHAR(32)
ПЛОХО т.к.
Индекс будет занимать много места на диске - 32 байта. Больше чтения с диска - меньше скорость. Больше места в памяти.
Неполный индекс CHAR(20)... Что он даст....
ХОРОШО:
Удобно работать с таким полем...
###
2. Сомнительный
###
Как 2 числа
BIGINT md5_part1, BIGINT md5_part2
PRIMARY KEY тогда будет (md5_part1, md5_part2)
ХОРОШО: уже 16 байт на диске, а не 32.
ПЛОХО:
1. не очень удобно с таким индексом работать из программ
2. НЕ понятно, будет ли такой индекс эффективен. или хотя бы эффективнее чем неполный индекс по CHAR(16) а не 32 из варианта 1.
###
3. С параноидальными сомнениями.
###
BINARY(16)
ПЛОХО: Есть подозрение, что число BIGINT машиной обрабатывается быстрее чем 8 байт бинарных данных. И индекс по BIGINT
поэтому может оказаться более быстрым по своей природе, чем индекс по BINARY(8).
Суть подозрений в том, что INT обрабатывается вероятно машиной как число, т.е. 4 или 8 байт (x64) за одну команду - сложить, вычесть и т.п. Т.е. на шыну данных выставляется 32 бита... или 64...
А вот как BINARY обрабатывается, если оно во внутренней форме не преобразовывается к INT - я не могу сказать.
А вдруг как 8 раз по 8 бит...
###
4. Странный
###
В документации написано, что INT это строго 8 байт.
Но у меня под виндой на миске 5.1.24-rc-community
прокатывает:
mysql> create table asdf (id int(16) UNSIGNED PRIMARY KEY, name BLOB);
Query OK, 0 rows affected (0.22 sec)
mysql> describe asdf;
+-------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id | int(16) unsigned | NO | PRI | NULL | |
| name | blob | YES | | NULL | |
+-------+------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
Как это понимать???
Либо можно хранить INT(16)? либо миска внутри все сама приводит к BINARY.
Но это врядли т.к., когда я делаю CREATE TABLE ( ... BIGINT ... )
и затем describe таблицы, миска пишет, что поле в созданной таблице это INT(20)!
Вот как то так... Как бы вы хранили md5 в связи с выше сказанным, и что такое int(16) которое работает, если знаете...
Неактивен
int(16) - это обычное число (4 байта, почему 8?), в котором отображаются 16 цифр. Лучше
для числовых полей не писать ограничение - смысла нет
Любой индекс используется в бинарном виде. Один индекс на binary(16) позволит Вам
вытаскивать данные достаточно быстро. Один индекс над двумя полями bigint должен
быть точно такой же, только запрос будет немного сложнее
Неактивен
А..... Это оказывается число знаков, а не байт... :-) Про binary понял, спасибо!
Неактивен
Обсуждаемый вопрос интересен, но походу обсуждения собеседники видимо ошибаются или я что-то не правильно понимаю, поправте если у меня будет не верно
вобще int - это число, занимает память 4 байта, Диапазон для знакового представления от -2147483648 до 2147483647, для беззнакового от 0 до 4294967295,
максимум 10 цифр плюс один символ если есть знак
А к вопросу о преимуществе хранить как BINARY, как мы помним из математики, бинарное представление самое не экономичное из всех возможных по занимаемым символам, поэтому собсна и используется шестнадцатеричное представление в программах, в коде и т.д., например 32 битный хеш будет иметь длину 32*8 = 256 бит, т.е. для хранения нужно создать поле BINARY(255) - длина у него будет 256 символов еденичек и ноликов идущих друг за другом, что не экономично для хранения. Получается интересная вещь, что бы хранить один бит, будет расходоваться один байт ))
Помоему самый оптимальный вариант хранения это CHAR(32) для экономии на индексе можно делать индекс не на всю дину, а скажем на половину, все равно будет быстро находить, т.к. даже при такой длине индекса повторов наверно не будет на миллионе записей.
Неактивен
denisimus написал:
вобще int - это число, занимает память 4 байта, Диапазон для знакового представления от -2147483648 до 2147483647, для беззнакового от 0 до 4294967295,
максимум 10 цифр плюс один символ если есть знак
А к вопросу о преимуществе хранить как BINARY, как мы помним из математики, бинарное представление самое не экономичное из всех возможных по занимаемым символам, поэтому собсна и используется шестнадцатеричное представление в программах, в коде и т.д., например 32 битный хеш будет иметь длину 32*8 = 256 бит, т.е. для хранения нужно создать поле BINARY(255) - длина у него будет 256 символов еденичек и ноликов идущих друг за другом, что не экономично для хранения. Получается интересная вещь, что бы хранить один бит, будет расходоваться один байт ))
int в машинном коде занимает 4 байта (или 8) - машина не хранит его в десятичном виде.
256 в бинарном виде помещается в BINARY(32) и занимает 32 байта.
Текстовое представление наименее эффективное, так как оно не бинарное - каждый символ занимает 1 байт, но несет информации на полбайта (число 1-16).
Неактивен
rgbeast написал:
Текстовое представление наименее эффективное, так как оно не бинарное - каждый символ занимает 1 байт, но несет информации на полбайта (число 1-16).
Пожалуйста объясните подробнее, почему именно бинарное более эффективно, по сравнению с Char(32) по количеству занимаемого места одинакового c Char(32) получается, как вы сами говорите.
Различия я вижу только в том что, с помощью бинарного поля можно сохранить больше информации при той же длине 32 байта, но мы же хеши храним, это преимущество нивелируется этим условием.
Неактивен
Допустим у нас 16-ричное число из 8 байт (64 бита). В бинарном виде оно будет занимать 8 байт. В текстовом - 16 символов, то есть 16 байт, так как каждый байт занимает в текстовом 16-ричном предствлении 2 символа.
Неактивен
Сколько же места в таблице в БД MySQL будет занимать один md5 хеш (например такой, 7117720c97d7ff7870892f3066908567)
1)Сохраненный в виде Char(32) = 32 байта это понятно
2)А вот тот же хеш но сохраненный как Binary() тоже 32 байта или сколько?
Неактивен
2 символа - один байт, то есть 16 байт, 128 бит. Значит влезет в binary(16) и будет занимать 16 байт. Альтернативно можно хранить как 4 числа int (каждое - 8 шестнадцатиричных знаков), каждое из которых займет по 4 байта, то есть те же 16 байт.
Неактивен