NULL-значение
NULL-значение (от лат. nullus — никакой, ничтожный) — в информатике и системах управления базами данных (СУБД) специальное значение (маркер), указывающее на отсутствие данных, неприменимость атрибута или неизвестное значение. NULL не является числом, строкой или каким-либо другим типом данных; это состояние, которое означает, что значение ячейки не определено или не существует. Концепция NULL была введена Эдгаром Коддом, автором реляционной модели данных, в 1970 году как средство представления «неизвестных» или «отсутствующих» данных.
История и происхождение
Понятие NULL возникло в контексте реляционной теории баз данных. В 1970 году Эдгар Кодд в своей работе «A Relational Model of Data for Large Shared Data Banks» предложил использовать NULL для обозначения отсутствующих данных, чтобы отличать их от нуля или пустой строки. В 1979 году Кодд уточнил концепцию, выделив два типа NULL: «отсутствующее значение, которое не применимо» (например, рост человека, не имеющего ног) и «отсутствующее значение, которое неизвестно» (например, рост человека, который не был измерен). Однако на практике большинство СУБД реализуют только один тип NULL, не различая эти случаи.
В 1980-х годах NULL был включён в стандарт SQL (Structured Query Language), что сделало его обязательным элементом реляционных баз данных. Несмотря на критику со стороны некоторых математиков и программистов (в частности, из-за трёхзначной логики, которую он вводит), NULL остаётся фундаментальной частью современных СУБД, таких как MySQL, PostgreSQL, Oracle Database, Microsoft SQL Server и других.
Логика и трёхзначная логика
NULL вводит в SQL так называемую трёхзначную логику (three-valued logic, 3VL), где истинность логического выражения может принимать три значения: TRUE (истина), FALSE (ложь) и UNKNOWN (неизвестно). Это связано с тем, что сравнение с NULL (например, x = NULL) не даёт ни TRUE, ни FALSE, а возвращает UNKNOWN, поскольку NULL не является конкретным значением.
Правила трёхзначной логики:
NULL = NULL→ UNKNOWN (даже два NULL не равны друг другу, так как оба неизвестны).NULL <> NULL→ UNKNOWN.NULL > 5→ UNKNOWN.NULL + 5→ NULL.NULL AND TRUE→ UNKNOWN.NULL OR TRUE→ TRUE (так как TRUE достаточно для истинности).NULL AND FALSE→ FALSE (так как FALSE достаточно для ложности).NOT NULL→ UNKNOWN.
Для проверки на NULL в SQL используются специальные операторы IS NULL и IS NOT NULL, а не обычное сравнение. Например, SELECT * FROM users WHERE name IS NULL вернёт строки, где поле name не заполнено.
Использование в базах данных
В реляционных базах данных NULL используется для обозначения отсутствия данных в ячейке таблицы. Это может быть связано с несколькими причинами:
- Неизвестное значение: например, дата рождения сотрудника, которая не была записана.
- Неприменимое значение: например, поле «отчество» для человека, у которого его нет.
- Отсутствие данных: например, поле «зарплата» для временного работника, который ещё не получил расчёт.
Ограничения и поведение:
- NULL не может быть использован в первичных ключах (PRIMARY KEY) — столбец, объявленный первичным ключом, должен содержать только уникальные и не-NULL значения.
- В индексах NULL обычно игнорируется (в зависимости от СУБД), но может быть включён в составной индекс.
- При агрегатных функциях (SUM, AVG, COUNT, MAX, MIN) NULL-значения игнорируются, за исключением
COUNT(*), который считает все строки, включая те, где есть NULL. - При объединении таблиц (JOIN) NULL-значения не участвуют в равенстве, если не используются специальные операторы.
Проблемы и критика
Концепция NULL подвергается критике по нескольким причинам:
1. Трёхзначная логика
Трёхзначная логика усложняет написание корректных запросов. Например, условие WHERE x = 1 OR x <> 1 не вернёт строки, где x равно NULL, так как оба сравнения дают UNKNOWN. Это может приводить к неожиданным результатам, особенно для новичков.
2. Неоднозначность
NULL не различает «неизвестное» и «неприменимое» значение, что может быть проблемой в семантическом моделировании данных. Например, поле «дата смерти» для живого человека и для человека, чья дата смерти неизвестна, будет одинаково NULL, хотя это разные ситуации.
3. Производительность
Использование NULL может снижать производительность запросов, так как СУБД требует дополнительных проверок. Индексы на столбцах с NULL могут быть менее эффективными.
4. Альтернативные подходы
Некоторые системы (например, NoSQL-базы данных, такие как MongoDB) не используют NULL, а вместо этого просто не включают поле в документ, если оно отсутствует. В реляционных базах данных альтернативой является использование значений-заглушек (например, 0, пустая строка, -1), но это может искажать данные.
Особенности в различных СУБД
Разные СУБД по-разному обрабатывают NULL:
- MySQL: NULL в индексах может быть включён, но не участвует в уникальных ограничениях (несколько NULL допускаются в уникальном индексе).
- PostgreSQL: NULL обрабатывается строго по стандарту SQL, но есть расширения, такие как
NULLS FIRSTиNULLS LASTв сортировке. - Oracle Database: NULL в сортировке по умолчанию считается больше любого другого значения (при сортировке по возрастанию NULL идут последними).
- Microsoft SQL Server: NULL в сортировке по умолчанию считается меньше любого другого значения (при сортировке по возрастанию NULL идут первыми).
- SQLite: NULL обрабатывается как значение, которое меньше любого другого (при сортировке по возрастанию NULL идут первыми).
Использование в языках программирования
Понятие NULL также широко используется в языках программирования, хотя его реализация отличается от SQL:
- C/C++:
NULL— макрос, обычно определяемый как(void*)0или0, используется для указателей, не указывающих на объект. - Java:
null— литерал, обозначающий отсутствие ссылки на объект. Попытка вызова метода уnullприводит к исключениюNullPointerException. - Python:
None— объект-синглтон, обозначающий отсутствие значения. Используется в функциях, возвращающих ничего, или как значение по умолчанию. - JavaScript:
null— примитивное значение, обозначающее отсутствие объекта. Также естьundefined, которое обозначает неопределённое значение. - C#:
null— ссылка, не указывающая на объект. В последних версиях языка введены nullable-типы (например,int?), которые могут приниматьnull. - Rust:
Option<T>— перечисление, которое может бытьSome(T)илиNone, что позволяет избежать null-указателей.
Интересные факты
- В 1965 году Тони Хоар, создатель языка ALGOL W, назвал введение NULL в языках программирования своей «миллиардной ошибкой», имея в виду ущерб от ошибок, связанных с null-указателями.
- В SQL есть функция
COALESCE, которая возвращает первое не-NULL значение из списка аргументов. Например,COALESCE(NULL, NULL, 5, NULL)вернёт 5. - В некоторых СУБД (например, Oracle) пустая строка (
'') считается NULL, что может вызывать путаницу. - NULL не участвует в арифметических операциях: любое выражение, содержащее NULL, возвращает NULL (например,
5 + NULL= NULL).
Источники
- Эдгар Кодд, «A Relational Model of Data for Large Shared Data Banks», 1970.
- Стандарт SQL:2016 (ISO/IEC 9075:2016).
- Тони Хоар, «Null References: The Billion Dollar Mistake», 2009.
- Документация MySQL, PostgreSQL, Oracle Database, Microsoft SQL Server.
- Книга «SQL for Dummies», 8-е издание, Аллен Тейлор.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →