Введение
Маркер, используемый в базах данных SQL для указания на то, что значение отсутствует.
В SQL, null или NULL – это специальный маркер, используемый для обозначения отсутствия значения данных в базе данных. Введенный создателем модели реляционных баз данных, Э. Ф. Коддом, SQL null служит для выполнения требования, чтобы все настоящие системы управления реляционными базами данных (RDBMS) поддерживали представление «отсутствующей и неприменимой информации». Кодд также ввел использование символа греческой строчной омеги (ω) для обозначения null в теории баз данных. В SQL, NULL является зарезервированным словом, используемым для идентификации этого маркера. Null не следует путать со значением 0. Null указывает на отсутствие значения, что не является тем же самым, что нулевое значение. Например, рассмотрим вопрос: «Сколько книг у Адама?». Ответ может быть «ноль» (мы знаем, что у него нет ни одной книги) или «null» (мы не знаем, сколько у него книг). В таблице базы данных столбец, содержащий ответ на этот вопрос, изначально не будет иметь значения (обозначенного как null), и он не будет обновлен значением ноль, пока не будет установлено, что у Адама нет книг. В SQL, null – это маркер, а не значение. Это использование существенно отличается от большинства языков программирования, где нулевое значение ссылки означает, что она не указывает ни на какой объект.
История
Э. Ф. Кодд упомянул значения NULL как способ представления отсутствующих данных в реляционной модели в статье 1975 года, опубликованной в FDT Bulletin журнала ACM SIGMOD. Статья Кодда, наиболее часто цитируемая в контексте семантики NULL (в том виде, в котором она принята в SQL), — это его статья 1979 года в ACM Transactions on Database Systems, в которой он также представил свою Реляционную модель/Тасмания, хотя многие другие предложения из этой статьи остались малоизвестными. В разделе 2.3 его статьи 1979 года подробно описана семантика распространения NULL в арифметических операциях, а также сравнения, использующие троичную (трехзначную) логику при сравнении со значениями NULL; в ней также подробно рассматривается обработка NULL в других операциях над множествами (последний вопрос до сих пор вызывает споры). В сообществе теоретиков баз данных первоначальное предложение Кодда (1975, 1979) теперь называют "таблицами Кодда". Стандарт SQL 1986 года в значительной степени принял предложение Кодда после создания прототипа реализации в IBM System R. Хотя Дон Чемберлин признал значения NULL (наряду с дублирующимися строками) одной из самых спорных особенностей SQL, он защищал их реализацию в SQL, приводя прагматические аргументы о том, что это наименее затратный способ системной поддержки отсутствующей информации, избавляя программиста от множества избыточных проверок на уровне приложения (см. проблему полупредикатов), и в то же время предоставляя разработчику базы данных возможность не использовать NULL, если он того пожелает; например, чтобы избежать известных аномалий (обсуждаемых в разделе "Семантика" этой статьи). Чемберлин также утверждал, что помимо обеспечения функциональности для представления отсутствующих значений, практический опыт работы с NULL привел к появлению других языковых конструкций, основанных на NULL, таких как определенные конструкции группировки и внешние соединения. Наконец, он утверждал, что на практике NULL также часто используются как быстрый способ изменения существующей схемы, когда возникает необходимость расширить ее за пределы первоначального замысла, кодируя не отсутствие данных, а их неприменимость; например, для базы данных, которой быстро требуется поддержка электромобилей, при наличии столбца "миль на галлон". Кодд указал в своей книге 1990 года "Реляционная модель управления базами данных, версия 2", что единственного значения NULL, определенного стандартом SQL, недостаточно, и его следует заменить двумя отдельными маркерами типа NULL, чтобы указать причину отсутствия данных. В книге Кодда эти два маркера типа NULL называются "A-значениями" и "I-значениями", представляющими "Отсутствует, но применимо" и "Отсутствует, но неприменимо" соответственно. Хотя было предложено несколько способов решения этих проблем, сложность альтернативных решений помешала их широкому распространению.
Функции нулевой обработки
SQL определяет две функции для явной обработки значений NULL: NULLIF и COALESCE. Обе функции являются сокращенной формой конструкций CASE с поиском.
Тип данных булевой
Стандарт ISO SQL:1999 ввел тип данных BOOLEAN в SQL, однако это до сих пор лишь необязательная, не являющаяся основной функцией, обозначенная кодом T031. При наличии ограничения NOT NULL, SQL BOOLEAN функционирует как булев тип из других языков программирования. Однако, несмотря на название, тип данных BOOLEAN, без ограничений, может хранить значения истинности TRUE, FALSE и UNKNOWN, все из которых определены стандартом как булевы литералы. Стандарт также утверждает, что NULL и UNKNOWN "могут использоваться взаимозаменяемо для обозначения одного и того же значения". Булев тип подвергался критике, в частности из-за предписанного поведения литерала UNKNOWN, который из-за отождествления с NULL никогда не равен самому себе. Как было описано выше, в реализации SQL в PostgreSQL, NULL используется для представления всех неопределенных результатов, включая UNKNOWN BOOLEAN. PostgreSQL не реализует литерал UNKNOWN (хотя оператор IS UNKNOWN реализован, и является независимой функцией). Большинство других крупных поставщиков не поддерживали булев тип (в соответствии с определением T031) по состоянию на 2012 год. Процедурная часть Oracle PL/SQL, тем не менее, поддерживает BOOLEAN переменные; им также может быть присвоено значение NULL, которое считается эквивалентным UNKNOWN.
interchangeably to mean exactly the same thing". The Boolean type has been subject of criticism, particularly because of the mandated behavior of the UNKNOWN literal, which is never equal to itself because of the identification with NULL. As discussed above, in the PostgreSQL implementation of SQL, Null is used to represent all UNKNOWN results, including the UNKNOWN BOOLEAN. PostgreSQL does not implement the UNKNOWN literal (although it does implement the IS UNKNOWN operator, which is an orthogonal feature.) Most other major vendors do not support the Boolean type (as defined in T031) as of 2012. The procedural part of Oracle's PL/SQL however supports BOOLEAN variables; these can also be assigned NULL and the value is considered the same as UNKNOWN.
Критика
Реализация Null в ISO SQL является предметом критики, дискуссий и призывов к изменениям. В книге «Реляционная модель управления базами данных: Версия 2» Кодд предположил, что реализация Null в SQL является ошибочной и должна быть заменена двумя различными маркерами типа Null. Предложенные им маркеры должны были обозначать «Отсутствует, но применимо» и «Отсутствует, но неприменимо», известные как A-значения и I-значения соответственно. Принятие рекомендации Кодда потребовало бы внедрения четырехзначной логики в SQL. Другие предлагали добавить к рекомендации Кодда дополнительные маркеры типа Null, чтобы указать еще больше причин, по которым значение данных может быть «отсутствующим», что увеличило бы сложность логической системы SQL. В разное время также выдвигались предложения по реализации нескольких пользовательских маркеров Null в SQL. Из-за сложности обработки Null и логических систем, необходимых для поддержки нескольких маркеров Null, ни одно из этих предложений не получило широкого распространения. Крис Дэйт и Хью Дарвен, авторы «Третьего манифеста», предположили, что реализация Null в SQL принципиально ошибочна и должна быть полностью устранена, указывая на несоответствия и недостатки в реализации обработки Null в SQL (особенно в агрегатных функциях) как доказательство того, что вся концепция Null ошибочна и должна быть исключена из реляционной модели. Другие, такие как автор Фабиан Паскаль, выразили мнение, что «то, как вычисление функции должно обрабатывать отсутствующие значения, не регулируется реляционной моделью».
Предположение о закрытом мире
Еще один конфликт, связанный с использованием значений NULL, заключается в том, что они нарушают принцип замкнутого мира, лежащий в основе реляционных баз данных, внедряя принцип открытого мира. Принцип замкнутого мира в контексте баз данных утверждает: "Всё, что явно или неявно отражено в базе данных, истинно; всё остальное – ложно". Этот подход исходит из предположения, что знания о мире, хранящиеся в базе данных, являются исчерпывающими. Однако значения NULL оперируют в рамках принципа открытого мира, при котором некоторые данные, хранящиеся в базе данных, считаются неизвестными, что делает знания базы данных о мире неполными.