- •Глава 13. Семантическое моделирование
- •Часть III Проектирование базы данных
- •Часть IV
- •14.1. Введение
- •14.2. Транзакции
- •14.3. Восстановление транзакции
- •14.4. Восстановление системы
- •14.5. Восстановление носителей
- •14.6. Двухфазная фиксация
- •14.7. Поддержка языка sql
- •14.8. Резюме
- •15.1. Введение
- •15.2. Три проблемы параллельности
- •15.3. Блокировка
- •15.4. Устранение трех проблем параллельности
- •15.5. Взаимная блокировка
- •15.6. Упорядочиваемость
- •15.7. Уровни изоляции
- •15.8. Блокировка намерения
- •15.9. Средства языка sql
- •15.10. Резюме
- •Часть V
- •16.1. Введение
- •16.2. Избирательная схема управления доступом
- •16.3. Мандатная схема управления доступом
- •16.4. Статистические базы данных
- •16.5. Шифрование данных
- •16.6. Средства языка sql
- •16.7. Резюме
- •17.1. Введение
- •17.2. Пример выполнения оптимизации
- •17.3. Оптимизация запросов
- •17.4. Преобразование выражений
- •17.5. Статистические показатели базы данных
- •17.6. Стратегия по принципу "разделяй и властвуй"
- •17.7. Реализация реляционных операторов
- •17.8. Резюме
- •18.1. Введение
- •18.2. Обзор концепции трехзначной логики
- •18.3. Некоторые следствия изложенной схемы
- •18.4. Отсутствующие значения и ключи
- •18.5. Внешнее соединение
- •18.6. Специальные значения
- •18.7. Поддержка неопределенных значений в языке sql
- •18.8. Резюме
- •Глава 19
- •19.1. Введение
- •19.2. Иерархия типов
- •19.3. Полиморфизм и заменимость
- •19.4. Переменные и операция присвоения
- •19.5. Специализация по ограничениям
- •19.6. Операции сравнения
- •19.7. Операторы, версии и сигнатуры
- •19.8. Является ли окружность эллипсом
- •19.9. Пересмотр специализации ограничением
- •19.10. Резюме
- •20.1. Введение
- •20.2. Предварительные сведения
- •20.3. Двенадцать основных целей
- •1. Локальная независимость
- •2. Отсутствие опоры на центральный узел
- •3. Непрерывное функционирование
- •4. Независимость от расположения
- •5. Независимость от фрагментации
- •6. Независимость от репликации
- •7. Обработка распределенных запросов
- •8. Управление распределенными транзакциями
- •9. Аппаратная независимость
- •10. Независимость от операционной системы
- •11. Независимость от сети
- •12. Независимость от типа субд
- •20.4. Проблемы распределенных систем
- •Транзакция т1х
- •20.5. Системы "клиент/сервер"
- •20.6. Независимость от субд
18.6. Специальные значения
Как показано выше, введение неопределенных значений (NULL) приводит к раз- рушению реляционной модели, которая великолепно обходилась без них в течение десяти лет с момента ее создания 1969 году [5.1] и вплоть до введения этих значе- ний в 1979 году [13.1].
Теперь предположим, как в разделе 18.4, что понятие "неопределенных значений" в контексте представления отсутствующей информации заменено понятием специальных значений. Следует отметить, что в реальном мире мы обычно пользуемся именно специ- альными значениями. Например, специальное значение "?" используется для обозначе- ния количества рабочих часов для некоторого сотрудника, если его фактическое значе- ние по какой-либо причине неизвестно7. Таким образом, общая идея заключается в том, чтобы просто применять подходящее специальное значение, отличное от обычных зна- чений атрибута, во всех тех случаях, когда обычное значение не может использоваться. Обратите внимание, что это специальное значение обязательно должно принадлежать соответствующему домену. Поэтому в примере с данными о количестве рабочих часов типом атрибута HOURS_WORKED является не просто целое число, а целые числа плюс спе- циальное значение.
Безусловно, следует признать, что изложенная выше схема не очень элегантна, но она обладает явным преимуществом, поскольку не подрывает логических основ реляционной модели. В остальной части этой книги мы будем просто игнорировать возможность под- держки неопределенных значений (NULL) за исключением некоторых случаев, специфи- ческих для контекста языка SQL, когда те или иные ссылки на неопределенные значения (NULL) будут неизбежны. Более подробно эти вопросы рассматриваются в [18.12].
18.7. Поддержка неопределенных значений в языке sql
Поддержка неопределенных значений (NULL) и трехзначной логики в языке SQL от- ражает весь широкий спектр подходов, описанных в разделах 18.1-18.5. Так, например, когда в языке SQL условие WHERE применяется к таблице Т, это исключает из рассмотре- ния все строки таблицы Т, для которых указанное в предложении WHERE условие прини- мает значение false или ипк (т.е. не true). Аналогично, когда к результату выполнения не- которой операции группирования, представленному таблицей G, применяется оператор HAVING, из дальнейшего рассмотрения исключаются все группы кортежей, для которых указанное в предложении HAVING условие принимает значение false или ипк (т.е. не true). Из этого следует, что мы просто обратили внимание читателя на некоторые возможно- сти, специфические для языка SQL и не являющиеся частью концепции трехзначной ло- гики, которая обсуждалась в предыдущем разделе.
Замечание. Очень сложно оценить все последствия поддержки неопределенных зна- чений (NULL) в языке SQL. Дополнительную информацию можно найти в официальных документах стандарта SQL [4.22] и в учебном издании [4.19].
Обратите внимание, что для этого не используется неопределенное значение (NULL). В ре- альном мире никакого неопределенного значения вообще не существует.
Определение данных
Как описано в разделе 5.5 главы 5, для столбцов таблиц базы данных обычно указы- вается некоторое значение, принимаемое по умолчанию; оно часто определяется (явно или неявно), как величина NULL. Более того, столбцы в таблицах базы данных всегда раз- решают использование неопределенных значений, если условие запрета их использова- ния не будет указано явно (например, в виде фразы NOT NULL). Представление неопреде- ленных значений зависит от реализации, но оно должно быть таким, чтобы система смогла отличить это значение от других, которые неопределенными не являются (даже несмотря на то, что операция сравнения NULL Ф х не дает в результате true).
Табличные выражения
Напомним замечание из главы 7 (раздел 7.7) о том, что явная поддержка операции JOIN была введена только в версии SQL/92 стандарта языка SQL. Более того, если перед ключевым словом JOIN указан один из определителей LEFT, RIGHT или FULL (с необяза- тельной добавкой OUTER в каждом случае), рассматриваемое соединение является внеш- ний. Вот несколько примеров.
S LEFT JOIN SP ON S.St = SP.Si S LEFT JOIN SP USING ( SI ) S LEFT NATURAL JOIN SP
Три приведенных выражения эквивалентны, но первое приводит к созданию таблицы с двумя идентичными столбцами номера поставщика, а второе и третье — таблицы с од- ним столбцом номера поставщика.
Язык SQL также поддерживает аппроксимацию внешнего соединения, которую назы- вают объединяющим соединением. Однако подробное обсуждение этого вопроса выхо- дит за рамки данной главы.
Условные выражения
Как отмечалось в главе 8, в языке SQL условные выражения являются аналогом того, что во всех остальных случаях называется логическими (или булевыми) выражениями (более подробно они рассматриваются в приложении А). Неудивительно, что условные выражения являются той частью языка SQL, которая в наибольшей степени связана с неопределенными значениями и трехзначной логикой. Ниже предлагается несколько за- мечаний по этому поводу.
■ Проверка наличия неопределенного значения. В языке SQL предусмотрены два специальных оператора сравнения, IS NULL и IS NOT NULL, предназначенных для проверки наличия или отсутствия неопределенных значений. Синтаксис использо- вания этих операторов показан ниже.
<ковструктор строки> IS [ NOT ] NULL
(Параметр <конструктор строки> подробно рассматривается в приложении А.) Невнимательные пользователи могут попасть здесь в ловушку, поскольку выра- жения г IS NOT NULL и NOT (г IS NULL) не являются эквивалентными! Более подробно эта особенность рассматривается в [4.19].
■ Проверка наличия значений true, false и unknown. Если р - это заключенное в скобки условное выражение, то следующие операторы также являются условными выражениями.
р IS [ NOT ] TRUE р IS [ NOT ] FALSE p IS [ NOT ] UNKNOWN
Значения этих выражений показаны в приведенной ниже таблице истинности.
р |
true |
false |
unk |
р IS TRUE |
true |
false |
false |
р IS NOT TRUE |
false |
true |
true |
p IS FALSE |
false |
true |
false |
p IS NOT FALSE |
true |
false |
true |
p IS UNKNOWN |
false |
false |
true |
p IS NOT UNKNOWN |
true |
true |
false |
Обратите внимание, что выражения р IS NOT TRUE и NOT p не являются эквива- лентными.
Замечание. Выражение р IS UNKNOWN соответствует описанному выше оператору MAYBE{р).
■ Условие MATCH. Синтаксис параметра <условие match> (см. приложение А) содер- жит ключевые слова PARTIAL и FULL (их использование в приложении А не рас- сматривается). Эти опции могут повлиять на результат, если в данных присутст- вуют неопределенные значения.
<конструктор строки> MATCH [ UNIQUE ]
[ PARTIAL I FULL ] ( <табличное выражениё>)
Существует шесть возможных случаев, зависящих от того, указана ли опция UNIQUE, а также указана ли опция PARTIAL либо FULL. Подробное обсуждение этого вопроса достаточно сложное и выходит за рамки настоящей главы. Дополнитель- ную информацию можно найти в [4.19].
■ Условие EXISTS. См. комментарий к [18.6].
Скалярные выражения
■ Литералы. Ключевое слово NULL может быть использовано как способ лите- рального представления неопределенных значений (например, в операторе INSERT). Тем не менее следует заметить, что данное ключевое слово может ука- зываться не во всех контекстах, в которых допускается использование литера- лов. Согласно стандарту "не существует значения параметра <литерал> для представления неопределенных значений, хотя в некоторых случаях для указа- ния необходимости использования неопределенного значения может употреб- ляться ключевое слово NULL" [4.22]. Поэтому, например, ключевое слово NULL нельзя явно использовать как операнд в простых операциях сравнения, т.е. вы- ражение WHERE X = NULL некорректно.
Функция COALESCE. Это SQL-аналог функции IF_UNK (см. раздел 18.2), определен- ной выше в данной главе.
Обобщающие функции. Обобщающие функции языка SQL, например SUM, AVG и т.п., не ведут себя в соответствии с правилами для скалярных операторов, изложенными выше, в разделе 18.2. Вместо этого они просто игнорируют лю- бое неопределенное значение в своих аргументах (исключение составляет функция CQUNT(*), при вычислении которой неопределенное значение тракту- ется, как обычное значение). Кроме того, если этим функциям в качестве ар- гумента передается пустое множество, они возвращают неопределенное значение. Исключение и здесь составляет функция COUNT, которая в данном случае возвращает значение "нуль". (Сравните с трактовкой обработки пустых множеств, изложенной в главе 7.)
Скачярные подчиненные запросы. Если скалярное выражение фактически является заключенным в скобки табличным выражением, например (SELECT S.CITY FROM S WHERE S.St='Sl'), то вполне естественно, что результатом вычисления подобного табличного выражения должна быть таблица, содержащая единствен- ный столбец и единственную строку. Тогда значением скалярного выражения в целом будет то единственное скалярное значение, которое содержится в результи- рующей таблице. Но если результатом вычисления табличного выражения являет- ся таблица, не содержащая ни одной строки, в языке SQL значение этого скаляр- ного выражения определяется, как неопределенное (NULL).
Ключи
Ниже кратко перечислены основные особенности использования неопределенных значений в ключевых атрибутах, характерные для языка SQL.
Потенциальные ключи. Пусть С — это атрибут, являющийся частью потенциаль- ного ключа К некоторой базовой таблицы. Если ключ К является первичным, то язык SQL запрещает использование неопределенных значений в столбце С (обеспечивая таким образом соблюдение ограничения целостности сущности). Тем не менее, если ключ К не является первичным, язык SQL разрешает присутст- вие в столбце С любого количества неопределенных значений (конечно, вместе с любым количеством значений, не являющихся неопределенными).
Внешние ключи. Правила, определяющие смысл соответствия значения заданного внешнего ключа некоторому значению соответствующего потенциального ключа (при наличии в них неопределенных значений), очень сложны. В данном случае их подробное обсуждение опускается. Заметим только, что они, в основном, совпа- дают с правилами, установленными для условий MATCH (см. выше).
Неопределенные значения также оказывают влияние на выполнение действий по установленным правилам поддержки ссылочной целостности (CASCADE, SET NULL и т.д.), заданным в предложениях ON DELETE и ON UPDATE. Дополнительно под- держивается действие SET DEFAULT, требующее установки заданного значения по умолчанию. Для простоты изложения подробное обсуждение этой проблемы здесь опущено. Заинтересованный читатель может обратиться к [4.19].
Внедренные SQL-операторы
■ Индикаторные переменные. Рассмотрим конкретный пример внедренного SQL- выражения. (Он уже приводился в главе 4 при описании однострочного опера- тора SELECT.)
EXEC SQL SELECT STATUS, CITY INTO :RANK, :CITY FROM S
WHERE S# = :GIVENSi ; Предположим, что для некоторых поставщиков атрибут STATUS может содержать неопределенное значение. Тогда выполнение приведенного выше оператора SELECT завершится неудачей, если в выбранном кортеже атрибут STATUS будет со- держать неопределенное значение (в переменную SQLSTATE будет помещен код ошибки 22002). В общем случае, когда существует вероятность, что выбираемое значение может оказаться неопределенным, для данного атрибута пользователь должен указать, помимо целевой, еще и индикаторную переменную. Пример оп- ределения индикаторной переменной приведен ниже.
EXEC SQL SELECT STATUS, CITY
INTO :RANK INDICATOR :RANKIND, :CITY FROM S
WHERE S# = :GIVENS# ;
IF RANKIND = -1 THEN /* Атрибут STATUS содержит величину NULL */;
END IF;
Если значение, которое нужно выбрать, является неопределенным и для данного ат- рибута задана индикаторная переменная, то в эту переменную будет помещено зна- чение -1 (значение, помещаемое в целевую переменную, зависит от реализации).
■ Упорядочение. Для упорядочения строк, полученных в результате вычисления табличного выражения, в определении курсора используется фраза ORDER BY. (Безусловно, она может использоваться и при вводе интерактивных запросов.) Возникает вопрос: "Каков относительный порядок двух скалярных значений А и В, если либо А является неопределенным значением, либо В является неопределен- ным значением, либо оба они одновременно являются неопределенными значе- ниями?". В стандарте языка SQL на этот вопрос даются следующие ответы.
В процессе упорядочения все неопределенные значения считаются равными од- но другому.
В процессе упорядочения все неопределенные значения считаются либо боль- шими всех остальных значений, либо меньшими их всех (реальный выбор одной из этих возможностей зависит от конкретной реализации).