12. Поради щодо вибору типів даних в MySQL

Вибираючи тип даних для стовпця, перш за все варто визначити загальний клас даних, який краще використовувати для стовпця: числові, строкові або часові;
Дані необхідно вибрати конкретний тип даних з представлених в класі. Багато типів даних MySQL дозволяють зберігати дані одного і того ж типу, але з різними діапазонами значень, точністю або необхідним фізичним простором (на диску або в пам'яті).
Деякі типи мають специфічні властивості.
Наприклад, у DATETIME і TIMESTAMP можна зберігат и один і той же тип даних: дату і час, з точністю до секунди.
Однак тип TIMESTAMP потребує вдвічі менше місця, дозволяє працювати з часовими поясами і володіє спеціальними засобами автоматичного оновлення. З іншого боку, діапазон допустимих значень для нього менший.

На що звернути увагу при виборі типу даних:

Тому значення дати і часу краще зберігати у вбудованих типах даних MySQL, а не в рядках, а для IP-адрес має сенс використовувати цілочисельні типи даних.

Швидкість при з'єднанні стовпців типу VARCHAR і ENUM:
Запитів в секунду:

 З'єднання VARCHAR з VARCHAR	2.6
 З'єднання VARCHAR з ENUM	1.7
 З'єднання ENUM з VARCHAR	1.8
 З'єднання ENUM з ENUM	3.5

З метою сумісності MySQL підтримує різні псевдоніми, наприклад INTEGER, BOOL - це псевдоніми (синоніми) одного і того ж типу даних. Даний факт не впливає на продуктивність.

Числові типи
BIT - можна використовувати для зберігання одного або декількох значень true-false в одному стовпці. BIT (1) визначає поле, що містить один біт, BIT (2) - два біта і т. д. Максимальна довжина стовпчика типу BIT дорівнює 64 бітам.
До версії MySQL 5.0 слово BIT було синонімом TINYINT. Поведінка типу BIT залежить від підсистеми зберігання.

Зберігання цілих чисел

СУБД MySQL дозволяє вказувати для цілих чисел «розмір», наприклад INT (11).
Для більшості додатків це не має значення: діапазон можливих значень цим не обмежується. Однак даний параметр говорить деяким інтерактивним інструментам MySQL, скільки позицій необхідно зарезервувати для виведення числа.
З точки зору зберігання і обчислення INT(1) і INT(20) ідентичні.
Цілочисельний тип даних довжиною N біт дозволяє зберігати значення від -2^(N-1) до 2^(N-1) -1.
Цілі типи даних можуть мати необов'язковий атрибут UNSIGNED, що забороняє негативні значення і вдвічі збільшує верхню межу додатних значень. Наприклад, тип TINYINT UNSIGNED дозволяє зберігати значення від 0 до 255, а не від -128 до 127.
Знакові і беззнакові типи потребують однакового простору і мають однакову продуктивністю.
Необов'язковий атрибут ZEROFILL заповнить нулями вільні позиції зліва. Наприклад з TINYINT (3) ZEROFILL, величина 2 буде записана, як 002.

Зберігання дробовних чисел
Всі типи допускають наближені математичні обчислення з плаваючою точкою, але у випадку з FLOAT і DOUBLE операції виконуються швидше, так як процесор виконує їх природним для нього чином.

Для типів з плаваючою точкою можна вказати максимально дозволену кількість цифр до і після десяткової коми. У випадку з DECIMAL це впливає на об’єм пам’яті, необхідної для зберігання даних стовпця. При заданні точності, в деяких випадках, MySQL непомітно для користувача може вибирати інший тип даних або буде округляти значення при збереженні.
FLOAT і DOUBLE можуть мати параметр UNSIGNED, що забороняє негативні числа, але діапазон значень від цього не зміниться.
Число типу DECIMAL в MySQL 5.0 і новіших версіях може містити до 65 цифр. У більш ранніх версіях MySQL тип DECIMAL мав межа 254 цифри і зберігав значення у вигляді упакованих рядків (один байт на цифру).
Однак ці версії СУБД не вміли використовувати такі великі числа в обчисленнях, оскільки тип DECIMAL був просто форматом зберігання. При виконанні будь-яких операцій значення DECIMAL перетворювалися в тип DOUBLE.

Строкові типи
У типах CHAR і VARCHAR рядки розглядаються як послідовності символів, тому, при використанні багатобайтових кодувань, наприклад UNICODE, розмір рядка в байтах буде більше, ніж в символах.

Зазвичай має сенс використовувати тип VARCHAR при дотриманні хоча б однієї з таких умов:
максимальна довжина рядка в стовпці значно більше середньої;
оновлення поля виконується рідко, так що фрагментація не викликає особливих проблем;
або використовується складне кодування, наприклад UTF-8, в якому для зберігання одного символу використовується змінна кількість байтів.

При створенні таблиці можна комбінувати стовпці типів CHAR і VARCHAR. В цьому випадку MySQL змінить тип стовпців CHAR на тип VARCHAR.
Уявімо що строковий тип застосовується для зберігання значень Y і N. У разі використання CHAR (1) значення займе один байт, тоді як для типу VARCHAR (1) буде потрібно два байта через наявність додаткового байта довжини рядка.

Приклади\\??????????????????????????

Значення CHAR(4)Пам'ятьVARCHAR(4)Пам'ять
|' ' 4 байта 1 байт
'ab' 'ab ' 4 байта 'ab' 3 байта
'abcd' 'abcd' 4 байта 'abcd' 5 байт
'abcdefgh''abcd'4 байта 'abcd' 5 байт

Двійкові рядки
Для сумісності зі старими версіями MySQL введені два спеціальних типи даних: BINARY і VARBINARY, які еквівалентні типам CHAR і VARHAR, проте рядок в них розглядається як послідовність байтів, а не символів.
У BINARY рядках не можна кодувати і упорядковані вони, як звичайні послідовності байтів.
Ці типи можуть бути корисні, коли потрібно зберігати двійкові дані, і потрібно, щоб MySQL порівнював значення як байти, а не як символи. При цьому, двійкове порівняння може виявитися значно простіше і швидше символьного.

Текстові та бінарні типи Вони призначені для зберігання двійкових або символьних даних великих об’ємів.
MySQL обробляє значення BLOB і TEXT, як окремі об'єкти. Єдина відмінність між BLOB і TEXT полягає в тому, що типи BLOB зберігають двійкові дані без урахування впорядкування і кодування, а з типами TEXT асоційовані схеми впорядкування і кодування.
Сімейство TEXT використовується для зберігання безпосередньо тексту:

Сімейство BLOB використовується для зберігання зображень, звуку, електронних документів і т.д .:

MySQL не може індексувати дані цих типів по повній довжині і не може використовувати для сортування індекси.
Підсистема зберігання Memory не підтримує типи BLOB і TEXT.

Типи данихМакс. розмірБайт
TINYTEXT або TINYBLOB28-1255
TEXT або BLOB216-1 (64K-1) 65535
MEDIUMTEXT або MEDIUMBLOB224-1 (16M-1)16777215
LONGTEXT абоLONGBLOB232-1 (4G-1)4294967295

Складені типи

Часові типи

Для зберігання типу TIMESTAMP використовується тільки чотири байти, але він дозволяє представити значно менший діапазон дат, ніж тип DATETIME: з 1970 року до деякої дати в 2038 році.
В MySQL є функції FROM_UNIXTIME () і UNIX_TIMESTAMP () – службові функції для перетворення. Стовпці типу TIMESTAMP за замовчуванням створюються в режимі NOT NULL, якщо не вказано значення для стовпця, MySQL вставляє в перший стовпець типу TIMESTAMP поточний час.
Тип TIMESTAMP має також спеціальні властивості, яких немає у типу DATETIME.

Таблиці типу Memory
Таблиці типу Memory (раніше називались таблицями типу HEAP) корисні, коли необхідно здійснити швидкий доступ до даних, які або ніколи не змінюються, або немає потреби в їх збереженні після перезапуску.
Зазвичай таблиці типу Memory обробляються приблизно на порядок швидше, ніж таблиці MyISAM. Всі їх дані зберігаються в пам'яті, тому запитам не потрібно чекати виконання операцій дискового введення / виводу. Структура таблиці Memory зберігається після перезапуску сервера, але дані губляться.
Векілька корисних застосувань для таблиць Memory:

Таблиці Memory працюють дуже швидко, але не завжди годяться в якості заміни дискових таблиць. Вони використовують блокування на рівні таблиці, що зменшує конкуренцію під час запису, і не підтримують стовпці типу TEXT і BLOB.
Також вони допускають використання тільки рядків фіксованого розміру, тому значення типу VARCHAR зберігаються як значення типу CHAR, що призводить до зростання споживання пам'яті.
MySQL всередині себе використовує підсистему Memory для зберігання проміжних результатів при обробці запитів, яким потрібна тимчасова таблиця. Якщо проміжний результат стає занадто великим для таблиці Memory або містить стовпці типу TEXT або BLOB, то MySQL перетворює його в таблицю MyISAM на диску.
Часто плутають таблиці типу Memory з тимчасовими таблицями, які створюються командою CREATE TEMPORARY TABLE.
Тимчасові таблиці можуть використовувати будь-яку підсистему зберігання. Це не те ж саме, що таблиці типу Memory. Тимчасові таблиці видно тільки в одному з'єднанні і повністю зникають при його закритті.