MySQL: NULL против "" - PullRequest
       37

MySQL: NULL против ""

43 голосов
/ 10 июля 2009

Лучше ли использовать default null или default "" для текстовых полей в MySQL?

Почему?

Обновление: я знаю, что означает каждый из них. Мне интересно, что лучше использовать, учитывая дисковое пространство и производительность.

Обновление 2: Эй, чел! Вопрос был «что лучше использовать», а не «что каждый из них значит» или «как их проверить» ...

Ответы [ 12 ]

53 голосов
/ 10 июля 2009

Для таблиц MyISAM NULL создает дополнительный бит для каждого столбца NULLABLE (нулевой бит) для каждой строки. Если столбец не NULLABLE, дополнительный бит информации никогда не требуется. Однако это дополняется до 8 битных байтов, поэтому вы всегда получаете 1 + мод 8 байтов для количества столбцов NULLABLE. 1

Текстовые столбцы немного отличаются от других типов данных. Во-первых, для "" запись таблицы содержит двухбайтовую длину строки, за которой следуют байты строки, и представляет собой структуру длины варианта. В случае NULL информация о длине не требуется, но она в любом случае включена как часть структуры столбца.

В InnoDB NULLS не занимают места: они просто не существуют в наборе данных. То же самое верно для пустой строки, поскольку смещения данных также не существуют. Единственное отличие состоит в том, что для значений NULL будет установлен бит NULL, а для пустых строк - нет. 2

Когда данные на самом деле располагаются на диске, NULL и '' занимают ровно то же самое пространство в обоих типах данных. Однако при поиске значения проверка NULL выполняется немного быстрее, чем проверка '', поскольку вам не нужно учитывать длину данных в своих вычислениях: вы проверяете только нулевой бит.

В результате различий между NULL и '', NULL и '' НЕ ВЛИЯЮТ НА РАЗМЕР, если в столбце не указано NULLable или нет. Если столбец НЕ ПУСТО (NULL), то только в таблицах MyISAM вы увидите разницу в производительности (и тогда, очевидно, значение по умолчанию NULL не может быть использовано, поэтому это спорный вопрос).

Реальный вопрос сводится к интерпретации приложением столбцов «здесь не задано значение». Если "" является допустимым значением, означающим "пользователь здесь ничего не ввел" или что-то подобное, то предпочтительным является значение по умолчанию NULL, поскольку вы хотите различать NULL и "" при вводе записи, в которой нет данных.

Обычно, по умолчанию, действительно полезно только для рефакторинга базы данных, когда новые значения должны вступать в силу для старых данных. В этом случае, опять же, выбор зависит от того, как интерпретируются данные приложения. Для некоторых старых данных NULL идеально подходит и лучше всего подходит (столбец ранее не существовал, поэтому теперь он имеет значение NULL!). Для других «» более подходит (часто, когда запросы используют SELECT *, а NULL вызывает проблемы сбоев).

В ULTRA-GENERAL TERMS (и с философской точки зрения) значение NULL по умолчанию для столбцов NULLABLE является предпочтительным, поскольку оно дает наилучшую семантическую интерпретацию «Не указано значение».

