Тут я сподіваюся прояснити свою позицію.
Це 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
будь-якого можливого значення x - не виняток.
Зауважте також, що NULL є дійсними " не-значеннями " (як вважають їх апологети), які можна призначити як значення атрибутів (??) як частина змінних відношень. Тож вони є прийнятними значеннями кожного типу (домену), а не лише типу логічних виразів.
І в цьому була моя думка : NULL
як цінність - «дивний звір». Без евфемізму я вважаю за краще: дурниці .
Я думаю, що ця формулювання набагато чіткіше і менш дискусійне - вибачте за моє слабке знання англійської мови.
Це лише одна з проблем NULL. Краще уникати їх цілком, коли це можливо.
§ ми стурбовані цінностями , тому той факт, що два подарунки - це завжди два різні фізичні об'єкти, не є дійсним запереченням; якщо ви не впевнені, вибачте, це не місце пояснити різницю між значеннями та "об'єктною" семантикою (реляційна алгебра має значення значення семантики з самого початку - див. інформаційний принцип Кодда; я думаю, що деякі реалізатори SQL СУБД роблять Навіть не піклується про загальну семантику).
§§ наскільки мені відомо, це аксіома, прийнята (у тій чи іншій формі, але завжди інтерпретована у 2ВЛ) ще з античності, і саме тому, що настільки інтуїтивно зрозуміла. 3VL (насправді сімейство логіків) є набагато пізнішою розробкою (але я не впевнений, коли вперше був розроблений).
Побічна примітка: якщо хтось буде представляти типи Bottom , Unit та Option як спроби виправдати SQL NULL, я переконаюсь лише після досить детального вивчення, яке покаже, як реалізація SQL з NULLs має систему звукового типу, і, нарешті, уточнить, що насправді є NULL (ці "не зовсім цінні значення").
У подальшому я цитую деяких авторів. Будь-яка помилка чи упущення, ймовірно, є моїм, а не оригінальним авторам.
Джо Селко на SQL NULL
Я бачу, як Джо Селко часто цитується на цьому форумі. Мабуть, він тут дуже шановний автор. Отже, я сказав собі: "що він пише про SQL NULL? Як він пояснює численні проблеми NULL?". Один мій друг має електронну версію SQL Джо Селко для розумних розробок: розширене програмування SQL, 3-е видання . Подивимось.
По-перше, зміст. Найбільше мене вражає, скільки разів згадується NULL та в найрізноманітніших контекстах:
3.4 Арифметичні та NULLs 109
3.5 Перетворення значень в та з NULL 110
3.5.1 Функція NULLIF () 110
6 NULL: відсутні дані в SQL 185
6.4 Порівняння NULLs 190
6.5 NULLs та Logic 190
6.5.1 NULLS в предикатах предикатів 191
6.5.2 Стандарт Рішення SQL 193
6.6 Математика та NULLs 193
6.7 Функції та NULLs 193
6.8 NULLs та мови хостів 194
6.9 Консультації з дизайну для NULLs 195
6.9.1 Уникання NULL з хост-програм 197
6.10 Примітка про кілька значень NULL 198
10.1 IS NULL Predicate 241
10.1. 1 Джерела NULLs 242
...
і так далі. Мені дзвонить "бридкий особливий випадок" для мене.
Я розберуся в деяких із цих випадків із уривками з цієї книги, намагаючись обмежитися істотними з міркувань авторського права. Я думаю, що ці цитати належать до доктрини "добросовісного використання", і вони навіть можуть стимулювати придбання книги - тому сподіваюся, що ніхто не скаржиться (інакше мені потрібно буде видалити більшу частину, якщо не все). Крім того, я утримаюсь від звітних фрагментів коду з тієї ж причини. Вибач за це. Купіть книгу, щоб прочитати про деталізовані міркування.
Наступні номери сторінок між дужками.
НЕ NULL обмеження (11)
Найважливішим обмеженням стовпця є NOT NULL, який забороняє використовувати NULLs у стовпці. Використовуйте це обмеження звичайно, і усувайте його лише тоді, коли у вас є вагомі причини. Це допоможе вам уникнути ускладнень значень 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 (скорочення "негативна нескінченність") як результат.
Джо Челко, цитуючи Девіда МакГоверана та CJ Date:
6 NULL: відсутні дані в SQL (185)
У своїй книзі «Керівництво по Sybase та SQL Server» Девід МакГоверан та CJ Date зазначили: «Це думка цього автора, ніж NULL, принаймні, як це визначено та впроваджено в SQL, - набагато більше проблем, ніж їх варто та їх слід уникати; вони проявляють дуже дивну та непослідовну поведінку і можуть бути багатим джерелом помилок та плутанини. (Зверніть увагу, що ці коментарі та зауваження стосуються будь-якої системи, яка підтримує NULL-стилі у стилі SQL, а не лише до SQL Server.) "
NULL як наркоманія :
(186/187)
В решті цієї книги я закликаю вас не користуватися ними , що може здатися суперечливим, але це не так. Подумайте про НІЛЛ як наркотик; використовуйте його належним чином, і він працює для вас, але зловживайте ним, і це може зіпсувати все. Ваша найкраща політика - уникати NULL, коли ви можете та правильно їх використовувати, коли потрібно.
Моє унікальне заперечення тут - "використовувати їх належним чином", що погано взаємодіє з конкретними способами поведінки.
6.5.1 NULLS в предикатах підзапиту (191/192)
Люди забувають, що підзапит часто приховує порівняння з NULL. Розглянемо ці дві таблиці:
...
Результат буде порожнім. Це контрінтуїтивно , але правильно.
(роздільник)
6.5.2 Стандартні рішення SQL (193)
SQL-92 вирішив деякі проблеми 3VL (тризначна логіка), додавши новий предикат форми:
<умова пошуку> Є [НЕ] ІСТИНА | ПОМИЛКА | НЕЗНАЧЕНО
Але НЕВІДОМЛЕННЕ є самим джерелом проблем, так що CJ Date, у своїй цитованій нижче книзі, рекомендує голову 4.5. Уникнення нулів у SQL :
- Не використовуйте ключове слово UNKNOWN ні в якому контексті.
Прочитайте "ДОПОМОГА" в невідомому , також пов'язаному нижче.
6.8 NULL та мови господарів (194)
Однак ви повинні знати, як обробляються NULL, коли вони повинні бути передані хост-програмі. Жодна стандартна мова хоста, для якої визначено вбудовування, не підтримує NULL, що є ще однією вагомою причиною уникати використання їх у схемі бази даних.
(роздільник)
6.9 Консультації з дизайну для NULL (195)
Добре задекларувати всі свої базові таблиці з обмеженнями NULL на всіх стовпцях, коли можливо. NULL плутають людей, які не знають SQL, а NULL - це дорого.
Заперечення: NULL збиває з пантелику навіть людей, які добре знають SQL, див. Нижче.
(195)
У ІНОЗЕМНИХ КЛЮЧАХ слід уникати NULL. SQL дозволяє це співвідношення «користь сумніву», але це може призвести до втрати інформації в запитах, що передбачають приєднання. Наприклад, враховуючи код номера деталі в Інвентарі, на який посилається як ІНТЕРНЕТ-КЛЮЧ таблицею замовлень, у вас виникнуть проблеми з переліком частин, які мають NULL. Це обов'язкові відносини; ви не можете замовити частину, яка не існує.
(роздільник)
6.9.1 Уникнення NULL з хост-програм (197)
Ви можете уникнути введення NULL в базу даних з програм Хост з деякою дисципліною програмування.
...
- Визначте вплив відсутніх даних на програмування та звітування:
Числові стовпці з NULL є проблемою, оскільки запити, що використовують сукупні функції, можуть дати оманливі результати.
(роздільник)
(227)
SUM () порожнього набору завжди NULL. Однією з найпоширеніших помилок програмування, допущеною при використанні цього фокусу, є написання запиту, який може повернути більше одного рядка. Якщо ви не замислювалися над цим, ви, можливо, написали останній приклад як: ...
(роздільник)
10.1.1 Джерела NULL (242)
Важливо пам’ятати, де можуть виникати NULL. Вони є більш ніж просто можливим значенням у стовпці . Функції сукупності на порожніх множинах, OUTER JOINs, арифметичні вирази з NULL і оператори OLAP повертають NULL. Ці конструкції часто відображаються у вигляді стовпців у VIEW.
(роздільник)
(301)
Інша проблема з NULL виявляється при спробі перетворення предикатів IN у предикати EXISTS.
(роздільник)
16.3 ВСІ функції предиката та екстремуму (313)
Спочатку протипоказано, що ці два предикати не однакові в SQL:
...
Але ви повинні пам'ятати правила для екстремальних функцій - вони викидають усі NULL, перш ніж повертати великі або найменші значення. ВСЕ предикат не скидає NULL, тому ви можете отримати їх у результатах.
(роздільник)
(315)
Однак визначення в стандарті сформульовано негативно, так що NULL отримають користь від сумніву. ...
Як бачите, добре уникати NULLs в УНІКАЛЬНИХ обмеженнях.
Обговорення групи за:
NULL трактуються так, ніби всі вони рівні між собою , і утворюють свою власну групу. Потім кожна група зменшується до одного рядка в новій таблиці результатів, яка замінює стару.
Це означає, що для GROUP BY пункт NULL = NULL не оцінюється як NULL, як у 3VL, але оцінює до TRUE.
Стандарт SQL заплутано:
ЗАМОВЛЕННЯ ПО ТА НУЛЬ (329)
Будь-яке ключове значення сортування, яке NULL, вважається більшим або меншим за значення, яке не є NULL, визначається реалізацією, але ...
... Є продукти SQL, які роблять це в будь-якому випадку.
У березні 1999 року Кріс Фаррар поставив запитання у одного з його розробників, яке змусило його вивчити частину стандарту SQL, яку я вважав зрозумілою . Кріс виявив деякі відмінності між загальним розумінням та фактичним формулюванням специфікації .
І так далі. Я думаю, що це досить.
Дата CJ для NQL з SQL
Дата CJ є більш радикальною щодо NULL: уникайте NULL в SQL, період. Насправді, глава 4 його SQL та реляційної теорії: Як правильно писати код SQL має назву "НЕ ДУПЛІКАЦІЙ, НІ НУЛЛІВ", з підрозділами
"4.4 Що не так з нулями?" та "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 НЕ NULL" не дорівнює "NOT (x IS NULL)", як це стосується 2VL.
...
Усі діалектні SQL, комерційно реалізовані, дотримуються цього підходу 3VL, і, таким чином, вони не лише виявляють ці проблеми, але і мають специфічні проблеми з реалізацією, які залежать від продуктів .