Здесь я надеюсь уточнить мою позицию.
Это NULL = NULL
оценивать FALSE
неправильно. Хакер и Мистер правильно ответили NULL
. Вот почему. Дуэйн Кристенсен написал мне в комментарии Скотту Айви :
Так как это декабрь, давайте использовать сезонный пример. У меня есть два подарка под елкой. Теперь скажите мне, если у меня есть два одинаковых или нет.
Они могут быть разными или равными, вы не знаете, пока не откроете оба подарка. Кто знает? Вы пригласили двух людей, которые не знают друг друга и оба сделали вам один и тот же подарок - редкий, но не невозможный § .
Таким образом, вопрос: эти два НЕИЗВЕСТНЫХ представляют одинаково (равно, =)? Правильный ответ: НЕИЗВЕСТНО (то есть NULL
).
Этот пример был призван продемонстрировать, что «.. ( false
или null
, в зависимости от вашей системы) ..» является правильным ответом - это не так, только NULL
правильно в 3VL (или вы можете принять систему, которая дает неправильные ответы? )
Правильный ответ на этот вопрос должен подчеркнуть следующие два момента:
- трехзначная логика (3VL) нелогична (см. бесчисленное множество других вопросов по этому вопросу в Stackoverflow и на других форумах, чтобы убедиться в этом);
- СУБД на основе SQL часто не уважают даже 3VL, иногда они дают неправильные ответы (как утверждают первоначальные авторы, SQL Server в этом случае).
Поэтому я повторяю: SQL не имеет смысла заставлять интерпретировать рефлексивное свойство равенства, которое утверждает, что:
for any x, x = x
§§ (на простом английском языке: независимо от вселенной дискурса, «вещь» всегда равна себе ).
.. в 3VL ( TRUE
, FALSE
, NULL
). Ожидание людей будет соответствовать 2VL ( TRUE
, FALSE
, что даже в SQL справедливо для всех других значений), то есть x = x
всегда вычисляться TRUE
для любого возможного значения х - без исключений.
Также обратите внимание, что значения NULL являются допустимыми « ненулевыми значениями » (как утверждают их апологеты), которые можно назначать как значения атрибутов (??) как часть переменных отношения. Таким образом, они являются приемлемыми значениями каждого типа (домена), а не только типа логических выражений.
И это была моя точка зрения : NULL
как ценность, это «странный зверь». Без эвфемизма я предпочитаю говорить: ерунда .
Я думаю, что эта формулировка намного более ясна и менее спорна - извините за мое плохое знание английского языка.
Это только одна из проблем NULL. Лучше избегать их полностью, когда это возможно.
§ мы обеспокоены ценностями здесь, поэтому тот факт, что два подарка всегда являются двумя разными физическими объектами, не является обоснованным возражением; если вы не уверены, извините, это не то место, чтобы объяснить разницу между значением и семантикой «объекта» (реляционная алгебра имеет семантику значения с самого начала - см. информационный принцип Кодда; я думаю, что некоторые разработчики СУБД SQL не даже не заботится об общей семантике).
§§ насколько мне известно, это аксиома, принятая (в той или иной форме, но всегда интерпретируемая в 2VL) с древности и именно потому , что она настолько интуитивна. 3VLs (в действительности это семейство логик) - это гораздо более свежая разработка (но я не уверен, когда она была впервые разработана).
Примечание: если кто-то представит типы Bottom , Unit и Option как попытки оправдать значения NULL в SQL, я буду убежден только после довольно подробного изучения, которое покажет, как реализации SQL с NULL имеют систему звукового типа, и, в конце концов, прояснит, что такое NULL (эти «значения-не-совсем-значения»).
В дальнейшем я процитирую некоторых авторов. Любая ошибка или упущение, вероятно, принадлежит мне, а не авторам оригинала.
Джо Селко о SQL NULL
Я вижу, Джо Селко часто цитируется на этом форуме. Видимо, он очень уважаемый автор здесь. Итак, я сказал себе: «что он пишет о SQL NULL? Как он объясняет NULL многочисленные проблемы?». У одного из моих друзей есть электронная версия SQL Джо Селко для умных людей: продвинутый SQL-программирование, 3-е издание . Посмотрим.
Во-первых, оглавление. Больше всего меня поражает количество упоминаний NULL в самых разных контекстах:
3.4 Арифметика и NULL 109
3.5 Преобразование значений в и из NULL 110
3.5.1 NULLIF () Функция 110
6 NULL: отсутствуют данные в SQL 185
6.4 Сравнение NULL 190 190
NULL и логики 190
6.5.1 NULL в подзапросе Предикаты 191
6.5.2 Стандарт Решения SQL 193
6.6 Math и NULL 193
6.7 Функции и NULL 193
6.8 NULL и языки хоста 194
6.9 Советы по проектированию для NULL 195
6.9.1 Избегание NULL из программ хоста 197
6.10 Замечание о множественных значениях NULL 198
10.1 IS NULL Predicate 241
10.1. 1 Источники NULL 242
...
и так далее. Это звучит как "неприятный особый случай" для меня.
Я расскажу о некоторых из этих случаев с выдержками из этой книги, пытаясь ограничиться основным, из соображений авторского права. Я думаю, что эти цитаты подпадают под доктрину «добросовестного использования», и они могут даже стимулировать покупку книги - так что я надеюсь, что никто не будет жаловаться (в противном случае мне придется удалить большую часть, если не все). Кроме того, по той же причине я не буду сообщать фрагменты кода. Извини за это. Купите книгу, чтобы прочитать о данных рассуждениях.
Номера страниц между круглыми скобками в дальнейшем.
Ограничение NOT NULL (11)
Наиболее важным ограничением столбца является NOT NULL, которое запрещает использование NULL в столбце. Используйте это ограничение регулярно и снимайте его только тогда, когда у вас есть веская причина. Это поможет вам избежать осложнений значений NULL при выполнении запросов к данным.
Это не ценность ; это маркер, который содержит место, куда может пойти значение.
Опять эта ерунда "ценность, но не совсем ценность". Остальное мне кажется вполне разумным.
(12)
Короче говоря, NULL вызывают много нерегулярных функций в SQL, которые мы обсудим позже. Лучше всего запоминать ситуации и правила для NULL, когда вы не можете их избежать.
По поводу SQL, NULL и бесконечности:
(104) ГЛАВА 3: ЧИСЛЕННЫЕ ДАННЫЕ В SQL
SQL не принял модель IEEE для математики по нескольким причинам.
...
Если бы правила IEEE для математики были разрешены в SQL, то нам понадобились бы правила преобразования типов для бесконечного числа и способ представления бесконечного точного числового значения после преобразования. У людей достаточно проблем с NULL, поэтому давайте не будем туда идти.
Реализации SQL не определились с тем, что на самом деле означает NULL в определенных контекстах:
3.6.2. Экспоненциальные функции (116)
Проблема в том, что логарифмы не определены, когда (x <= 0). Некоторые реализации SQL возвращают сообщение об ошибке, некоторые возвращают NULL и DB2 / 400; версия 3, выпуск 1 вернул * NEGINF (сокращение от «минус бесконечность») в качестве результата.
Джо Селко цитирует Дэвида Макговерана и СиДжея Дейта:
6 NULL: отсутствуют данные в SQL (185)
В своей книге «Руководство по Sybase и SQL Server» Дэвид МакГоверан и СиДжей Дейт сказал: «По мнению этого автора, NULL, по крайней мере в том виде, как они определены и реализованы в SQL, в настоящее время представляют собой гораздо больше проблем, чем их стоит, и их следует избегать; они демонстрируют очень странное и непоследовательное поведение и могут стать источником ошибок и путаницы. (Обратите внимание, что эти комментарии и критические замечания относятся к любой системе, поддерживающей значения NULL в стиле SQL, а не только к SQL Server). »
NULL как наркомания :
(186/187)
В остальной части этой книги я буду убеждать вас не использовать их , что может показаться противоречивым, но это не так. Думайте о NULL как о наркотике; используйте это правильно, и это работает для вас, но злоупотребляйте этим, и это может разрушить все. Ваша лучшая политика - избегать значений NULL, когда вы можете, и использовать их правильно, когда это необходимо.
Мое единственное возражение здесь состоит в том, чтобы «использовать их правильно», что плохо взаимодействует с определенным поведением реализации.
6.5.1 NULL в предикатах подзапроса (191/192)
Люди забывают, что подзапрос часто скрывает сравнение с NULL. Рассмотрим эти две таблицы:
...
Результат будет пустым. Это нелогично , но правильно.
(разделитель)
6.5.2 Стандартные решения SQL (193)
SQL-92 решил некоторые проблемы 3VL (трехзначной логики), добавив новый предикат в форме:
<условие поиска> IS [NOT] TRUE | ЛОЖЬ | НЕИЗВЕСТНЫЙ
Но UNKNOWN сам по себе является источником проблем, поэтому CJ Date в своей книге, цитируемой ниже, рекомендуется в главе 4.5. Как избежать пустых значений в SQL :
- Не используйте ключевое слово НЕИЗВЕСТНО в любом контексте.
Прочитайте «ВНУТРИ» на НЕИЗВЕСТНОМ, также связанном ниже.
6,8 NULL и языки хоста (194)
Однако вы должны знать, как обрабатываются значения NULL, когда они должны быть переданы хост-программе. Ни один стандартный хост-язык, для которого определено встраивание, не поддерживает NULL, что является еще одной веской причиной избегать их использования в схеме базы данных.
(разделитель)
6.9. Советы по проектированию для NULL (195)
Рекомендуется объявлять все ваши базовые таблицы с ограничениями NOT NULL для всех столбцов, когда это возможно. NULL сбивают с толку людей, которые не знают SQL, а NULL стоят дорого.
Возражение: NULL сбивает с толку даже людей, которые хорошо знают SQL, см. Ниже.
(195)
В ИНОСТРАННЫХ КЛЮЧАХ следует избегать NULL. SQL допускает это отношение «выгоды от сомнений», но может привести к потере информации в запросах, которые включают в себя объединения. Например, учитывая код номера детали в Inventory, на который ссылается таблица FOREIGN KEY таблицы Orders, у вас будут проблемы с получением списка деталей, имеющих NULL. Это обязательные отношения; Вы не можете заказать деталь, которая не существует.
(разделитель)
6.9.1. Избегание пустых значений из программ хоста (197)
Вы можете избежать помещения NULL в базу данных из программ Host с некоторой дисциплиной программирования.
...
- Определите влияние отсутствующих данных на программирование и создание отчетов.
Числовые столбцы с NULL являются проблемой, поскольку запросы, использующие агрегатные функции, могут давать ошибочные результаты.
(разделитель)
(227)
SUM () пустого набора всегда равно NULL. Одна из наиболее распространенных ошибок программирования, допущенных при использовании этого трюка, заключается в написании запроса, который может вернуть более одной строки. Если вы не думали об этом, вы могли бы написать последний пример как ...
(разделитель)
10.1.1 Источники NULL (242)
Важно помнить, где могут быть значения NULL. Они больше, чем просто возможное значение в столбце . Агрегатные функции для пустых множеств, OUTER JOIN, арифметические выражения с NULL и операторы OLAP возвращают NULL. Эти конструкции часто отображаются в виде столбцов в VIEW.
(разделитель)
(301)
Другая проблема с NULL обнаруживается при попытке преобразовать предикаты IN в предикаты EXISTS.
(разделитель)
16.3. Функции предиката и экстремума ALL (313)
Поначалу нелогично, что эти два предиката не совпадают в SQL:
...
Но вы должны помнить правила для функций экстремумов - они отбрасывают все NULL перед возвратом больших или меньших значений. Предикат ALL не пропускает NULL, поэтому вы можете получить их в результатах.
(разделитель)
(315)
Однако определение в стандарте сформулировано отрицательно, так что значения NULL получают преимущество сомнения. ...
Как видите, хорошей идеей является избегать значений NULL в ограничениях UNIQUE.
Обсуждение GROUP BY:
NULL обрабатываются так, как будто все они равны друг другу , и образуют свою собственную группу. Затем каждая группа сокращается до одной строки в новой таблице результатов, которая заменяет старую.
Это означает, что для предложения GROUP BY NULL = NULL не оценивается как NULL, как в 3VL, но оценивается как TRUE.
Стандарт SQL сбивает с толку:
ORDER BY и NULL (329)
То, считается ли значение ключа сортировки, равное NULL, большим или меньшим, чем значение, отличное от NULL, определяется реализацией, но ...
... Есть продукты SQL, которые делают это в любом случае.
В марте 1999 года Крис Фаррар поднял вопрос от одного из своих разработчиков, который заставил его изучить часть стандарта SQL, которую, как мне показалось, я понял . Крис обнаружил некоторые различия между общим пониманием и реальной формулировкой спецификации .
И так далее. Я думаю, что достаточно Celko.
Дата CJ на пустых значениях SQL
CJ Date более радикально относится к NULL: избегайте NULL в SQL, точка. Фактически, глава 4 его теории SQL и реляционной теории: как писать точный код SQL называется «NO DUPLICATES, NO NULLS», с подразделами
«4.4. Что не так с NULL?» и «4.5 Избегание пустых значений в SQL» (перейдите по ссылке: благодаря Google Книгам вы можете читать некоторые страницы в режиме онлайн).
Фабиан Паскаль о SQL NULL
Из практических вопросов по управлению базами данных - справочник для практикующего мышления (нет выдержек в Интернете, извините):
10.3 Практические последствия
10.3.1. SQL NULL
... SQL страдает от проблем, присущих 3VL, а также от многих причуд, сложностей, противоречивости и прямых ошибок [10, 11]; среди них есть следующие:
- Агрегатные функции (например, SUM (), AVG ()) игнорируют NULL (за исключением COUNT ()).
- Скалярное выражение в таблице без строк неправильно оценивается как NULL вместо 0.
- Выражение «NULL = NULL» оценивается как NULL, но на самом деле недопустимо в SQL; тем не менее ORDER BY обрабатывает значения NULL как равные (независимо от того, предшествуют они или следуют «обычным» значениям, остается поставщик СУБД).
- Выражение «x IS NOT NULL» не равно «NOT (x IS NULL)», как в случае 2VL.
...
Все коммерчески реализуемые диалекты SQL следуют этому подходу 3VL, и, таким образом, они не только демонстрируют эти проблемы, но также имеют специфические проблемы реализации, которые различаются в разных продуктах .