Когда использовать NULL и когда использовать пустую строку?
Меня интересуют в основном MySQL и PostgreSQL, но вы могли бы ответить на следующее в целом:
- Есть ли логический сценарий, в котором было бы полезно различать пустую строку из NULL?
-
Каковы были бы физические помехи для хранения пустой строки как ...
- NULL?
- Пустая строка?
- Другое поле?
- Любой другой способ?
9 ответов
Предположим, что запись поступает из формы для сбора информации о имени и адресе. Строка 2 адреса обычно будет пустым, если пользователь не проживает в квартире. Пустая строка в этом случае вполне допустима. Я предпочитаю использовать NULL для обозначения того, что значение неизвестно или не указано.
Я не считаю, что физическая разница в памяти стоит беспокоиться на практике. В качестве администраторов баз данных у нас гораздо больше рыбы, чтобы жарить!
Я не знаю о MySQL и PostgreSQL, но позвольте мне рассмотреть это в целом.
Существует одна СУБД, а именно Oracle, которая не позволяет выбирать ее пользователей между NULL и '. Это наглядно демонстрирует, что нет необходимости проводить различие между ними. Есть некоторые досадные последствия:
Вы устанавливаете varchar2 в пустую строку следующим образом:
Обновить набор mytable varchar_col = '';
следующее приводит к тому же результату
Обновить набор mytable varchar_col = NULL;
Но для выбора столбцов, где значение пусто или NULL, вы должны использовать
выберите * из mytable, где varchar_col - NULL;
Используя
выберите * из mytable, где varchar_col = '';
является синтаксически правильным, но никогда не возвращает строку.
С другой стороны, при конкатенации строк в Oracle. NULL varchars рассматриваются как пустые строки.
выберите NULL || 'abc' из DUAL;
дает abc . Другая СУБД в этих случаях возвращает NULL.
Если вы хотите явно выразить, что назначено значение, вы должны использовать что-то вроде '..
И вам нужно беспокоиться, что обрезка не пустая приводит к NULL
выберите случай, когда ltrim ('') имеет значение null, тогда 'null' else 'not null' end from dual
Он делает.
Теперь посмотрим на СУБД, где '' не совпадает с NULL (например, SQL-Server)
Работа с '' обычно проще, и в большинстве случаев нет практической необходимости различать их. Одно из исключений, которые я знаю, - это когда ваша колонка представляет некоторую настройку, и у вас нет пустых значений по умолчанию для них. Когда вы можете различать '' и NULL, вы можете выразить, что ваш параметр пуст, и избегайте использования по умолчанию.
Это зависит от домена, над которым вы работаете. NULL
означает отсутствие значения (т. е. есть no value ), а пустая строка означает, что существует строковое значение нулевой длины.
Например, скажем, что у вас есть таблица для хранения данных пользователя, и она содержит столбец Gender
. Вы можете сохранить значения как «Мужской» или «Женский». Если пользователь может выбрать не предоставлять гендерные данные, вы должны сохранить это как NULL
(т.е. пользователь не предоставил значение) и не пустую строку (так как там не имеет пола со значением '').
Следует иметь в виду, что когда у вас есть поле, которое не требуется, но любые значения, которые присутствуют, должны быть уникальными, вам нужно будет хранить пустые значения как NULL. В противном случае вы сможете иметь только один кортеж с пустым значением в этом поле.
Существуют также некоторые различия с реляционной алгеброй и значениями NULL: NULL! = NULL, например.
Вы также можете учитывать критику Даты NULL и проблемы 3VL в SQL и реляционной теории (и критика Рубинсона критики Дати, Nulls, трехзначная логика и неоднозначность в SQL: критический анализ даты ).
Оба ссылаются и подробно обсуждаются в связанной потоке SO, Опции для исключения столбцов NULLable из модели DB .
Новая мысль, большое влияние на ваш выбор NULL
/NOT NULL
- это если вы используете фреймворк. Я использую symfony alot и используя разрешенные поля NULL
, упрощает некоторые проверки кода и данных при манипулировании данными.
Если вы не используете фреймворк или используете простые операторы sql и обработку, я бы пошел с выбором, который вам кажется проще проследить. Обычно я предпочитаю NULL, поэтому выполнение инструкций INSERT
не утомительно с забыванием установить пустые поля в NULL
.
Придется работать с Oracle (, который не позволяет вам различать ). Я пришел к следующему выводу:
-
Из логического POV это не имеет значения. Я действительно не могу придумать убедительный пример, в котором дифференцирование между NULL и строкой нулевой длины добавляет любое значение в СУБД.
-
Из этого следует: у вас есть столбец
NULL
, который не разрешает нуль-len''
(решение Oracle-ish) или < code> NOT NULL, который допускает нулевое значение. -
И по моему опыту
''
делает больше много при обработке данных, так как обычно вы хотите обработать отсутствие строки как пустая строка: Конкатенация, Сравнение и т. д.
Примечание. Чтобы вернуться к моему опыту Oracle: скажите, что хотите
сгенерировать запрос для запроса поиска. Если вы используете ''
, вы можете просто сгенерировать WHERE columnX = <searchvalue>
, и он будет работать для поиска равенства. Если вы используете NULL
, вам нужно сделать WHERE columnX = <searchvalue> или (columnX равно NULL, а значение равно NULL)
. Ба! : -)
Они также отличаются от проектной точки зрения:
например.
CREATE TABLE t (
id INTEGER NOT NULL,
имя ХАРАКТЕР (40),
CONSTRAINT t_PK ПЕРВИЧНЫЙ КЛЮЧ (id)
);
СОЗДАТЬ УНИКАЛЬНЫЙ ИНДЕКС t_AK1 ON t (имя);
Похож:
\ d t
Таблица "public.t"
Колонка | Тип | Модификаторы
-------- + --------------- + -----------
id | целое число | не ноль
имя | персонаж (40) |
Индексы:
"t_pk" ПЕРВИЧНЫЙ КЛЮЧ, btree (id)
"t_ak1" UNIQUE, btree (имя)
Позволяет вставить некоторые данные:
op = # insert в значения t (id, name) (1, 'Hello');
INSERT 0 1
op = # insert в значения t (id, name) (2, '');
INSERT 0 1
op = # insert в значения t (id, name) (3, '');
ОШИБКА: дублирующее значение ключа нарушает уникальное ограничение «t_ak1»
Теперь попробуем с помощью null:
op = # insert в значения t (id, name) (4, null);
INSERT 0 1
op = # insert в значения t (id, name) (5, null);
INSERT 0 1
Это разрешено.
Soooooo: nulls - это не тривиальные строки, а наоборот.
Приветствия
Если мы говорим о теории, то правила Codd говорят, что RDBMS должен обрабатывать значения NULL
особым образом.
Как именно это используется для архитекторов баз данных, в зависимости от области domain - task - project - application - area.