SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 29.07.2008 15:27:14

Михаил
Участник
Зарегистрирован: 29.07.2008
Сообщений: 3

Как лучше хранить md5 в Mysql?

Добрый день!

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) которое работает, если знаете...

Неактивен

 

#2 29.07.2008 15:49:02

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Как лучше хранить md5 в Mysql?

int(16) - это обычное число (4 байта, почему 8?), в котором отображаются 16 цифр. Лучше
для числовых полей не писать ограничение - смысла нет smile

Любой индекс используется в бинарном виде. Один индекс на binary(16) позволит Вам
вытаскивать данные достаточно быстро. Один индекс над двумя полями bigint должен
быть точно такой же, только запрос будет немного сложнее smile

Неактивен

 

#3 29.07.2008 16:13:52

Михаил
Участник
Зарегистрирован: 29.07.2008
Сообщений: 3

Re: Как лучше хранить md5 в Mysql?

А..... Это оказывается число знаков, а не байт... :-) Про binary понял, спасибо!

Неактивен

 

#4 09.12.2008 01:09:09

denisimus
Участник
Зарегистрирован: 30.10.2008
Сообщений: 18

Re: Как лучше хранить md5 в Mysql?

Обсуждаемый вопрос интересен, но походу обсуждения собеседники видимо ошибаются или я что-то не правильно понимаю, поправте если у меня будет не верно

вобще int - это число, занимает память 4 байта, Диапазон для знакового представления от -2147483648 до 2147483647, для беззнакового от 0 до 4294967295,
максимум 10 цифр плюс один символ если есть знак

А к вопросу о преимуществе хранить как BINARY, как мы помним из математики, бинарное представление самое не экономичное из всех возможных по занимаемым символам, поэтому собсна и используется шестнадцатеричное представление в программах, в коде и т.д., например 32 битный хеш будет иметь длину 32*8 = 256 бит, т.е. для хранения нужно создать поле  BINARY(255) - длина у него будет 256 символов еденичек и ноликов идущих друг за другом, что не экономично для хранения. Получается интересная вещь, что бы хранить один бит, будет расходоваться один байт ))

Помоему самый оптимальный вариант хранения это CHAR(32) для экономии на индексе можно делать индекс не на всю дину, а скажем на половину, все равно будет быстро находить, т.к. даже при такой длине индекса повторов наверно не будет на миллионе записей.

Неактивен

 

#5 09.12.2008 06:33:10

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Как лучше хранить md5 в Mysql?

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).

Неактивен

 

#6 09.12.2008 07:26:55

denisimus
Участник
Зарегистрирован: 30.10.2008
Сообщений: 18

Re: Как лучше хранить md5 в Mysql?

rgbeast написал:

Текстовое представление наименее эффективное, так как оно не бинарное - каждый символ занимает 1 байт, но несет информации на полбайта (число 1-16).

Пожалуйста объясните подробнее, почему именно бинарное более эффективно, по сравнению с Char(32) по количеству занимаемого места одинакового c Char(32) получается, как вы сами говорите.
Различия я вижу только в том что, с помощью бинарного поля можно сохранить больше информации при той же длине 32 байта, но мы же хеши храним, это преимущество нивелируется этим условием.

Неактивен

 

#7 09.12.2008 07:33:07

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Как лучше хранить md5 в Mysql?

Допустим у нас 16-ричное число из 8 байт (64 бита). В бинарном виде оно будет занимать 8 байт. В текстовом - 16 символов, то есть 16 байт, так как каждый байт занимает в текстовом 16-ричном предствлении 2 символа.

Неактивен

 

#8 09.12.2008 08:19:51

denisimus
Участник
Зарегистрирован: 30.10.2008
Сообщений: 18

Re: Как лучше хранить md5 в Mysql?

Сколько же места в таблице в БД MySQL будет занимать один md5 хеш (например такой, 7117720c97d7ff7870892f3066908567)
1)Сохраненный в виде Char(32) = 32 байта это понятно
2)А вот тот же хеш но сохраненный как Binary() тоже 32 байта или сколько?

Неактивен

 

#9 09.12.2008 12:10:03

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Как лучше хранить md5 в Mysql?

2 символа - один байт, то есть 16 байт, 128 бит. Значит влезет в binary(16) и будет занимать 16 байт. Альтернативно можно хранить как 4 числа int (каждое - 8 шестнадцатиричных знаков), каждое из которых займет по 4 байта, то есть те же 16 байт.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson