Содержание
Выбор типов данных
Основные принципы
При выборе типа данных для колонки таблицы необходимо руководствоваться следующими основными принципами:
- чем меньше места занимает тип, тем лучше (чтобы все уместилось в память)
- чем проще тип, тем лучше (число лучше строки)
Крайне желательно использовать NOT NULL:
- лучше используются индексы
- не тратится время на сравнение каждого значения с NULL
- колонка с
NULLзанимает больше места - если колонка требует наличия пустых значений, по возможности рекомендуется заменять их на специальное непустое (нулевое и т.д.)
Некоторые рекомендации по использованию различных типов данных
INT vs FLOAT vs DOUBLE vs DECIMAL
- по возможности
INT(TINYINT,SMALLINTи т.д.); - по возможности
UNSIGNED; - для плавающей точки по возможности
FLOATвместоDOUBLEиDECIMAL DECIMAL- если дробная часть действительно важна (цены)INT(width)- влияет только на отображение
CHAR vs VARCHAR
CHAR- короткие строки и строки фиксированной длины, быстрее чемVARCHARCHARудаляет пробелы в конце строкиVARCHAR- плюс 1 или 2 байта для хранения длины;VARCHAR- меньше места, но дольше обработка, медленнее изменения
Максимальная длина строки значительно больше среднего значения - VARCHAR, произвольный текст - VARCHAR, хеши, пароли - CHAR.
TEXT vs BLOB
TEXT=BLOB+encoding+collation- Cуществуют подтипы
TINYTEXT,MEDIUMTEXT,LONGTEXT,SMALLBLOBи т.д. - отдельный способ хранения по отношению к другим полям, отдельное хранилище в InnoDB
- при сортировке используется max_sort_length символов (1024)
- при построении индекса нужно указываеть его длину
- temporary table и memory engine не поддерживают - при сложных запросах таблица на диске, снижение производительности
Вывод: использовать внимательно и по необходимости, а по возможности использовать VARCHAR.
Для html-текста лучше использовать LONGTEXT, а не TEXT, чтобы не поймать ограничение в 64кб.
DATETIME vs TIMESTAMP
- если позволяет временной интервал -
TIMESTAMPлучше DATETIME- в два раза больше местаTIMESTAMPзависит от зоны,DATETIME- нет
CREATE TABLE t1 ( ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
Желательно использовать TIMESTAMP, INT для хранения unix timestamp аналогичен TIMESTAMP, но неудобно.
- Сравнение скорости DATETIME vs TIMESTAMP vs INT
Аргументы в пользу DATETIME перед TIMESTAMP и INT
- для даты рожения
TIMESTAMPне подходит, нижний интервал ограничен1970-01-01, дляDATETIMEон равен1000-01-01 - для футуристических сайтов (высадка на Марс в 2050 году) верхний предел
TIMESTAMP- 2038 год,DATETIME- 9999 год - в отличие от
INT, удобно смотреть в базе - «у вас в приложении есть другие проблемные запросы», и оптимизация на DATETIME > TIMESTAMP не даст ничего существенного
Если очень хочется, можно использовать INT в виде YYYYMMDD, например 20160101 - 1 янврая 2016 года
