Що саме робить null ефективністю та сховищем (простором) в MySQL?
Наприклад:
TINYINT: 1 байт TINYINT w / NULL 1 байт + якось зберігає NULL?
Відповіді:
Це залежить від того, який механізм зберігання даних ви використовуєте.
У форматі MyISAM кожен заголовок рядка містить бітове поле з одним бітом для кожного стовпця для кодування стану NULL. Стовпець із значенням NULL все ще займає місце, тому значення NULL не зменшує обсяг пам’яті. Див. Https://dev.mysql.com/doc/internals/en/myisam-introduction.html
У InnoDB кожен стовпець має "зміщення старту поля" в заголовку рядка, який становить один або два байти на стовпець. Високий біт у цьому полі зміщення старту ввімкнено, якщо стовпець NULL. У цьому випадку стовпець взагалі не потрібно зберігати. Отже, якщо у вас багато NULL, ваш обсяг пам’яті повинен бути значно зменшений. Див. Https://dev.mysql.com/doc/internals/en/innodb-field-contents.html
РЕДАГУВАТИ:
Біти NULL є частиною заголовків рядків, ви не вирішите їх додавати.
Єдиний спосіб, яким я можу уявити, що NULL покращує продуктивність, це те, що в InnoDB сторінка даних може вмістити більше рядків, якщо рядки містять NULL. Тож ваші буфери InnoDB можуть бути ефективнішими.
Але я був би дуже здивований, якщо це забезпечить значну перевагу на практиці. Турбуючись про вплив NULL на продуктивність, це в області мікро-оптимізації. Вам слід зосередити свою увагу в іншому місці, в областях, які дають більший виграш. Наприклад, додавання добре підібраних індексів або збільшення розподілу кешу бази даних.
Відповідь Білла хороша, але трохи застаріла. Використання одного або двох байтів для зберігання NULL стосується лише формату рядка InnoDB REDUNDANT. Оскільки MySQL 5.0.3 InnoDB використовує формат рядка COMPACT , який використовує лише один біт для зберігання NULL (звичайно, один байт є мінімальним), тому:
Необхідний простір для NULL = СТОЛ (N / 8) байт, де N - кількість стовпців NULL в рядку.
Згідно з офіційним сайтом MySQL про COMPACT проти REDUNDANT:
Компактний формат рядків зменшує простір для зберігання рядків приблизно на 20% за рахунок збільшення використання ЦП для деяких операцій. Якщо ваше робоче навантаження є типовим, обмеженим швидкістю потрапляння в кеш і швидкістю диска, компактний формат, швидше за все, буде швидшим.
Ви починаєте бачити економію тут:
З іншого боку, я пропоную використовувати NULL над порожніми рядками або нулями, оскільки вони більш організовані, портативні та вимагають менше місця. Щоб покращити продуктивність та заощадити простір, зосередьтеся на використанні належних типів даних, індексів та запитів замість дивних прийомів.
Докладніше на: https://dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html
Я погодився б із Біллом Карвіном, хоча додав би ці поради щодо MySQL . Номер 11 стосується саме цього:
Перш за все, запитайте себе, чи є якась різниця між значенням порожнього рядка та значенням NULL (для полів INT: 0 проти NULL). Якщо немає причин мати обидва, вам не потрібно поле NULL. (Чи знали ви, що Oracle вважає NULL і порожній рядок однаковими?)
Стовпці NULL вимагають додаткового простору, і вони можуть додати складності вашим операторам порівняння. Просто уникайте їх, коли можете. Однак я розумію, що у деяких людей можуть бути дуже конкретні причини мати значення NULL, що не завжди погано.
З іншого боку, я все ще використовую null для таблиць, які не мають тонн рядків, здебільшого тому, що мені подобається логіка сказати NOT NULL.
Оновлення Переглядаючи це пізніше, я б додав, що мені особисто не подобається використовувати в базі даних 0 замість NULL, і я не рекомендую цього Це може легко призвести до багатьох помилкових спрацьовувань у вашому додатку, якщо ви не будете обережні.
dev.mysql.com/doc/refman/5.0/en/is-null-optimization.html
MySQL може виконати ту саму оптимізацію для col_name IS NULL, яку він може використовувати для col_name = constant_value. Наприклад, MySQL може використовувати індекси та діапазони для пошуку NULL за допомогою IS NULL