Ноль (SQL)

В SQL — это специальный маркер , нуль или NULL используемый для обозначения того, что значение данных не существует в базе данных . Введенный создателем реляционной модели базы данных Э.Ф. Коддом , SQL null служит для выполнения требования, чтобы все настоящие системы управления реляционными базами данных ( СУБД ) поддерживали представление «недостающей информации и неприменимой информации». использование строчной греческой омеги (ω) для обозначения нуля Кодд также ввел в теорию баз данных . В SQL, NULL
— зарезервированное слово, используемое для идентификации этого маркера.
Не следует путать значение NULL со значением 0 . Нуль указывает на отсутствие значения, что не то же самое, что нулевое значение. Например, рассмотрим вопрос «Сколько книг у Адама?» Ответ может быть «ноль» (мы знаем , что у него нет ни одного ) или «ноль» (мы не знаем, сколько у него есть). В таблице базы данных столбец , сообщающий об этом ответе, будет начинаться со значения без значения (отмечен нулем) и не будет обновляться нулевым значением до тех пор, пока не будет установлено, что у Адама нет книг.
В SQL значение null является маркером, а не значением. Такое использование сильно отличается от большинства языков программирования, где нулевое значение ссылки означает, что она не указывает ни на какой объект .
История
[ редактировать ]Э. Ф. Кодд упомянул нули как метод представления недостающих данных в реляционной модели в статье 1975 года, опубликованной в бюллетене FDT ACM - SIGMOD . Статья Кодда, которая чаще всего цитируется в связи с семантикой Null (принятой в SQL), — это его статья 1979 года в журнале ACM Transactions on Database Systems , в которой он также представил свою реляционную модель/Tasmania , хотя многие другие предложения из последняя статья осталась неясной. В разделе 2.3 его статьи 1979 года подробно описана семантика распространения нулей в арифметических операциях, а также сравнения, использующие троичную (трехзначную) логику при сравнении с нулями; в нем также подробно описывается обработка нулей в других операциях над множествами (последний вопрос до сих пор остается спорным). В кругах теории баз данных первоначальное предложение Кодда (1975, 1979) теперь называется «таблицами Кодда». [ 1 ] Позже Кодд подтвердил свое требование о том, чтобы все СУБД поддерживали Null для указания недостающих данных, в статье, состоящей из двух частей, опубликованной в журнале Computerworld в 1985 году . [ 2 ] [ 3 ]
Стандарт SQL 1986 года в основном принял предложение Кодда после прототипа реализации в IBM System R. Хотя Дон Чемберлин признавал нули (наряду с повторяющимися строками) одной из наиболее спорных особенностей SQL, он защищал дизайн пустых значений в SQL, ссылаясь на прагматичные аргументы, что это наименее дорогая форма системной поддержки недостающей информации, избавляющая программиста от множество дублирующих проверок на уровне приложения (см. проблему полупредикатов ), в то же время предоставляя разработчику базы данных возможность не использовать значения Null, если они того пожелают; например, чтобы избежать хорошо известных аномалий (обсуждаемых в разделе семантики этой статьи). Чемберлин также утверждал, что, помимо обеспечения некоторой функциональности недостающих значений, практический опыт работы с нулями также привел к появлению других функций языка, основанных на нулях, таких как определенные конструкции группировки и внешние соединения. Наконец, он утверждал, что на практике нули также используются как быстрый способ исправить существующую систему. схему , когда ей необходимо выйти за пределы своего первоначального замысла, кодируя не недостающую, а скорее неприменимую информацию; например, база данных, которая должна быстро поддерживать электромобили, имея при этом столбец миль на галлон. [ 4 ]
1990 года Кодд указал, В своей книге «Реляционная модель управления базами данных, версия 2» что одиночный нуль, предусмотренный стандартом SQL, недостаточен и должен быть заменен двумя отдельными маркерами нулевого типа, чтобы указать причину отсутствия данных. В книге Кодда эти два маркера нулевого типа называются «A-значениями» и «I-значениями», что означает «Отсутствует, но применимо» и «Отсутствует, но неприменимо» соответственно. [ 5 ] Рекомендация Кодда требовала расширения логической системы SQL для включения четырехзначной логической системы. Из-за этой дополнительной сложности идея нескольких нулей с разными определениями не получила широкого признания в области практиков баз данных. Тем не менее, эта область исследований остается активной, и многочисленные статьи все еще публикуются.
Проблемы
[ редактировать ]Null был в центре споров и источником дебатов из-за связанной с ним трехзначной логики (3VL), особых требований к его использованию в соединениях SQL и специальной обработки, требуемой агрегатными функциями и операторами группировки SQL. Профессор информатики Рон ван дер Мейден резюмировал различные проблемы следующим образом: «Несоответствия в стандарте SQL означают, что невозможно приписать какую-либо интуитивную логическую семантику обработке нулевых значений в SQL». [ 1 ] Хотя для решения этих проблем были выдвинуты различные предложения, сложность альтернатив помешала их широкому внедрению.
Распространение нуля
[ редактировать ]Арифметические операции
[ редактировать ]Поскольку Null — это не значение данных, а маркер отсутствующего значения, использование математических операторов для Null дает неизвестный результат, который представлен Null. [ 6 ] В следующем примере умножение 10 на Null приводит к результату Null:
10 * NULL -- Result is NULL
Это может привести к неожиданным результатам. Например, когда предпринимается попытка разделить Null на ноль, платформы могут вернуть Null вместо ожидаемого «исключения данных – деление на ноль». [ 6 ] Хотя такое поведение не определено стандартом ISO SQL, многие поставщики СУБД рассматривают эту операцию аналогичным образом. Например, платформы Oracle, PostgreSQL, MySQL Server и Microsoft SQL Server возвращают нулевой результат для следующих значений:
NULL / 0
Конкатенация строк
[ редактировать ] строк Операции конкатенации , распространенные в SQL, также приводят к значению NULL, если один из операндов имеет значение NULL. [ 7 ] В следующем примере демонстрируется результат Null, возвращаемый при использовании Null с SQL. ||
оператор конкатенации строк.
'Fish ' || NULL || 'Chips' -- Result is NULL
Это справедливо не для всех реализаций баз данных. В СУБД Oracle, например, NULL и пустая строка считаются одним и тем же, и поэтому 'Fish' || НУЛЬ || «Чипсы» приводят к «рыбным чипсам». [ 8 ]
Сравнение с NULL и трехзначной логикой (3VL)
[ редактировать ]Поскольку Null не является членом какой-либо области данных , он не считается «значением», а скорее маркером (или заполнителем), указывающим неопределенное значение . По этой причине сравнение с Null никогда не может привести ни к True, ни к False, а всегда к третьему логическому результату — Unknown. [ 9 ] Логический результат приведенного ниже выражения, которое сравнивает значение 10 с нулевым значением, — «Неизвестно»:
SELECT 10 = NULL -- Results in Unknown
Однако некоторые операции с Null могут возвращать значения, если отсутствующее значение не имеет отношения к результату операции. Рассмотрим следующий пример:
SELECT NULL OR TRUE -- Results in True
В этом случае тот факт, что значение слева от ИЛИ неизвестно, не имеет значения, поскольку результат операции ИЛИ будет истинным независимо от значения слева.
SQL реализует три логических результата, поэтому реализации SQL должны обеспечивать специализированную трехзначную логику (3VL) . Правила, управляющие трехзначной логикой SQL, показаны в таблицах ниже ( p и q представляют логические состояния)». [ 10 ] Таблицы истинности, которые SQL использует для И, ИЛИ и НЕ, соответствуют общему фрагменту трехзначной логики Клини и Лукасевича (которые различаются определением импликации, однако SQL не определяет такую операцию). [ 11 ]
п | д | п ИЛИ q | р И q | р = q |
---|---|---|---|---|
Истинный | Истинный | Истинный | Истинный | Истинный |
Истинный | ЛОЖЬ | Истинный | ЛОЖЬ | ЛОЖЬ |
Истинный | Unknown | Истинный | Unknown | Unknown |
ЛОЖЬ | Истинный | Истинный | ЛОЖЬ | ЛОЖЬ |
ЛОЖЬ | ЛОЖЬ | ЛОЖЬ | ЛОЖЬ | Истинный |
ЛОЖЬ | Unknown | Unknown | ЛОЖЬ | Unknown |
Unknown | Истинный | Истинный | Unknown | Unknown |
Unknown | ЛОЖЬ | Unknown | ЛОЖЬ | Unknown |
Unknown | Unknown | Unknown | Unknown | Unknown |
п | НЕ п |
---|---|
Истинный | ЛОЖЬ |
ЛОЖЬ | Истинный |
Unknown | Unknown |
Эффект неизвестного в предложениях WHERE
[ редактировать ]Трехзначная логика SQL встречается в языке манипулирования данными (DML) в предикатах сравнения операторов и запросов DML. WHERE
Предикат приводит к тому, что оператор DML действует только на те строки, для которых предикат имеет значение True. Строки, для которых предикат имеет значение False или Unknown, не обрабатываются. INSERT
, UPDATE
, или DELETE
операторы DML и отбрасываются SELECT
запросы. Интерпретация Unknown и False как одного и того же логического результата является распространенной ошибкой, возникающей при работе с нулями. [ 10 ] Следующий простой пример демонстрирует это заблуждение:
SELECT *
FROM t
WHERE i = NULL;
Приведенный выше пример запроса логически всегда возвращает ноль строк, поскольку сравнение столбца i с Null всегда возвращает Unknown, даже для тех строк, где i равно Null. Неизвестный результат приводит к SELECT
оператор для суммарного отбрасывания каждой строки. (Однако на практике некоторые инструменты SQL извлекают строки, используя сравнение с Null.)
Предикаты сравнения, специфичные для NULL и 3VL
[ редактировать ]Базовые операторы сравнения SQL всегда возвращают Unknown при сравнении чего-либо с Null, поэтому стандарт SQL предусматривает два специальных предиката сравнения, специфичных для Null. IS NULL
и IS NOT NULL
предикаты (которые используют постфиксный синтаксис) проверяют, являются ли данные нулевыми или нет. [ 12 ]
Стандарт SQL содержит дополнительную функцию F571 «Проверка истинностного значения», которая вводит три дополнительных логических унарных оператора (фактически шесть, если считать их отрицание, которое является частью их синтаксиса), также использующих постфиксную нотацию. Они имеют следующие таблицы истинности: [ 13 ]
п | п ЭТО ПРАВДА | п НЕ ПРАВДА | п ЭТО ЛОЖЬ | р НЕ ЛОЖЬ | р НЕИЗВЕСТНО | р НЕ НЕИЗВЕСТНО |
---|---|---|---|---|---|---|
Истинный | Истинный | ЛОЖЬ | ЛОЖЬ | Истинный | ЛОЖЬ | Истинный |
ЛОЖЬ | ЛОЖЬ | Истинный | Истинный | ЛОЖЬ | ЛОЖЬ | Истинный |
Unknown | ЛОЖЬ | Истинный | ЛОЖЬ | Истинный | Истинный | ЛОЖЬ |
Функция F571 ортогональна наличию логического типа данных логические или трехзначные литералы в SQL (обсуждаемому далее в этой статье) и, несмотря на синтаксическое сходство, F571 не вводит в язык . Функция F571 действительно присутствовала в SQL92 , [ 14 ] задолго до того, как логический тип данных был введен в стандарт в 1999 году. Однако функция F571 реализована немногими системами; PostgreSQL — один из тех, кто его реализует.
Добавление IS UNKNOWN к другим операторам трехзначной логики SQL делает трехзначную логику SQL функционально завершенной . [ 15 ] это означает, что его логические операторы могут выражать (в комбинации) любую мыслимую трехзначную логическую функцию.
В системах, которые не поддерживают функцию F571, можно эмулировать IS UNKNOWN p , просматривая каждый аргумент, который может сделать выражение p Unknown, и проверять эти аргументы с помощью IS NULL или других функций, специфичных для NULL, хотя это может быть более громоздкий.
Закон исключенного четвертого (в пунктах WHERE)
[ редактировать ]В трехзначной логике SQL закон исключенного третьего , p ИЛИ НЕ p , больше не считается истинным для всех p . Точнее, в трехзначной логике SQL p OR NOT p неизвестен именно тогда, когда p неизвестен, и истинен в противном случае. Поскольку прямое сравнение с Null приводит к неизвестному логическому значению, следующий запрос
SELECT * FROM stuff WHERE ( x = 10 ) OR NOT ( x = 10 );
не эквивалентно в SQL с
SELECT * FROM stuff;
если столбец x содержит нули; в этом случае второй запрос вернет некоторые строки, которые не возвращает первый, а именно все те, в которых x имеет значение Null. В классической двузначной логике закон исключенного третьего допускал бы упрощение предиката предложения WHERE, а фактически его устранение. Попытка применить закон исключенного третьего к 3VL SQL фактически является ложной дихотомией . Второй запрос фактически эквивалентен:
SELECT * FROM stuff;
-- is (because of 3VL) equivalent to:
SELECT * FROM stuff WHERE ( x = 10 ) OR NOT ( x = 10 ) OR x IS NULL;
Таким образом, для правильного упрощения первого оператора SQL необходимо вернуть все строки, в которых x не равен нулю.
SELECT * FROM stuff WHERE x IS NOT NULL;
Учитывая вышеизложенное, заметим, что для предложения SQL WHERE можно записать тавтологию, подобную закону исключенного третьего. Предполагая, что присутствует оператор IS UNKNOWN, p OR (NOT p ) OR ( p IS UNKNOWN) истинен для каждого предиката p . Среди логиков это называется законом исключенной четвертой .
Есть некоторые выражения SQL, в которых менее очевидно, где возникает ложная дилемма, например:
SELECT 'ok' WHERE 1 NOT IN (SELECT CAST (NULL AS INTEGER))
UNION
SELECT 'ok' WHERE 1 IN (SELECT CAST (NULL AS INTEGER));
не создает строк, потому что IN
преобразуется в повторяющуюся версию равенства набора аргументов, и 1<>NULL является неизвестным, так же как 1=NULL является неизвестным. (CAST в этом примере необходим только в некоторых реализациях SQL, таких как PostgreSQL, которые в противном случае отклонят его с ошибкой проверки типа. Во многих системах в подзапросе работает простой SELECT NULL.) Отсутствующий случай выше, конечно, таков:
SELECT 'ok' WHERE (1 IN (SELECT CAST (NULL AS INTEGER))) IS UNKNOWN;
Эффект Null и Unknown в других конструкциях
[ редактировать ]Присоединяется
[ редактировать ]Объединения оцениваются с использованием тех же правил сравнения, что и для предложений WHERE. Поэтому необходимо соблюдать осторожность при использовании столбцов, допускающих значение NULL, в критериях соединения SQL. В частности, таблица, содержащая любые значения NULL, не равна естественному самообъединению, а это означает, что тогда как верно для любого отношения R в реляционной алгебре , самосоединение SQL исключит все строки, имеющие где-либо значение NULL. [ 16 ] Пример такого поведения приведен в разделе, посвященном анализу семантики пропущенных значений Nulls.
SQL COALESCE
функция или CASE
выражения можно использовать для «имитирования» равенства Null в критериях соединения, а IS NULL
и IS NOT NULL
предикаты также могут использоваться в критериях соединения. Следующий предикат проверяет равенство значений A и B и считает значения NULL равными.
(A = B) OR (A IS NULL AND B IS NULL)
CASE-выражения
[ редактировать ]SQL предоставляет два варианта условных выражений . Один из них называется «простым CASE» и работает как оператор переключения . Другой в стандарте называется «search CASE» и работает как if...elseif .
Простой CASE
выражения используют неявные сравнения на равенство, которые работают по тем же правилам, что и DML. WHERE
правила предложения для Null. Таким образом, простой CASE
выражение не может напрямую проверить наличие Null. Проверка на Null простым способом CASE
выражение всегда приводит к Unknown, как показано ниже:
SELECT CASE i WHEN NULL THEN 'Is Null' -- This will never be returned
WHEN 0 THEN 'Is Zero' -- This will be returned when i = 0
WHEN 1 THEN 'Is One' -- This will be returned when i = 1
END
FROM t;
Поскольку выражение i = NULL
оценивается как Неизвестно независимо от того, какое значение содержит столбец i (даже если он содержит значение Null), строка 'Is Null'
никогда не будет возвращен.
С другой стороны, "искавший" CASE
выражение может использовать предикаты, такие как IS NULL
и IS NOT NULL
в его условиях. В следующем примере показано, как использовать поиск CASE
выражение для правильной проверки значения Null:
SELECT CASE WHEN i IS NULL THEN 'Null Result' -- This will be returned when i is NULL
WHEN i = 0 THEN 'Zero' -- This will be returned when i = 0
WHEN i = 1 THEN 'One' -- This will be returned when i = 1
END
FROM t;
В поиске CASE
выражение, строка 'Null Result'
возвращается для всех строк, в которых i имеет значение NULL.
Диалект SQL Oracle предоставляет встроенную функцию DECODE
который можно использовать вместо простых выражений CASE и считает два нуля равными.
SELECT DECODE(i, NULL, 'Null Result', 0, 'Zero', 1, 'One') FROM t;
Наконец, все эти конструкции возвращают NULL, если совпадение не найдено; у них есть значение по умолчанию ELSE NULL
пункт.
Операторы IF в процедурных расширениях
[ редактировать ]SQL/PSM (постоянные хранимые модули SQL) определяет процедурные расширения для SQL, такие как IF
заявление. Однако основные поставщики SQL исторически включали свои собственные процедурные расширения. Процедурные расширения для циклов и сравнений работают в соответствии с правилами сравнения значений Null, аналогичными правилам для операторов и запросов DML. Следующий фрагмент кода в стандартном формате ISO SQL демонстрирует использование Null 3VL в IF
заявление.
IF i = NULL THEN
SELECT 'Result is True'
ELSEIF NOT(i = NULL) THEN
SELECT 'Result is False'
ELSE
SELECT 'Result is Unknown';
The IF
Оператор выполняет действия только для тех сравнений, которые оцениваются как True. Для операторов, которые оцениваются как False или Unknown, IF
оператор передает управление ELSEIF
пункт и, наконец, ELSE
пункт. Результатом приведенного выше кода всегда будет сообщение 'Result is Unknown'
поскольку сравнения с Null всегда оцениваются как Unknown.
Анализ семантики пропущенных значений SQL Null
[ редактировать ]Новаторская работа Т. Имелинского и В. Липского-младшего (1984). [ 17 ] предоставил основу для оценки предполагаемой семантики различных предложений по реализации семантики пропущенных значений, которая называется алгеброй Имелинского-Липского . Этот раздел примерно соответствует главе 19 учебника «Алиса». [ 18 ] Аналогичное изложение появляется в обзоре Рона ван дер Мейдена, §10.4. [ 1 ]
В выборках и прогнозах: слабое представительство
[ редактировать ]Конструкции, представляющие недостающую информацию, такие как таблицы Кодда, на самом деле предназначены для представления набора отношений, по одному для каждого возможного экземпляра их параметров; в случае таблиц Кодда это означает замену нулей каким-то конкретным значением. Например,
Имя | Возраст |
---|---|
Джордж | 43 |
Гарриет | NULL
|
Чарльз | 56 |
Имя | Возраст |
---|---|
Джордж | 43 |
Гарриет | 22 |
Чарльз | 56 |
Имя | Возраст |
---|---|
Джордж | 43 |
Гарриет | 37 |
Чарльз | 56 |
Конструкция (такая как таблица Кодда) называется сильной системой представления (недостающей информации), если любой ответ на запрос, сделанный на основе конструкции, может быть конкретизирован для получения ответа на любой соответствующий запрос по отношениям, которые она представляет, что рассматриваются как модели конструкции. Точнее, если q — это формула запроса в реляционной алгебре («чистых» отношений) и если q — это ее повышение до конструкции, предназначенной для представления недостающей информации, сильное представление обладает тем свойством, что для любого запроса q и (таблица) конструкция T , q поднимает все ответы на конструкцию, т.е.:
(Вышеуказанное справедливо для запросов, принимающих любое количество таблиц в качестве аргументов, но для данного обсуждения достаточно ограничения одной таблицей.) Очевидно, что таблицы Кодда не обладают этим сильным свойством, если выборки и проекции рассматриваются как часть языка запросов. Например, все ответы на
SELECT * FROM Emp WHERE Age = 22;
должен включать возможность существования такой связи, как EmpH22. Однако таблицы Кодда не могут представлять результат дизъюнкции, возможно, с 0 или 1 строкой. устройство, представляющее в основном теоретический интерес, называемое условной таблицей Однако такой ответ может представлять собой (или c-таблицей):
Имя | Возраст | состояние |
---|---|---|
Гарриет | ох 1 | ω 1 = 22 |
где столбец условия интерпретируется как строка не существует, если условие ложно. Оказывается, поскольку формулы в столбце условий c-таблицы могут быть произвольными формулами пропозициональной логики , алгоритм решения проблемы, представляет ли c-таблица какое-то конкретное отношение, имеет ко-NP-полную сложность и, таким образом, не имеет большого значения. практическая ценность.
Поэтому желательно более слабое понятие представительства. Имелински и Липски ввели понятие слабого представления , которое, по сути, позволяет (снимать) запросы к конструкции, чтобы возвращать представление только для достоверной информации, т.е. если оно действительно для всех « возможных мировых » экземпляров (моделей) конструкции. Конкретно, конструкция является слабой системой представления, если
Правая часть приведенного выше уравнения представляет собой достоверную информацию, т. е. информацию, которую можно с уверенностью извлечь из базы данных независимо от того, какие значения используются для замены нулей в базе данных. В примере, который мы рассмотрели выше, легко увидеть, что пересечение всех возможных моделей (т.е. достоверной информации) выбора запроса WHERE Age = 22
на самом деле пуст, потому что, например, (необработанный) запрос не возвращает строк для отношения EmpH37. В более общем плане Имелински и Липски показали, что таблицы Кодда являются слабой системой представления, если язык запросов ограничивается проекциями, выбором (и переименованием столбцов). Однако как только мы добавляем в язык запросов соединения или объединения, даже это слабое свойство теряется, как показано в следующем разделе.
Если рассматриваются соединения или союзы: даже слабое представление
[ редактировать ]Рассмотрим следующий запрос к той же таблице Кодда. Эмп из предыдущего раздела:
SELECT Name FROM Emp WHERE Age = 22
UNION
SELECT Name FROM Emp WHERE Age <> 22;
Какую бы конкретную ценность вы бы ни выбрали для NULL
возраста Гарриет, приведенный выше запрос вернет полный столбец имен любой модели Emp , но когда (снятый) запрос выполняется Сам Эмп , Харриет всегда будет отсутствовать, т.е. имеем:
Результат запроса Эмп : |
|
Результат запроса по любой модели Эмп : |
|
Таким образом, когда в язык запросов добавляются объединения, таблицы Кодда даже не являются слабой системой представления недостающей информации, а это означает, что запросы к ним даже не сообщают всю достоверную информацию. Здесь важно отметить, что семантика UNION для нулевых значений, которая обсуждается в следующем разделе, даже не использовалась в этом запросе. «Забывчивый» характер двух подзапросов был достаточным для того, чтобы гарантировать, что некоторая достоверная информация останется незамеченной при выполнении вышеуказанного запроса к таблице Кодда Emp.
Для естественных объединений пример, показывающий, что определенная информация может не сообщаться некоторым запросом, немного сложнее. Рассмотрим таблицу
Ф1 | Ф2 | F3 |
---|---|---|
11 | NULL |
13 |
21 | NULL |
23 |
31 | 32 | 33 |
и запрос
SELECT F1, F3 FROM
(SELECT F1, F2 FROM J) AS F12
NATURAL JOIN
(SELECT F2, F3 FROM J) AS F23;
Результат запроса по J: |
|
Результат запроса по любой модели J: |
|
Интуиция того, что происходит выше, заключается в том, что таблицы Кодда, представляющие проекции в подзапросах, упускают из виду тот факт, что нули в столбцах F12.F2 и F23.F2 на самом деле являются копиями оригиналов в таблице J. Это наблюдение предполагает, что относительно простым улучшением таблиц Кодда (которое правильно работает в этом примере) было бы использование констант Скулема (то есть функций Скулема , которые также являются постоянными функциями ), скажем, ω 12 и ω 22. вместо одного NULL-символа. Такой подход, называемый v-таблицами или наивными таблицами, требует меньше вычислительных затрат, чем c-таблицы, обсуждавшиеся выше. Однако это все еще не полное решение для неполной информации в том смысле, что v-таблицы являются лишь слабым представлением для запросов, не использующих никаких отрицаний при выборе (и не использующих никаких различий между множествами). Первый пример, рассматриваемый в этом разделе, — использование предложения отрицательного выбора: WHERE Age <> 22
, поэтому это также пример, когда запросы к v-таблицам не сообщают достоверную информацию.
Проверка ограничений и внешних ключей
[ редактировать ]Основное место, где трехзначная логика SQL пересекается с языком определения данных SQL (DDL), — это форма проверочных ограничений . Проверочное ограничение, помещенное в столбец, действует по несколько иному набору правил, чем правила DML. WHERE
пункт. В то время как DML WHERE
предложение должно иметь значение True для строки, проверочное ограничение не должно иметь значение False. (С точки зрения логики назначенными значениями являются «Истина» и «Неизвестно».) Это означает, что ограничение проверки будет успешным, если результат проверки будет либо «Истина», либо «Неизвестно». В следующем примере таблицы с проверочным ограничением будет запрещена вставка любых целочисленных значений в столбец i , но будет разрешена вставка Null, поскольку результат проверки всегда будет оцениваться как Unknown для Nulls. [ 19 ]
CREATE TABLE t (
i INTEGER,
CONSTRAINT ck_i CHECK ( i < 0 AND i = 0 AND i > 0 ) );
Из-за изменения обозначенных значений относительно ГДЕ , с логической точки зрения, закон исключенного третьего является тавтологией для ПРОВЕРИТЬ ограничения, что означает CHECK (p OR NOT p)
всегда удается. Более того, если предположить, что значения NULL следует интерпретировать как существующие, но неизвестные значения, некоторые патологические ПРОВЕРКИ, подобные показанному выше, позволяют вставлять значения NULL, которые никогда не могут быть заменены каким-либо значением, отличным от NULL.
Чтобы ограничить столбец отклонением значений NULL, NOT NULL
ограничение может быть применено, как показано в примере ниже. NOT NULL
ограничение семантически эквивалентно проверочному ограничению с IS NOT NULL
предикат.
CREATE TABLE t ( i INTEGER NOT NULL );
По умолчанию проверка ограничений на внешние ключи завершается успешно, если какое-либо из полей таких ключей имеет значение NULL. Например, таблица
CREATE TABLE Books
( title VARCHAR(100),
author_last VARCHAR(20),
author_first VARCHAR(20),
FOREIGN KEY (author_last, author_first)
REFERENCES Authors(last_name, first_name));
позволит вставлять строки, в которых указаны значенияauthor_last илиauthor_first. NULL
независимо от того, как определена таблица «Авторы» или что она содержит. Точнее, значение null в любом из этих полей допускает любое значение в другом, даже если оно не найдено в таблице авторов. Например, если Авторы содержали только ('Doe', 'John')
, затем ('Smith', NULL)
будет удовлетворять ограничению внешнего ключа. В SQL-92 добавлены две дополнительные опции для сужения совпадений в таких случаях. Если MATCH PARTIAL
добавляется после REFERENCES
объявление, то любое ненулевое значение должно соответствовать внешнему ключу, например ('Doe', NULL)
все равно будет соответствовать, но ('Smith', NULL)
не стал бы. Наконец, если MATCH FULL
добавляется тогда ('Smith', NULL)
также не будет соответствовать ограничению, но (NULL, NULL)
все равно будет соответствовать этому.
Внешние соединения
[ редактировать ]
NULL
вместо данных в результатах. Результаты взяты из Microsoft SQL Server , как показано в SQL Server Management Studio. SQL Внешние соединения , включая левые внешние соединения, правые внешние соединения и полные внешние соединения, автоматически создают пустые значения в качестве заполнителей для отсутствующих значений в связанных таблицах. Например, для левых внешних соединений нули создаются вместо строк, отсутствующих в таблице, появляющихся в правой части таблицы. LEFT OUTER JOIN
оператор. В следующем простом примере используются две таблицы, чтобы продемонстрировать создание пустого заполнителя в левом внешнем соединении.
Первая таблица ( Сотрудник ) содержит идентификационные номера и имена сотрудников, а вторая таблица ( PhoneNumber ) содержит соответствующие идентификационные номера сотрудников и номера телефонов , как показано ниже.
|
|
Следующий пример SQL-запроса выполняет левое внешнее соединение этих двух таблиц.
SELECT e.ID, e.LastName, e.FirstName, pn.Number
FROM Employee e
LEFT OUTER JOIN PhoneNumber pn
ON e.ID = pn.ID;
Набор результатов , сгенерированный этим запросом, демонстрирует, как SQL использует Null в качестве заполнителя для значений, отсутствующих в правой таблице ( PhoneNumber ), как показано ниже.
ИДЕНТИФИКАТОР | Фамилия | Имя | Число |
---|---|---|---|
1 | Джонсон | Джо | 555-2323 |
2 | Льюис | Ларри | NULL
|
3 | Томпсон | Томас | 555-9876 |
4 | Паттерсон | Патрисия | NULL
|
Агрегатные функции
[ редактировать ]SQL определяет агрегатные функции для упрощения агрегатных вычислений данных на стороне сервера. За исключением COUNT(*)
функции, все агрегатные функции выполняют этап исключения нулей, поэтому нули не включаются в окончательный результат вычисления. [ 20 ]
Обратите внимание, что удаление Null не эквивалентно замене Null нулем. Например, в следующей таблице AVG(i)
(среднее значение i
) даст результат, отличный от результата AVG(j)
:
я | дж |
---|---|
150 | 150 |
200 | 200 |
250 | 250 |
NULL
|
0 |
Здесь AVG(i)
составляет 200 (среднее значение 150, 200 и 250), а AVG(j)
равно 150 (среднее значение 150, 200, 250 и 0). Хорошо известным побочным эффектом этого является то, что в SQL AVG(z)
эквивалентно не SUM(z)/COUNT(*)
но SUM(z)/COUNT(z)
. [ 4 ]
Выходные данные агрегатной функции также могут быть нулевыми. Вот пример:
SELECT COUNT(*), MIN(e.Wage), MAX(e.Wage)
FROM Employee e
WHERE e.LastName LIKE '%Jones%';
Этот запрос всегда будет выводить ровно одну строку, подсчитывая количество сотрудников, фамилия которых содержит «Джонс», и выдавая минимальную и максимальную заработную плату, найденную для этих сотрудников. Однако что произойдет, если ни один из сотрудников не соответствует заданным критериям? Вычислить минимальное или максимальное значение пустого набора невозможно, поэтому эти результаты должны быть NULL, что указывает на отсутствие ответа. Это не неизвестное значение, это значение Null, обозначающее отсутствие значения. Результатом будет:
СЧИТАТЬ(*) | МИН(электронная заработная плата) | МАКС. (электронная заработная плата) |
---|---|---|
0 | NULL
|
NULL
|
Когда два нуля равны: группировка, сортировка и некоторые операции над множествами.
[ редактировать ]Поскольку SQL:2003 определяет все нулевые маркеры как неравные друг другу, требовалось специальное определение для группировки нулевых значений вместе при выполнении определенных операций. SQL определяет «любые два значения, равные друг другу, или любые два нуля» как «неразличимые». [ 21 ] Это определение неотличимости позволяет SQL группировать и сортировать нули, когда GROUP BY
используется предложение (и другие ключевые слова, выполняющие группировку).
В других операциях SQL, предложениях и ключевых словах при обработке значений NULL используется слово «не различимо». К ним относятся следующие:
PARTITION BY
пункт о ранжировании и оконных функциях, таких какROW_NUMBER
UNION
,INTERSECT
, иEXCEPT
оператор, который обрабатывает NULL как одно и то же для целей сравнения/исключения строкDISTINCT
ключевое слово, используемое вSELECT
запросы
Принцип, согласно которому значения NULL не равны друг другу (а скорее, что результат неизвестен), фактически нарушается в спецификации SQL для UNION
оператор, который идентифицирует нули друг с другом. [ 1 ] Следовательно, некоторые операции над множествами в SQL, такие как объединение или различие, могут давать результаты, не представляющие достоверную информацию, в отличие от операций, включающих явное сравнение с NULL (например, в WHERE
пункт, рассмотренный выше). В предложении Кодда 1979 года (которое в основном было принято в SQL92) это семантическое несоответствие объясняется тем, что удаление дубликатов в операциях над множествами происходит «на более низком уровне детализации, чем проверка на равенство при оценке операций поиска». [ 11 ]
Стандарт SQL явно не определяет порядок сортировки по умолчанию для нулей. Вместо этого в соответствующих системах нули можно сортировать до или после всех значений данных, используя метод NULLS FIRST
или NULLS LAST
положения ORDER BY
список соответственно. Однако не все поставщики СУБД реализуют эту функциональность. Поставщики, которые не реализуют эту функциональность, могут указать в СУБД разные способы сортировки значений Null. [ 19 ]
Влияние на работу индекса
[ редактировать ]Некоторые продукты SQL не индексируют ключи, содержащие NULL. Например, в версиях PostgreSQL до 8.3 этого не было, а в документации по индексу B-дерева указано, что [ 22 ]
B-деревья могут обрабатывать запросы на равенство и диапазон данных, которые можно отсортировать в определенном порядке. В частности, планировщик запросов PostgreSQL будет рассматривать возможность использования индекса B-дерева всякий раз, когда индексированный столбец участвует в сравнении с использованием одного из этих операторов: < ≤ = ≥ >
Конструкции, эквивалентные комбинациям этих операторов, такие как BETWEEN и IN, также могут быть реализованы с помощью поиска по индексу B-дерева. (Но обратите внимание, что IS NULL не эквивалентен = и не индексируется.)
В тех случаях, когда индекс обеспечивает уникальность, значения NULL исключаются из индекса, а уникальность между значениями NULL не обеспечивается. Опять же, цитируя документацию PostgreSQL : [ 23 ]
Если индекс объявлен уникальным, несколько строк таблицы с одинаковыми индексированными значениями не допускаются. Нулевые значения не считаются равными. Уникальный индекс с несколькими столбцами будет отклонять только те случаи, когда все индексированные столбцы равны в двух строках.
Это соответствует в SQL:2003 поведению скалярных сравнений Null, определенному .
Другой метод индексирования нулей предполагает обработку их как неразличимых в соответствии с поведением, определенным в SQL:2003. Например, в документации Microsoft SQL Server указано следующее: [ 24 ]
В целях индексации значения NULL сравниваются как равные. Следовательно, уникальный индекс или ограничение UNIQUE не может быть создан, если ключи имеют значение NULL более чем в одной строке. Выберите столбцы, которые определены как NOT NULL, когда выбраны столбцы для уникального индекса или ограничения уникальности.
Обе эти стратегии индексирования соответствуют поведению Null, определенному в SQL:2003. Поскольку методологии индексирования явно не определены стандартом SQL:2003, разработка и реализация стратегий индексирования для значений Null полностью оставлены на усмотрение поставщиков.
Функции обработки нулей
[ редактировать ]SQL определяет две функции для явной обработки значений NULL: NULLIF
и COALESCE
. Обе функции являются аббревиатурами для поиска CASE
выражения . [ 25 ]
НУЛИФ
[ редактировать ]The NULLIF
функция принимает два параметра. Если первый параметр равен второму параметру, NULLIF
возвращает ноль. В противном случае возвращается значение первого параметра.
NULLIF(value1, value2)
Таким образом, NULLIF
является аббревиатурой следующих CASE
выражение:
CASE WHEN value1 = value2 THEN NULL ELSE value1 END
ОБЪЕДИНЯТЬСЯ
[ редактировать ]The COALESCE
функция принимает список параметров, возвращая первое ненулевое значение из списка:
COALESCE(value1, value2, value3, ...)
COALESCE
определяется как сокращение для следующего SQL CASE
выражение:
CASE WHEN value1 IS NOT NULL THEN value1
WHEN value2 IS NOT NULL THEN value2
WHEN value3 IS NOT NULL THEN value3
...
END
Некоторые СУБД SQL реализуют функции, специфичные для конкретного поставщика, подобные COALESCE
. Некоторые системы (например, Transact-SQL ) реализуют ISNULL
функция или другие подобные функции, которые функционально аналогичны COALESCE
. (Видеть Is
функции для получения дополнительной информации о IS
функции в Transact-SQL.)
НВЛ
[ редактировать ]Оракул NVL
функция принимает два параметра. Он возвращает первый параметр, отличный от NULL, или NULL, если все параметры имеют значение NULL.
А COALESCE
выражение можно преобразовать в эквивалент NVL
выражение таким образом:
COALESCE ( val1, ... , val{n} )
превращается в:
NVL( val1 , NVL( val2 , NVL( val3 , … , NVL ( val{n-1} , val{n} ) … )))
Вариант использования этой функции — замена в выражении NULL значением, например NVL(SALARY, 0)
который говорит: «Если SALARY
имеет значение NULL, замените его значением 0'.
Однако есть одно примечательное исключение. В большинстве реализаций COALESCE
оценивает свои параметры до тех пор, пока не достигнет первого значения, отличного от NULL, в то время как NVL
оценивает все свои параметры. Это важно по нескольким причинам. Параметр после первого параметра, отличного от NULL, может быть функцией, которая может быть либо дорогостоящей в вычислительном отношении, либо недопустимой, либо создавать неожиданные побочные эффекты.
Типизация данных Null и Unknown
[ редактировать ]The NULL
Литерал не типизирован в SQL, что означает, что он не обозначается как целое число, символ или какой-либо другой конкретный тип данных . [ 26 ] По этой причине иногда необходимо (или желательно) явно преобразовывать значения NULL в определенный тип данных. Например, если СУБД поддерживает перегруженные функции, SQL не сможет автоматически разрешить правильную функцию, не зная типов данных всех параметров, включая те, для которых передается значение Null.
Конверсия из NULL
литерал к Null определенного типа возможен с использованием CAST
введенный в SQL-92 . Например:
CAST (NULL AS INTEGER)
представляет отсутствующее значение типа INTEGER.
Фактический тип Неизвестного (отличающийся от самого NULL или нет) варьируется в зависимости от реализации SQL. Например, следующее
SELECT 'ok' WHERE (NULL <> 1) IS NULL;
анализирует и успешно выполняет в некоторых средах (например, SQLite или PostgreSQL ), которые объединяют логическое значение NULL с неизвестным, но не могут анализировать в других (например, в SQL Server Compact ). В этом отношении MySQL ведет себя аналогично PostgreSQL (с небольшим исключением: MySQL считает TRUE и FALSE ничем не отличающимся от обычных целых чисел 1 и 0). PostgreSQL дополнительно реализует IS UNKNOWN
предикат, который можно использовать для проверки того, является ли трехзначный логический результат Неизвестным, хотя это всего лишь синтаксический сахар.
БУЛЕВЫЙ тип данных
[ редактировать ]Стандарт ISO SQL:1999 ввел в SQL тип данных BOOLEAN, однако это по-прежнему всего лишь необязательная, неосновная функция, имеющая код T031. [ 27 ]
При ограничении NOT NULL
ограничение, SQL BOOLEAN работает так же, как логический тип из других языков. Однако без ограничений тип данных BOOLEAN, несмотря на свое название, может содержать значения истинности TRUE, FALSE и UNKNOWN, которые все определяются как логические литералы в соответствии со стандартом. Стандарт также утверждает, что NULL и UNKNOWN «можно использовать
взаимозаменяемо, чтобы означать одно и то же». [ 28 ] [ 29 ]
Логический тип подвергался критике, особенно из-за обязательного поведения литерала UNKNOWN, который никогда не равен самому себе из-за идентификации с NULL. [ 30 ]
Как обсуждалось выше, в в PostgreSQL реализации SQL Null используется для представления всех НЕИЗВЕСТНЫХ результатов, включая НЕИЗВЕСТНОЕ БУЛЕВОЕ значение. PostgreSQL не реализует литерал UNKNOWN (хотя он реализует оператор IS UNKNOWN, который является ортогональной функцией). Большинство других основных поставщиков не поддерживают логический тип (как определено в T031) по состоянию на 2012 год. [ 31 ] Однако процедурная часть Oracle PL/SQL поддерживает переменные BOOLEAN; им также может быть присвоено NULL, и это значение считается таким же, как UNKNOWN. [ 32 ]
Споры
[ редактировать ]Распространенные ошибки
[ редактировать ]Непонимание того, как работает Null, является причиной большого количества ошибок в коде SQL, как в стандартных операторах SQL ISO, так и в конкретных диалектах SQL, поддерживаемых реальными системами управления базами данных. Эти ошибки обычно являются результатом путаницы между Null и 0 (нолем) или пустой строкой (строковым значением нулевой длины, представленным в SQL как ''
). Значение Null определяется стандартом SQL как отличное от пустой строки и числового значения. 0
, однако. Хотя значение Null указывает на отсутствие какого-либо значения, пустая строка и числовой ноль представляют фактические значения.
Классическая ошибка — попытка использовать оператор равенства. =
в сочетании с ключевым словом NULL
чтобы найти строки с нулями. Согласно стандарту SQL это недопустимый синтаксис, который приведет к сообщению об ошибке или исключению. Но большинство реализаций принимают синтаксис и оценивают такие выражения как UNKNOWN
. В результате строки не найдены — независимо от того, существуют ли строки с нулями или нет. Предлагаемый способ получения строк с нулями заключается в использовании предиката IS NULL
вместо = NULL
.
SELECT *
FROM sometable
WHERE num = NULL; -- Should be "WHERE num IS NULL"
В похожем, но более тонком примере, WHERE
предложение или условный оператор могут сравнивать значение столбца с константой. Часто ошибочно предполагается, что отсутствующее значение будет «меньше» или «не равно» константе, если это поле содержит значение Null, но на самом деле такие выражения возвращают Unknown. Пример ниже:
SELECT *
FROM sometable
WHERE num <> 1; -- Rows where num is NULL will not be returned,
-- contrary to many users' expectations.
Эта путаница возникает из-за того, что Закон идентичности ограничен в логике SQL. При сравнении сравнений на равенство с использованием NULL
буквально или UNKNOWN
истинностное значение, SQL всегда будет возвращать значения UNKNOWN
как результат выражения. Это отношение частичной эквивалентности , которое делает SQL примером нерефлексивной логики . [ 33 ]
Точно так же нули часто путают с пустыми строками. Рассмотрим LENGTH
функция, которая возвращает количество символов в строке. Когда в эту функцию передается значение Null, функция возвращает значение Null. Это может привести к неожиданным результатам, если пользователи плохо разбираются в трехзначной логике. Пример ниже:
SELECT *
FROM sometable
WHERE LENGTH(string) < 20; -- Rows where string is NULL will not be returned.
Это осложняется тем фактом, что в некоторых программах интерфейса базы данных (или даже в реализациях баз данных, таких как Oracle), NULL отображается как пустая строка, а пустые строки могут быть неправильно сохранены как NULL.
Критика
[ редактировать ]Реализация Null в ISO SQL является предметом критики, споров и призывов к переменам. В книге «Реляционная модель управления базами данных: версия 2 » Кодд предположил, что реализация Null в SQL имеет недостатки и ее следует заменить двумя отдельными маркерами нулевого типа. Маркеры, которые он предложил, должны были обозначать «Отсутствует, но применимо» и «Отсутствует, но неприменимо» , известные как A-значения и I-значения соответственно. Рекомендация Кодда, если бы она была принята, потребовала бы реализации четырехзначной логики в SQL. [ 5 ] Другие предложили добавить к рекомендации Кодда дополнительные маркеры нулевого типа, чтобы указать еще больше причин, по которым значение данных может быть «отсутствующим», что увеличивает сложность логической системы SQL. В разное время также выдвигались предложения по реализации в SQL нескольких определяемых пользователем нулевых маркеров. Из-за сложности обработки Null и логических систем, необходимых для поддержки нескольких нулевых маркеров, ни одно из этих предложений не получило широкого признания.
Крис Дэйт и Хью Дарвен , авторы «Третьего манифеста» , предположили, что реализация SQL Null по своей сути ошибочна и ее следует полностью исключить. [ 34 ] указывая на несоответствия и недостатки в реализации обработки Null в SQL (особенно в агрегатных функциях) как на доказательство того, что вся концепция Null ошибочна и ее следует удалить из реляционной модели. [ 35 ] Другие, такие как автор Фабиан Паскаль , высказали убеждение, что «то, как вычисление функции должно обрабатывать пропущенные значения, не регулируется реляционной моделью». [ нужна ссылка ]
Предположение о закрытом мире
[ редактировать ]Еще один конфликт, касающийся нулей, заключается в том, что они нарушают модель предположений о закрытом мире реляционных баз данных, вводя в нее предположение об открытом мире . [ 36 ] Предположение о закрытом мире, применительно к базам данных, гласит: «Все, что заявлено в базе данных, явно или неявно, истинно; все остальное ложно». [ 37 ] Эта точка зрения предполагает, что знания о мире, хранящиеся в базе данных, являются полными. Однако нули действуют в предположении открытого мира, в котором некоторые элементы, хранящиеся в базе данных, считаются неизвестными, что делает хранимые в базе данных знания о мире неполными.
См. также
[ редактировать ]- SQL
- NULL в: Wikibook SQL
- Трехзначная логика
- Язык манипулирования данными
- 12 правил Кодда
- Проверить ограничение
- Реляционная модель/Тасмания
- Система управления реляционными базами данных
- Присоединиться (SQL)
Ссылки
[ редактировать ]- ^ Jump up to: а б с д Рон ван дер Мейден, « Логические подходы к неполной информации: обзор » в Хомицки, Январь; Сааке, Гюнтер (ред.) Логика для баз данных и информационных систем , Kluwer Academic Publishers ISBN 978-0-7923-8129-7 , с. 344; Препринт PS (примечание: нумерация страниц в препринте отличается от опубликованной версии)
- ^ Кодд, Э.Ф. (14 октября 1985 г.). «Действительно ли ваша база данных реляционная?». Компьютерный мир .
- ^ Кодд, Э.Ф. (21 октября 1985 г.). «Ваша СУБД работает по правилам?». Компьютерный мир .
- ^ Jump up to: а б Дон Чемберлин (1998). Полное руководство по универсальной базе данных DB2 . Морган Кауфманн. стр. 28–32. ISBN 978-1-55860-482-7 .
- ^ Jump up to: а б Кодд, Э.Ф. (1990). Реляционная модель управления базами данных (Версия 2-е изд.). Издательская компания Аддисон Уэсли . ISBN 978-0-201-14192-4 .
- ^ Jump up to: а б ИСО/МЭК (2003). ISO/IEC 9075-2:2003, «SQL/Foundation» . ИСО/МЭК. Раздел 6.2.6: выражения числовых значений . .
- ^ ИСО/МЭК (2003). ISO/IEC 9075-2:2003, «SQL/Foundation» . ИСО/МЭК. Раздел 6.2.8: выражение строкового значения .
- ^ «Обработка пустых строк при переходе с Oracle на PostgreSQL | Блог базы данных AWS» . aws.amazon.com . 23 мая 2022 г. Проверено 30 декабря 2023 г.
- ^ ИСО/МЭК (2003). ISO/IEC 9075-1:2003, «SQL/Framework» . ИСО/МЭК. Раздел 4.4.2: Нулевое значение .
- ^ Jump up to: а б Коулз, Майкл (27 июня 2005 г.). «Четыре правила для нулей» . Центральный SQL-сервер . Программное обеспечение Red Gate.
- ^ Jump up to: а б Ханс-Иоахим, К. (2003). «Нулевые значения в реляционных базах данных и достоверные информационные ответы» . Семантика в базах данных. Второй международный семинар в замке Дагштуль, Германия, 7–12 января 2001 г. Пересмотренные статьи . Конспекты лекций по информатике. Том. 2582. стр. 119–138. дои : 10.1007/3-540-36596-6_7 . ISBN 978-3-540-00957-3 .
- ^ ИСО/МЭК (2003). ISO/IEC 9075-2:2003, «SQL/Foundation» . ИСО/МЭК. Раздел 8.7: нулевой предикат .
- ^ CJ Date (2004), Введение в системы баз данных , 8-е изд., Pearson Education, p. 594
- ^ Джим Мелтон; Джим Мелтон Алан Р. Саймон (1993). Понимание нового SQL: полное руководство . Морган Кауфманн. стр. 145–147. ISBN 978-1-55860-245-8 .
- ^ CJ Date, Сочинения о реляционных базах данных, 1991–1994 гг. , Аддисон-Уэсли, 1995 г., стр. 371
- ^ CJ Date (2004), Введение в системы баз данных , 8-е изд., Pearson Education, p. 584
- ^ Имелинский, Т. ; Липски-младший, В. (1984). «Неполная информация в реляционных базах данных» . Журнал АКМ . 31 (4): 761–791. дои : 10.1145/1634.1886 . S2CID 288040 .
- ^ Абитбул, Серж ; Халл, Ричард Б .; Виану, Виктор (1995). Основы баз данных . Аддисон-Уэсли. ISBN 978-0-201-53771-0 .
- ^ Jump up to: а б Коулз, Майкл (26 февраля 2007 г.). «Ноль против нуля?» . Центральный SQL-сервер . Программное обеспечение Red Gate.
- ^ ИСО/МЭК (2003). ISO/IEC 9075-2:2003, «SQL/Foundation» . ИСО/МЭК. Раздел 4.15.4: Агрегатные функции .
- ^ ИСО/МЭК (2003). ISO/IEC 9075-2:2003, «SQL/Foundation» . ИСО/МЭК. Раздел 3.1.6.8: Определения: отдельные .
- ^ «Документация PostgreSQL 8.0.14: Типы индексов» . ПостгреСБЛ . Проверено 6 ноября 2008 г.
- ^ «Документация PostgreSQL 8.0.14: уникальные индексы» . ПостгреСБЛ . Проверено 6 ноября 2008 г.
- ^ «Создание уникальных индексов» . ПостфреSQL. Сентябрь 2007 года . Проверено 6 ноября 2008 г.
- ^ ИСО/МЭК (2003). ISO/IEC 9075-2:2003, «SQL/Foundation» . ИСО/МЭК. Раздел 6.11: выражение регистра .
- ^ Джим Мелтон ; Алан Р. Саймон (2002). SQL:1999: Понимание компонентов реляционного языка . Морган Кауфманн. п. 53 . ISBN 978-1-55860-456-8 .
- ^ «ISO/IEC 9075-1:1999 Стандарт SQL». ИСО. 1999.
{{cite web}}
: Отсутствует или пусто|url=
( помощь ) - ^ С. Дата (2011). SQL и реляционная теория: как писать точный код SQL . О'Рейли Медиа, Инк. с. 83. ИСБН 978-1-4493-1640-2 .
- ^ ИСО/МЭК 9075-2:2011 §4.5
- ^ Мартин Пригмор (2007). Введение в базы данных с веб-приложениями . Пирсон Образования Канады. п. 197. ИСБН 978-0-321-26359-9 .
- ^ Троэлс Арвин, Обзор реализации типа данных BOOLEAN
- ^ Стивен Фейерштейн; Билл Прибыл (2009). Программирование Oracle PL/SQL . O'Reilly Media, Inc., стр. 74, 91. ISBN. 978-0-596-51446-4 .
- ^ Аренхарт, Краузе (2012), «Классическая логика или нерефлексивная логика? Случай семантической недоопределенности», Revista Portuguesa de Filosofia , 68 (1/2): 73–86, doi : 10.17990/RPF/2012_68_1_0073 , JSTOR 41955624 .
- ^ Дарвен, Хью; Крис Дэйт. «Третий манифест» . Проверено 29 мая 2007 г.
- ^ Дарвен, Хью. «Кривая стена» (PDF) . Проверено 29 мая 2007 г.
- ^ Дэйт, Крис (май 2005 г.). База данных в глубине: реляционная теория для практиков . О'Рейли Медиа, Инк. с. 73. ИСБН 978-0-596-10012-4 .
- ^ Свидание, Крис. «Аннотация: Предположение о закрытом мире» . Ассоциация управления данными , отделение области залива Сан-Франциско. Архивировано из оригинала 19 мая 2007 г. Проверено 29 мая 2007 г.
Дальнейшее чтение
[ редактировать ]- Э. Ф. Кодд. Понимание отношений (часть №7). Бюллетень FDT ACM-SIGMOD, 7 (3-4): 23–28, 1975.
- Кодд, Э.Ф. (1979). «Расширение реляционной модели базы данных для большего понимания». Транзакции ACM в системах баз данных . 4 (4): 397–434. CiteSeerX 10.1.1.508.5701 . дои : 10.1145/320107.320109 . S2CID 17517212 . Особенно §2.3.
- Дата, CJ (2000). Реляционная модель базы данных: ретроспективный обзор и анализ: исторический отчет и оценка вклада Э. Ф. Кодда в область технологии баз данных . Эддисон Уэсли Лонгман . ISBN 978-0-201-61294-3 .
- Кляйн, Ханс-Иоахим (1994). «Как изменить SQL-запросы, чтобы гарантировать точные ответы» . Запись ACM SIGMOD . 23 (3): 14–20. дои : 10.1145/187436.187445 . S2CID 17354724 .
- Клод Рубинсон, Nulls, трехзначная логика и неоднозначность в SQL: критика критики Date, заархивированная 5 марта 2016 г. в Wayback Machine , SIGMOD Record, декабрь 2007 г. (том 36, № 4)
- Джон Грант, Нулевые значения в SQL . SIGMOD Record, сентябрь 2008 г. (Том 37, № 3)
- Варапорн, Наронгрит и Криенгкрай Поркеу. « Нулевая семантика для подзапросов и атомарных предикатов ». IAENG 35.3 (2008): 305–313. Международный журнал компьютерных наук
- Бернхард Тальгейм; Клаус-Дитер Шеве (2011). «Алгебры и логики с нулевым значением» . Границы искусственного интеллекта и приложений . 225 (Информационное моделирование и базы знаний XXII). дои : 10.3233/978-1-60750-690-4-354 .
- Энрико Франкони и Серджио Тессарис, О логике нулевых значений SQL , Материалы 6-го Международного семинара Альберто Мендельзона по основам управления данными, Ору-Прету, Бразилия, 27–30 июня 2012 г., стр. 114–128.