1 [http://forge.mysql.com/wiki/MySQL_Internals_MyISAM]

2 [http://forge.mysql.com/wiki/MySQL_Internals_InnoDB]

41 голосов
/ 10 июля 2009

Использовать по умолчанию null.В SQL null сильно отличается от пустой строки ("").Пустая строка конкретно означает, что значение было установлено как пустое;null означает, что значение не было установлено или было установлено в ноль.Видите ли, разные значения.

Разные значения и их разное использование - вот почему важно использовать каждое из них по мере необходимости;объем пространства, который потенциально может быть сэкономлен при использовании default null, а не default "", настолько мал, что приближается к незначительности;однако потенциальная ценность использования надлежащих значений по умолчанию, как того требует соглашение, довольно высока.

21 голосов
/ 03 октября 2012

С Высокопроизводительный MySQL, 3-е издание

Избегайте NULL, если это возможно. Многие таблицы содержат пустые столбцы, даже когда приложение не нужно хранить NULL (отсутствие значения) просто потому, что это значение по умолчанию. Обычно лучше всего указывать столбцы как NOT NULL, если вы не собираетесь хранить в них NULL. MySQL сложнее оптимизировать запросы, которые ссылаются на обнуляемые столбцы, потому что они усложняют индексы, статистику индексов и сравнения значений. Обнуляемый столбец занимает больше места для хранения и требует специальной обработки внутри MySQL. Когда индексируемый столбец обнуляется, для каждой записи требуется дополнительный байт и даже может вызвать индекс фиксированного размера (например, индекс для одного целочисленного столбца) быть преобразованным в переменный размер в MyISAM. Улучшение производительности от замены столбцов NULL на NOT NULL обычно маленький, поэтому не делайте приоритетным поиск и изменение их в существующей схеме если вы не знаете, что они вызывают проблемы. Однако, если вы планируете индексировать столбцы, по возможности избегайте обнулять их. Конечно, есть исключения. Например, стоит упомянуть, что InnoDB хранит NULL с одним битом, поэтому он может быть довольно компактным для малонаселенных данные. Однако это не относится к MyISAM.

10 голосов
/ 16 ноября 2010

Я обнаружил, что значение NULL против "" незначительно с точки зрения дискового пространства и производительности.

Единственная истинная причина, по которой я лично вижу использование NULL над '', - это когда у вас есть поле, помеченное как UNIQUE , но вам нужна возможность разрешить несколько «пустых» столбцов.

Например, столбец email в моей пользовательской таблице заполняется только в том случае, если кто-то действительно имеет адрес электронной почты. Любой, у кого нет адреса электронной почты, получает NULL. Я все еще могу сделать это поле уникальным, поскольку NULL не считается значением, тогда как пустая строка '' имеет значение.

7 голосов
/ 10 июля 2009

Многие люди отвечают на вопрос, в чем разница между null и '', но ОП запросил, что занимает меньше места / быстрее, поэтому вот мое замечание:

Ответ в том, что это зависит. Если ваше поле имеет значение char(10), оно всегда будет занимать 10 байт, если не установлено значение null, и, следовательно, null будет занимать меньше места. Минуты построчно, но для миллионов и миллионов строк это может сложиться. Я полагаю, что даже varchar(10) будет хранить один байт (\0) как пустую строку, так что, опять же, это может привести к огромным таблицам.

С точки зрения производительности в запросах, null теоретически быстрее тестировать, но я не видел возможности заметить существенную разницу в хорошо проиндексированной таблице. Имейте в виду, однако, что вам может потребоваться преобразовать null в '' на стороне приложения, если это желаемый возврат. Опять же, строка за строкой, разница в минутах, но она может сложиться.

В целом, это микрооптимизация, поэтому все сводится к предпочтениям. Я предпочитаю использовать null, потому что мне нравится знать, что там нет значения, и не гадать, пустая ли это строка ('') или группа пробелов (' '). null явно по своей природе. '' нет. Поэтому, я иду с null, потому что я типичный парень.

3 голосов
/ 10 июля 2009

Используйте все, что имеет смысл. NULL означает «значение не доступно / не указано», "" означает «пустая строка».

Если вы не разрешаете пустые строки, но пользователю не нужно вводить значение, тогда NULL имеет смысл. Если вам требуется значение, но оно может быть пустым, NOT NULL и значение "" имеют смысл.

И, конечно, если вам не нужно значение, но можно указать пустое значение, тогда NULL имеет смысл.

С точки зрения эффективности, дополнительный бит используется, чтобы определить, является ли поле NULL или нет, но не беспокойтесь о такой микрооптимизации, пока не получите миллионы строк.

1 голос
/ 10 июля 2009

Я предпочитаю нуль, когда это семантически правильно. Если доступно поле адреса, а пользователь не заполнил, я ставлю его "". Тем не менее, если в атрибуте address в таблице users я еще не предложил пользователю заполнить его, я даю ему NULL.

Я сомневаюсь (но я не могу проверить), что NULL и "" имеют большое значение.

0 голосов
/ 10 июля 2009

Используйте "". Это требует меньше усилий для программирования, если вы можете утверждать, что столбцы не равны NULL. Разница в пространстве между ними тривиальна.

0 голосов
/ 10 июля 2009

'' = '' дает TRUE, что удовлетворяет условию WHERE

NULL = NULL дает NULL, что не удовлетворяет WHERE условию

Что лучше использовать, зависит от того, какой результат вы хотите получить.

Если ваши значения по умолчанию равны NULL, запрос не будет таким:

SELECT  *
FROM    mytable
WHERE   col1 = ?

будет всегда возвращать эти значения, даже если вы передадите NULL для связанного параметра, в то время как этот запрос:

SELECT  *
FROM    mytable
WHERE   col1 = ''

вернет вам строки, которые вы установили для пустой строки.

Это верно для MySQL, но не для Oracle, который не различает пустую строку и NULL.

В Oracle последний запрос никогда ничего не даст.

0 голосов
/ 10 июля 2009

NULL означает «нет значения» и рассматривается СУБД, особенно в отношении положений и объединений.

"" означает "пустая строка" и не рассматривается особо.

Это зависит от того, что представляет текст и как он будет фактически использоваться в запросах.

Например, у вас может быть анкета с некоторыми обязательными вопросами и некоторыми дополнительными вопросами.

  • Отклоненные необязательные вопросы должны иметь значение NULL в соответствующем столбце.
  • Обязательные вопросы должны иметь пустую строку по умолчанию, потому что на них ДОЛЖЕН быть ответ. (Конечно, в реальном приложении вы бы сказали пользователю ввести что-то, но я надеюсь, что вы поняли)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...