Статьи

Задумывались ли вы когда-нибудь о разнице между NOT NULL и DEFAULT?

При написании DDL на SQL вы можете указать пару ограничений для столбцов, например, ограничения NOT NULL или DEFAULT . Некоторые люди могут задаться вопросом, являются ли эти два ограничения на самом деле избыточными , то есть все еще необходимо указывать ограничение NOT NULL , если уже есть предложение DEFAULT ?

Ответ: да!

Да, вы все равно должны указать, что ограничение NOT NULL . И нет, эти два ограничения не являются избыточными. Ответ, который я дал здесь о переполнении стека, завершает его примером, который я собираюсь повторить здесь, в нашем блоге:

DEFAULT — это значение, которое будет вставлено при отсутствии явного значения в операторе вставки / обновления. Предположим, у вашего DDL не было ограничения NOT NULL :

1
2
3
ALTER TABLE tbl
  ADD COLUMN col VARCHAR(20)
    DEFAULT "MyDefault"

Тогда вы могли бы выдать эти заявления

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
-- 1. This will insert "MyDefault"
--    into tbl.col
INSERT INTO tbl (A, B)
  VALUES (NULL, NULL);
 
-- 2. This will insert "MyDefault"
--    into tbl.col
INSERT INTO tbl (A, B, col)
  VALUES (NULL, NULL, DEFAULT);
 
-- 3. This will insert "MyDefault"
--    into tbl.col
INSERT INTO tbl (A, B, col)
  DEFAULT VALUES;
 
-- 4. This will insert NULL
--    into tbl.col
INSERT INTO tbl (A, B, col)
  VALUES (NULL, NULL, NULL);

Кроме того, вы также можете использовать DEFAULT в инструкциях UPDATE в соответствии со стандартом SQL-1992:

1
2
3
4
5
6
7
-- 5. This will update "MyDefault"
--    into tbl.col
UPDATE tbl SET col = DEFAULT;
 
-- 6. This will update NULL
--    into tbl.col
UPDATE tbl SET col = NULL;

Обратите внимание, что не все базы данных поддерживают все эти стандартные синтаксисы SQL. Добавление ограничения NOT NULL приведет к ошибке с операторами 4, 6, в то время как 1-3, 5 по-прежнему являются действительными операторами. Итак, чтобы ответить на ваш вопрос:

Нет, NOT NULL и DEFAULT не являются избыточными

Это уже довольно интересно, поэтому ограничение DEFAULT действительно взаимодействует только с операторами DML и тем, как они определяют различные обновляемые столбцы. Ограничение NOT NULL является гораздо более универсальной гарантией, которая ограничивает содержимое столбца также «вне» манипулирующих операторов DML.

Например, если у вас есть набор данных, а затем вы добавляете ограничение DEFAULT , это не повлияет на ваши существующие данные, будут вставлены только новые данные.

Однако, если у вас есть набор данных, а затем вы добавляете ограничение NOT NULL , вы можете сделать это только в том случае, если ограничение действительно — т.е. когда в вашем столбце нет значений NULL . В противном случае возникнет ошибка.

Запрос производительности

Еще один очень интересный вариант использования, который применяется только к ограничениям NOT NULL — это их полезность для оптимизаторов запросов и планов выполнения запросов. Предположим, что у вас есть такое ограничение на ваш столбец, а затем вы используете предикат NOT IN :

1
2
3
4
5
6
SELECT *
FROM table
WHERE value NOT IN (
  SELECT not_nullable
  FROM other_table
)

В частности, когда вы используете Oracle, вышеуказанный запрос будет выполняться намного быстрее, если столбец not_nullable имеет индекс И это конкретное ограничение, потому что, к сожалению, значения NULL не включены в индексы Oracle .

Узнайте больше о предикатах NULL и NOT IN здесь .