ЗАСОБИ підтримки невизначених значень (NULL) і тризначної логіки в мові SQL

Підтримка невизначених значень (NULL) і тризначної логіки в мові SQL відображає весь широкий спектр підходів, описаних у попередніх розділах Так, наприклад, коли в мові SQL умова WHERE застосовується до деякої таблиці т, при цьому виключаються з розгляду всі рядки таблиці т, для яких вказане в конструкції WHERE вираз приймає значенняfalse або unk (Тобто не true) Аналогічним чином, коли до результату виконання деякої операції групування, представленому таблицею G, застосовується конструкція HAVING, ІЗ подальшого розгляду виключаються всі групи кортежів таблиці G, для яких вказане в конструкції HAVING вираз приймає значення false або unk (Тобто не true)10 З цього випливає, що ми просто звернули увагу читача на деякі засоби підтримки тризначною логіки, характерні для мови SQL як такого, а що не є невідємною частиною описаного вище підходу, заснованого на використанні тризначною легікі

9 Зверніть увагу, що для цього НЕ використовується невизначене значення (NULL) У реальному світі ніякого поняття невизначеного значення взагалі не існує ([1912])

10 У мові SQL згрупованої називається таблиця, яка створюється в результаті виконання конструкції GROUP BY (можливо, неявній) А після виконання відповідного оператора SELECT така таблиця зводиться до звичайної, несгруппірованних таблиці

Примітка Усі наслідки підтримки невизначених значень (NULL) У мові SQL оцінити дуже складно фактично, хоча вже було сказано, що в мові SQL в цілому підтримується тризначна логіка, істина полягає в тому, що в питаннях цієї підтримки допущені численні помилки, як незабаром буде показано Додаткову інформацію можна знайти в офіційних документах стандарту SQL [423] і в навчальному виданні [420]

Типи даних

Як вже було показано в розділі 4, в мові SQL передбачений вбудований тип BOOLEAN (він був введений в стандарт в 1999 році, але в даний час його підтримують лише деякі продукти, якщо взагалі такі є) Передбачені звичайні логічні оператори AND, OR і NOT, і логічні вирази можуть бути присутніми в будь-якому місці, де зазвичай допускається наявність скалярних виразів Але, як зазначено в даній чолі, тепер визначено три істиннісних значення, а не два (відповідними літералами є TRUE, FALSE і UNKNOWN), але незважаючи на цей факт, тип BOOLEAN включає тільки два значення, а не три Таким чином, невідоме {unknown) истинностное значення зовсім неправильно представлено за допомогою невизначеного значення NULL Нижче описані деякі наслідки з цього факту

■ Присвоєння значення UNKNOWN змінної в типу BOOLEAN фактично одно сильно присвоюванню цієї змінної невизначеного значення

■ Після такого присвоювання операція порівняння в = UNKNOWN не дає в результа ті true (Або, швидше, TRUE) замість цього результатом стає невизначене значення

■ Насправді, операція порівняння в = UNKNOWN завжди призводить до підлоги чению невизначеного значення, незалежно від значення у Справа в тому, що та кая операція логічно еквівалентна операції порівняння в = NULL (Яка не розглядається як синтаксично допустима)

Для того щоб зрозуміти серйозність вказаних недоліків, необхідно звернутися до аналогії з числовим типом, в якому для представлення нуля використовувалося б невизначене значення замість нульового

Тепер припустимо, що т – нескалярний тип або структурований тип (і в даному контексті не грає ролі, чи розглядаються структуровані типи як скалярні або нескалярние) Щоб уточнити опис, припустимо, що т являє собою саме строковий тип, а змінна V є змінною типу т У такому разі, безумовно, існує логічне відмінність між самої змінної V, що має невизначений значення, і змінної V, що має щонайменше один компонент (тобто поле), який містить невизначене значення Дійсно, сама змінна V не обовязково має невизначене значення , навіть якщо невизначеними є всі її компоненти Проте, мабуть, обгрунтованим є твердження (хоча в стандарті немає явних вказівок на цей рахунок), що якщо значення v не визначено, то всі компоненти цієї змінної також розглядаються як мають невизначене значення Тому, якщо значення V не є невизначеним, але ця

11 Насправді, в мові SQL і ця ситуація трактується неправильно див опис конструкції IS [NOT] NULL в підрозділі Логіческіевираженія.

змінна містить щонайменше один невизначений компонент, то в результаті порівняння V = V буде отримано невизначений значення і, тим не менш, вираз V IS NULL дорівнюватиме FALSE Але, загалом, можна хоча б стверджувати, що якщо вираз ((V = V) is NOT TRUE) is TRUE одно TRUE, то змінна vявляется або невизначеною, або містить невизначений компонент

