воскресенье, 5 апреля 2009 г.

MySQL. Выбирайте правильный числовой формат для полей!

При использовании реляционных баз данных всегда особое внимание следует уделять оптимизации структур таблиц базы данных. Это прямо сказывается, в дальнейшем, на скорости работы вашего хранилища в целом, особенно, если объёмы хранимых данных очень большие.

Все типы данных, с которыми работает СУБД MySQL можно разбить на три большие группы: числовые, текстовые и даты-времени. В данной статье хочу рассмотреть именно числовые типы, потому что у многих с ними возникает непонимание.

Числовые типы полей являются неотъемлемой частью любой таблицы базы данных. В MySQL существует 9 числовых типов данных:

  • целочисленные: TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT;
  • с плавающей запятой: FLOAT, DOUBLE;
  • с фиксированной запятой: DECIMAL;
  • и другие: BIT, и, возможно, ENUM.‫

Никогда НЕ СТОИТ ИСПОЛЬЗОВАТЬ такие комбинации, если вы не до конца понимаете их назначения и смысла:

- INT(1)‫‏‬
- BIGINT AUTO_INCREMENT
- не использовать UNSIGNED
- DECIMAL(31,0)

INT(1) – 1 не значит, что под хранение этого числа будет выделен один байт. Это глубочайшее заблуждение начинающих разработчиков программного обеспечения. Многие так и будут думать до конца жизни, что это количество байт под размещение этого поля. Но, ведь, это бред, обратитесь к официальному мануалу. Там чётко написано «Int (M)… M indicates the maximum display width for integer types». То есть, это число используется лишь при клиентском выводе числа и означает количество знаков для отображения. В общем, если кому-то интересно, то int(1) и int(11) имеют одинаковую размерность и вообще идентичны, если не использовать ZEROFILL при определении поля (для справки, ZEROFILL - означает, что число будет отображено с ведущими нулями).

Под TINYINT отводится 1 байт для хранения. TINYINT UNSIGNED может хранить числа 0 – 255. BIT –лучше всего использовать когда числа принимают значения 1 или 0. DECIMAL обычно используют для хранения денежных значений.

И никогда не стоит юзать BIGINT с AUTO_INCREMENT, это же зло. Возьмите INT UNSIGNED, он уже может вмещать ~4,3 миллиарда значений. При таком количестве записей в миллиарды в одной таблице, уже стоит серьёзно задуматься о том, чтобы разделить эти данные на несколько других таблиц. BIGINT используется для других целей, например, для суммирования больших значений.

Вообще хорошая практика – всегда использовать UNSIGNED поле для числовых значений, если нет видимой причины для использования отрицательных значений.

Надеюсь, программеры возьмут мои замечания на заметку. Сделаем код лучше!

2 комментария:

  1. Если задача хранение и просто извлечение вещественных чисел для обработки, то иногда прибегаю к хранию целой и дробной части в двух полях BIGINT (иногда необходимо до 7-го и более знака после запятой).

    ОтветитьУдалить

Рекоммендую

Попробуйте надёжный хостинг от Scala Hosting