Из структуры физических рядов Innodb, пункт № 7 под REDUNDANT ROW_FORMAT
Значение SQL NULL резервирует один или два байта в каталоге записей. Кроме того, значение SQL NULL резервирует нулевые байты в части данных записи, если она хранится в столбце переменной длины . В столбце фиксированной длины он резервирует фиксированную длину столбца в части данных записи. Резервирование фиксированного пространства для значений NULL позволяет выполнить обновление столбца с NULL до значения, отличного от NULL, без фрагментации страницы индекса.
Из структуры физических рядов Innodb, пункт № 2 под COMPACT ROW_FORMAT
Часть переменной длины заголовка записи содержит битовый вектор для указания столбцов NULL. Если число столбцов в индексе, которое может быть NULL, равно N, битовый вектор занимает байты CEILING (N / 8) . (Например, если есть где-то от 9 до 15 столбцов, которые могут быть NULL, битовый вектор использует два байта.) Столбцы с NULL не занимают пространство, отличное от бита в этом векторе . Часть заголовка переменной длины также содержит длины столбцов переменной длины. Каждая длина занимает один или два байта, в зависимости от максимальной длины столбца. Если все столбцы в индексе NOT NULL и имеют фиксированную длину, заголовок записи не имеет части переменной длины.
Основываясь на этих пунктах, вот что NULL
принимает значение для хранения столбца
- переменная длина: значение NULL не занимает места в самой строке
- фиксированная длина: занимает зарезервированное пространство
Теперь вы должны решить, использовать ли CHAR и VARCHAR из-за того, что выявил первый пункт
Резервирование фиксированного пространства для значений NULL позволяет выполнять обновление столбца с NULL до значения, отличного от NULL, без фрагментации страницы индекса.
Это предотвратит любую фрагментацию строки, идущей в будущем, после сохранения данных, отличных от NULL. Это то, что я обсуждал ранее в отношении MyISAM: см. Мой старый пост. Какое влияние на производительность оказывает использование CHAR против VARCHAR в поле фиксированного размера? ,
SELECT
который должен создать временную таблицу. Если это возможно, он будет использоватьMEMORY
, и конвертироватьVARCHAR
вCHAR
для таблицы TMP. ТеперьVARCHAR(100)
занимает фиксированные 100 (или 300) байтов, что может замедлить запрос.Независимо от длины, определенной вами для столбца varchar, объем памяти, используемый пустым столбцом, будет одинаковым.
Типы CHAR и VARCHAR
Это касается только пространства, используемого столбцом varchar, и не учитывает общее пространство хранения, используемое строкой, ее индексами, первичными ключами и другими столбцами.
Как упоминает ypercube в своем комментарии, существуют дополнительные соображения относительно хранения строк в целом, когда присутствует хотя бы один обнуляемый столбец.
Innodb Физическая Структура Рядов
И да, объем используемого хранилища изменяется в зависимости от выбранного вами типа, фиксированного или переменного, параметров сортировки и других факторов, таких как механизм.
MySQL дает рекомендации по оптимизации хранения данных здесь: Оптимизация размера данных
Обновить
Еще одно соображение с varchar и это память. В MySQL важно максимально ограничить размер столбца переменной длины. Несмотря на то, что столбец является переменным, а используемое пространство хранения является переменным, MySQL выделит память в фиксированных чанках для хранения значений. Например, varchar (200) будет использовать больше памяти, чем varchar (5). Это не проблема с объемом памяти, но все же нужно учитывать при определении столбцов.
источник
CHARACTER SET
latin1 или ascii. Для utf8, Требуемый для хранения :CHAR(4)
12.