Базові таблиці

Як описано в розділі 66 глави 6, для стовпців у базових таблицях зазвичай передбачені відповідні значення, що застосовуються за замовчуванням вони часто визначаються (явно або неявно), як невизначені значення NULL Більш того, стовпці в таблицях завжди дозволяють використання невизначених значень, якщо умова заборони їхнього використання не буде вказано явно (наприклад, у вигляді фрази NOT NULL)

Із зазначеного вище випливає, що якщо ми твердо дотримуємося декларованих принципів, то дійсно зобовязані здавати ключове слово NOT NULL, явно чи неявно, для кожного стовпця базовий таблиці в кожному прикладі SQL, наведеному вище в даній книзі Але, щонайменше, ця вимога буде дотримуватися у всіх прикладах SQL починаючи з цього моменту Однак слід зазначити, що застосування ключового слова NOT NULL неявно мається на увазі для будь-якого стовпця, зазначеного в специфікації PRIMARY KEY

Табличні вираження

Нагадаємо зауваження з глави 8 (розділ 87) про те, що явна підтримка операції JOIN була введена в стандарт мови SQL в 1992 році Більш того, якщо перед ключовим словом JOIN вказаний один з префіксів LEFT, RIGHT або FULL (С необовязковим ключовим словом OUTER в кожному випадку), що розглядається зєднання є зовнішнім Нижче наведено кілька прикладів

S LEFT JOIN SP ON SS# = SPS# S LEFT JOIN SP USING ( S# ) S LEFT NATURAL JOIN SP

Три наведених вираження еквівалентні, але перше призводить до створення таблиці з двома ідентичними стовпцями s #, а друге і третє – таблиці з одним таким стовпцем

Мова SQL підтримує також апроксимацію зовнішнього обєднання, яку називають обєднуючим зєднанням (Ця операція була введена в специфікації SQL: 1992, але повинна бути видалена в SQL: 2003) Однак детальне обговорення цього питання виходить за рамки даної глави

Логічні вирази

Не дивно те, що в мові SQL логічні вирази відчувають сильний вплив невизначених значень і тризначною логіки Зупинимося на розгляді лише декількох найбільш важливих окремих випадків, які описані нижче

■&nbsp Перевірка наявності невизначеного значення У мові SQL передбачено два спеціальні оператора порівняння, IS NULL і IS NOT NULL, призначених для перевірки наявності або відсутності невизначених значень Синтаксис використання цих операторів показаний нижче

&ltrow value constructor IS   [  NOT  ]    NULL

Якщо у виразі&ltrow  value  constructor  з визначенням конструктора значення рядка конструюється рядок зі ступенем один, то в мові SQL це вираження розглядається так, як ніби воно фактично вказує на значення, що міститься в цьому рядку, а не на саму рядок як таку в іншому випадку це вираз розглядається як вказує на рядок Але в останньому випадку вважається, що рядок має невизначене значення тоді і тільки тоді, коли кожен її компонент є невизначеним, а не має невизначеного значення – тоді і тільки тоді, коли кожен її компонент має значення, відмінне від невизначеного Одним наслідком цієї помилки є те, що якщо r – рядок з двома компонентами, то вирази r IS NOT NULL і NOT (r IS NULL) не є еквівалентними перше з них еквівалентно висловом cl is NOT NULL AND c2 is NOT NULL, а друге – висловом з 1 IS NOT NULL OR c2 IS NOT NULL Ще одним наслідком із зазначеного є те, що якщо рядок r одночасно включає і компоненти з невизначеними, і компоненти з певними значеннями, то сама рядок r, безумовно, не може розглядатися ні як що має невизначений значення, ні як що має певне значення

■&nbsp&nbsp Перевірка наявності значень true, false і unknown Якщо р – це укладену в круглі дужки логічне вираження (фактично в деяких випадках можна обійтися без круглих дужок, але вони ніколи не завадять), то наступні оператори також є логічними виразами

р IS [NOT] TRUE р IS [NOT] FALSE p IS [NOT] UNKNOWN

Значення цих виразів показані в наведеній нижче таблиці істинності

Зверніть увагу на те, що вирази р IS NOT TRUE і NOT p не є еквівалентними

Примітка Вираз р IS UNKNOWN відповідає описаному вище оператору MAYBE (р) Якщо вважати, що в мові SQL для подання значенняunk використовуються невизначені значення, то даний вираз еквівалентно також висловом р IS NULL

