Статьи

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

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

Ответ: да!

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

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

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

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

-- 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:

-- 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предикат:

SELECT *
FROM table
WHERE value NOT IN (
SELECT not_nullable
FROM other_table
)

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

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

{Примечание редактора: поскольку кодовые блоки DZone в настоящее время не монопространственные, ознакомьтесь с кодом в оригинальной статье здесь .}