Классика баз данных - статьи

NULL - проблема


Одной из наиболее серьезных теоретических проблем реляционной модели была проблема представления отсутствующей информации. Кодд предложил подход к ее решению, ныне широко известный практикам баз данных. Для представления отсутствующей информации используются специальные маркеры, называемые NULL - значениями. Идея заключается в следующем: если данный кортеж имеет NULL – маркер в данной позиции атрибута, то это означает, что в таком кортеже значение атрибута по некоторой причине отсутствует (причины этого могут быть различны, например, “отсутствует” или “не применимо”).

В свою очередь, Дейт и Дарвен подвергают критике такой подход, в частности, указывая, что “NULL – значения” вообще не являются реальными значениями в обычном смысле этого термина (это не то же самое, что, например, пробелы или числовые нули).

Попробуем кратко проследить логику рассуждений Дейт и Дарвена.

Рассмотрим подробнее семантику неопределенных значений. Результатом скалярных операций сравнения, в которых хотя бы один из операндов является величиной NULL, будет логическое значение unknown.

Приведем другой пример. В определение столбца может входить одно из ограничений: ограничение первичного ключа (PRIMARY KEY) или ограничение возможного ключа (UNIQUE). Включение в определение столбца любого из этих ограничений означает требование уникальности значений определяемого столбца, т. е. во все время существования определяемой таблицы во всех ее строках значения данного столбца должны быть различны. В этом случае SQL опирается на семантику неопределенных значений, отличную от используемой в большинстве других случаев. Считается, что (NULL = NULL) = true и что (a = NULL) = (NULL = a) = false для любого значения a, отличного от NULL.

Третий пример. Вычисление функции COUNT(*) производится путем подсчета числа строк в заданном мультимножестве. Все строки считаются различными, даже если они состоят из одного столбца со значением NULL во всех строках.
Это еще один вид различения строк в SQL и еще одна скрытая интерпретация неопределенного значения. COUNT(*) работает так, как если бы выполнялось соотношение (NULL=NULL) = false.

Тем самым, в SQL применяются все три возможных интерпретации NULL. При вычислении логических выражений полагается (NULL=NULL) = unknown; при определении строк-дубликатов неявно считается, что (NULL=NULL) = true; наконец, при вычислении агрегатной функции COUNT(*) неявно полагается, что (NULL=NULL) = false.

Критика Дейтом и Дарвеном подхода, основанного на использовании NULL – значений, основывается на следующей логике. Значение, по определению, является элементом некоторого домена. Пусть имеется домен, один из элементов которого мы решили представить символом NULL. Но тогда мы должны определить все операции, которые доступны в связи с этим доменом, включая, конечно, операцию сравнения. Но есть одна вещь, которую запрещено делать: это говорить, что NULL является чем-то отличным от этого символа. То есть говорить, что сравнение NULL = NULL когда-либо возвращает что-либо, кроме true. И “что-либо, кроме true” может быть “что-либо, кроме false” . И, как только мы понимаем, что NULL не являются значениями, считают Дейт и Дарвен, оказывается, что “отношения”, содержащие NULL, вовсе не являются отношениями, как они определены в реляционной модели, и, используя их, мы тем самым отказываемся от реляционной модели. Таким образом, NULL разрушают реляционную модель, и должны быть оттуда исключены.

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

Те, кто помнят институтский курс теории реляционных баз данных, скорее всего, согласится с обоснованностью такой критики, но вместе с тем, те, кто сталкивается с реляционными БД на практике, обязательно потребуют представить альтернативное применению NULL – значений решение.Дейт и Дарвен действительно предоставляют альтернативное решение, которое мы и попытаемся продемонстрировать.


Содержание раздела