■ Умови EXISTS Оператор EXISTS мови SQL не є аналогічним квантору існування в тризначній логіці, оскільки він завжди повертає значення true абоfalse,  але неunk,  навіть якщоunk  – Логічно правильну відповідь А саме, цей оператор повертає false, якщо таблиця, задана в ньому в якості

фактичного параметра, порожня, і true в іншому випадку (Тому він іноді повертає true, тоді як ІПК- логічно правильну відповідь) Додаткова інформація на цю тему приведена в [196]

■ Умови UNIQUE Неформально кажучи, умови UNIQUE служать для перевірки того, що вказана таблиця не містить дублікатів рядків (саме так) Точніше, вираз UNIQUE (&lt table exp&gt) повертає true, якщо таблиця, позначена за допомогою параметра < table exp&gt, не включає двох різних рядків, скажімо, rl і r2, таких що операція порівняння rl = r2 повертає true в іншому випадку даний вираз повертає false Тому UNIQUE, як і EXISTS, іноді повертає true, навіть коли ІПК – логічно правильну відповідь

■ Умови DISTINCT Умови DISTINCT, взагалі кажучи, призначені для про перевірки того, чи не є два рядки дублікатами один одного Позначимо дві рас сматривать рядки як Left і Right рядка Left і Right повинні мати однаковий ступінь, скажімо, п Припустимо, що i-ми компонентами Left і Right, відповідно, є Li і Ri (i = 1, 2, .., п) всі компоненти Li і Ri повинні бути такими, що операція порівняння Li = Ri є дійсною У такому випадку наступний вираз

Left IS DISTINCT FROM Right

повертає false, якщо для всіх i або операція порівняння Li = Ri повертає true, або обидва значення, Li і Ri, є невизначеними в іншому випадку вказане вираз повертає true

Інші скалярні вирази

І знову розглянемо лише кілька важливих окремих випадків, які описані нижче

■ Літерали. Ключове слово NULL може іноді використовуватися як свого роду литеральное уявлення невизначеного значення (наприклад, в операторі INSERT), але не у всіх контекстах в стандарті SQL зазначено, що ключове слово NULL .. може застосовуватися для позначення невизначеного значення .. в неко торих контекстах, [але] повсюдне використання цього литерала не допускається [423] Зокрема, слід зазначити, що ключове слово NULL не можна застосовувати для позначення операнда простого оператора порівняння наприклад, вираз WHERE х = NULL є неприпустимим (правильна форма, безумовно,

WHERE X  IS  NULL)

■ COALESCE Оператор COALESCE – це аналог запропонованого автором оператора IF_UNK в мові SQL Точніше, вираз COALESCE (x, y, .., z) повертає невизначене значення, якщо всі його параметри х, у, , Z повертають не визначене значення в іншому випадку воно повертає перший свій операнд, відмінний від невизначеного значення

■ Агрегує оператори Агрегує оператори SQL (SUM, AVG і тд) не дей ствуют відповідно до правил для скалярних операторів, описаними в раз справі 192, а замість цього просто ігнорують всі невизначені значення своїх фактичних параметрів (не рахуючи вираження COUNT (*), в якому неопреде лені значення розглядаються так, як якщо б вони були певними

значеннями) Крім того, якщо виявилося, що фактичний параметр такого оператора відповідає порожній множині, то оператор COUNT повертає нуль, а всі інші оператори – невизначене значення (Як було зазначено в розділі 8, така організація функціонування логічно не обгрунтована, але мова SQL визначений саме так)

■ Скалярні підзапити. Якщо скалярний вираз фактично являє собою табличне вираз, укладену в круглі дужки, наприклад, (SELECT

SCITY FROM S WHERE S S # = S # (S1)), TO У звичайних умовах це Табличне вираз повинен давати в результаті таблицю, що містить точно один стовпець і точно один рядок Тому значенням цього скалярного вираження повинно служити єдине скалярне значення, що міститься всередині цієї таблиці Але якщо результатом обчислення даного табличного вираження стає таблиця з одним стовпцем, взагалі не містить рядків, то в мові SQL значення скалярного вираження задається як невизначений

Ключі

Різні варіанти взаємодії між невизначеними значеннями і ключами в мові SQL можна в цілому описати, як показано нижче

■ Потенційні ключі Припустимо, що з – стовпець, який є компонентом деякого потенційного ключа до деякої базової таблиці Як було зазначено але раніше в цьому розділі, якщо до – первинний ключ, то згідно специфікації SQL наявність будь-яких невизначених значень в стовпці з не допускається (іншими словами, специфікація SQL вимагає дотримання правила цілісності сутності) А якщо до не є первинним ключем, то специфікація SQL до пускає наявність у стовпці С будь-якої кількості невизначених значень (але, ра зумеется, за умови, що ніякі дві різні рядки не містять однакового

У звязку зі сказаним, автор пропонує поміркувати над наведеною нижче трохи відредагованій цитатою з [420]

“Припустимо, що к2 – нове значення для К, яке певний користувач намагається ввести за допомогою операції INSERT або UPDATE .. Ця операція INSERT або UPDATE буде відкинута, якщо к2 збігається з деяким іншим значенням К, скажімо, kl, яке вже існує в таблиці .. Але що мається на увазі під тим, що два значення, kl і к2, збігаються Виявляється, що ніякі два з трьох таких тверджень не є еквівалентними:

1 kl і к2 є однаковими з точки зору операції порівняння

2 kl і к2 є однаковими з точки зору забезпечення унікальності потен альних ключів

3 kl і к2 є однаковими з точки зору усунення дублікатів

Затвердження 1 визначено відповідно до правил тризначною логіки, затвердження 2 визначено відповідно до правил для умови UNIQUE, а твердження 3 сформульоване відповідно з визначенням дублікатів, наведеному в розділі 192 Зокрема, якщо обидва значення, kl і к2, є невизначеними, то перевірка,

виконувана відповідно з твердженням 1, призводить до отримання unk, з твердженням 2 – false і з твердженням 3 – true&quot.

■ Зовнішні ключі Правила, що визначають, що мається на увазі під збігом даного значення зовнішнього ключа з відповідному йому значенням потенційного ключа в присутності невизначених значень, є досить складними У цьому розділі докладні відомості про це не розглядаються Примітка Наявність невизначених значень відображено також у визначеннях посилальних дій (CASCADE, SET NULL І ТД), зазначених у конструкціях ON DELETE і ON UPDATE (Крім того, підтримується ключове слово SET DEFAULT, що має очевидну інтерпретацію) І в цьому випадку застосовуються правила є досить складними і їх опис виходить за рамки цієї книги додаткові відомості наведені в [420]

Впроваджені оператори SQL

■&nbsp&nbsp&nbsp&nbsp Індикаторні змінні Розглянемо наступний приклад впровадженого висловлю ня SQL (Він вже розглядався в розділі 4 при описі однострочного операто ра SELECT)

EXEC SQL SELECT STATUS, CITY INTO

:RANK, :TOWN FROM S WHERE S# = S# ( :GIVENS# )

Припустимо, що для деяких постачальників атрибут STATUS може містити невизначене значення Тоді виконання наведеного вище оператора SELECT завершиться невдачею, якщо в обраному кортежі атрибут STATUS міститиме невизначене значення (в змінну SQLSTATE буде поміщений код помилки 22002) У загальному випадку, коли існує ймовірність, що обиране значення може виявитися невизначеним, для даного атрибута користувач повинен вказати, крім цільової, ще й індикаторну змінну Приклад визначення індикаторної змінної наведено нижче

EXEC SQL SELECT STATUS, CITY

INTO :RANK INDICATOR :RANKIND, :TOWN FROM S

WHERE S# = S# ( :GIVENS# )

IF RANKIND = -1 THEN / * Значення STATUS було невизначеним * /

… END IF

Якщо значення, яке потрібно вибрати, є невизначеним і для даного атрибута задана індикаторна змінна, то в цю змінну буде поміщено значення -1 (значення, що поміщається в цільову змінну, залежить від реалізації)

■&nbsp&nbsp&nbsp&nbsp Впорядкування Для впорядкування рядків, отриманих в результаті обчислення таб особистого вираження, у визначенні курсору використовується конструкція ORDER BY (Безумовно, вона може використовуватися і при введенні інтерактивних запитів) Виникає питання: Який відносний порядок двох скалярних значень А і B, якщо або А є невизначеним значенням, або в є невизначений вим значенням, або обидва вони одночасно є невизначеними значе нями . У стандарті мови SQL на це питання даються наведені нижче відповіді

1 У процесі упорядкування все невизначені значення вважаються рівними одне іншому

2 У процесі упорядкування все невизначені значення вважаються або біль шими всіх визначених значень, або меншими всіх визначених значе ний (реальний вибір однієї з цих можливостей залежить від конкретної реа лізації)

191 РЕЗЮМЕ

У цій главі обговорювалася проблема відсутньої інформації, а також вибраний в даний час (хоча і дуже невдалий) підхід до її вирішення, що базується на використанні невизначених значень і тризначною логіки Було показано, що невизначене значення насправді значенням не є, хоча так і прийнято говорити (наприклад, говорять, що деякий атрибут кортежу містить значення NULL) Результатом будь-яких операцій порівняння, в яких один з операндів містить невизначений значення, служить третій істиннісне значення, unknown (Скорочено – ІПК), тому така логіка називається тризначною Крім того, зазначалося, що, принаймні, концептуально може існувати багато різних видів невизначених значень, зокрема, в якості зручного (і явного) скорочення для того різновиду невизначених значень, коли значення невідомо, було введено скорочення UNK

Далі досліджувався вплив використання величини UNK і тризначної логіки на обчислення логічних операторів AND, OR і NOT (А також MAYBE), кванторів EXISTS іFORALL,  інших скалярних операторів,реляційних операторів та операторів поновлення INSERT і UPDATE У цьому розділі були представлені операторIS_UNK (Перевіряючий наявність величини UNK), оператор IF_UNK (Для перетворення величини UNK в значення, відмінне від UNK) Додатково обговорювалася проблема дублікатів кортежів з урахуванням присутності величини UNK Крім того, було особливо підкреслено, що величина UNK І логічне значення ІПК – це не одне і те ж

Потім розглядалися деякі слідства викладених ідей Ьило показано, що деякі еквівалентності двухзначной логіки не є еквівалентності в тризначній логіці В результаті користувачі і програми-оптимізатори СУБД можуть здійснювати помилки в процесі перетворення виразів Але навіть без урахування названих помилок тризначна логіка володіє одним дуже серйозним недоліком – вона не відповідає реальному світу, тобто результати операцій в тризначній логіці не завжди є правильними в реальному світі

Потім були описані наслідки присутності невизначених значень в первинних і зовнішніх ключах (Зокрема, згадувалися правила підтримки цілісності сутностей і переглянуте правило підтримки посилальної цілісності) Було зроблено відступ для опису зовнішнього зєднання Зазначалося, що автор не є прихильником прямої підтримки цієї операції (принаймні, в її звичайному сенсі), так як вважає, що існує краще рішення тієї проблеми, яку покликане вирішувати зовнішнє зєднання Зокрема, автор пропонує використовувати підхід на основі атрибутів зі значеннями у вигляді відносин Також коротко розглядалася можливість існування і інших зовнішніх операцій, зокрема операції зовнішнього обєднання

У даній главі проаналізовано підтримка викладених ідей в стандарті мови

SQL У трактуванні проблеми відсутності інформації в стандарті мови SQL широко

використовується тризначна логіка, але це трактування вносить безліч ускладнень, опис яких виходить за рамки цієї книги І дійсно, на додаток до власних недоліків тризначною логіки ([196], [1910]) стандарт мови SQL вносить свої недоліки Більш того, ці додаткові недоліки, по суті, виступають як фактори уповільнення процесу оптимізації (більш докладно це обговорюється в розділі

188глави 18)

На закінчення спробуємо коротко сформулювати деякі додаткові зауваження

■ Читач, безумовно, погодиться, що проблеми, повязані з використанням невизначених значень і тризначної логіки, описані в книзі кілька стисло Проте, тут представлений досить великий обсяг матеріалу, що дозволяє переконатися в тому, що переваги, що досягаються при використанні тризначною логіки, більш ніж сумнівні

■ Слід також зазначити, що навіть якщо читач не надто переймається проблемами, повязаними з використанням тризначною логіки, йому все ж рекомендується уникати застосування відповідних можливостей мови SQL через згадуваних вище додаткових недоліків.

■ Виходячи з усього сказаного, автор рекомендує користувачам СУБД повністю ігнорувати всі засоби підтримки тризначною логіки, надані розробником обраного ним продукту Замість них доцільно використовувати більш строгий механізм спеціальних значень (Завдяки своїй строгості залишається в рамках двухзначной логіки) Подібна схема детально описана в [1912]

■ Нарешті, повторимо важливе твердження, сформульоване в розділі 193 Говорячи вельми неформально, якщо значення даного атрибута даного кортежу даного відношення є невизначеним, то в цій позиції атрибута взагалі нічого не міститься Це означає, що даний атрибут вже не є атрибутом, що цей кортеж вже не є кортежем, що це ставлення вже не є ставленням і для обгрунтування наших подальших дій (якими б вони не були) використовувати математично строгу реляционную теорію вже не можна

Джерело: Дейт К Дж, Введення в системи баз даних, 8-е видання: Пер з англ – М: Видавничий дім «Вільямс», 2005 – 1328 с: Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*