- •Глава 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. Независимость от субд
19.6. Операции сравнения
Предположим, имеются две обычные переменные, Е и С, с объявленными типами ELLIPSE и CIRCLE соответственно. Предположим также, что текущее значение перемен- ной С присваивается переменной Е.
Е := С ;
Тогда совершенно ясно, что если выполнить сравнение значений этих переменных, то в результате должно быть получено значение истина.
Е = С
В общем виде соответствующее правило можно сформулировать так. Рассмотрим операцию сравнения X = Y, где X и Y — скалярные выражения. Объявленный тип DT(X) должен быть подтипом объявленного типа DT(Y) или наоборот, в противном случае сравнение будет просто недопустимым (проверяется при компиляции). При допустимом сравнении в результате получим значение истина, если конкретный тип MST(X) равен конкретному типу MST(Y) и значение v(X) равно значению v(Y), в противном случае ре- зультатом будет значение ложь. Отметим, в частности, что два значения нельзя сравнить "на равенство", если их конкретные типы различны.
Сравнения в реляционной алгебре
Сравнения на равенство явно или неявно используются во многих операциях реляци- онной алгебры. И в случае поддержки механизма супертипов и подтипов, на первый взгляд, может показаться, что некоторые из этих операций будут выполняться в проти- воречии со здравым смыслом. Рассмотрим отношения RX и RY, представленные на рис. 19.2. Обратите внимание, что единственный атрибут А в отношении RX имеет объяв- ленный тип ELLIPSE, а атрибут А в отношении RY имеет объявленный тип CIRCLE. При- мем, что значения вида Ei — это эллипсы, не являющиеся окружностями, а значения Ci — это окружности. Конкретные типы для каждого значения выделены на рисунке строчными буквами и курсивом.
RX |
А |
1 ELLIPSE |
RY |
A |
J CIRCLE |
|
Е1 |
! ellipse |
|
C2 |
! circle |
|
С2 |
, circle |
|
C3 |
, circle |
пом которого является ELLIPSE, не может сравниваться с любым значением А в отноше- нии RY). Поэтому можно подумать, что атрибут А в отношении RJ должен быть объявлен с типом CIRCLE, а не с типом ELLIPSE. Но рассмотрим следующие рассуждения.
RJ |
А |
[ELLIPSE |
|
С2 |
J circle |
операции должен быть ELLIPSE. Таким образом, и для операции объединения в резуль- тирующем отношении объявленный тип атрибута А также должен быть ELLIPSE (но об этом частном случае, в отличие от операций JOIN, INTERSECT и MINUS, вряд ли можно сказать, что он интуитивно непредсказуем). Теперь сформулируем общее правило.
Пусть гх и гу — отношения с общим атрибутом А, и пусть объявленные типы атрибута А в отношениях гх и гу — соответственно DT(Ax) и DT(Ay). Рассмот- рим соединение отношений гх и гу (обязательно по атрибуту А или по край- ней мере с его участием). Объявленный тип DT(Ax) должен быть подтипом типа DT(Ay) или наоборот, в противном случае выполнение соединения будет недопустимо (проверяется во время компиляции). Если соединение допусти- мо, можно считать, не теряя общности, что DT(Ay) — это подтип DT(Ax). То- гда объявленный тип атрибута А в результирующем отношении операции бу- дет DT(Ax).
Аналогичные соображения справедливы и для операций объединения, пересече- ния и разности. В каждом случае соответствующие атрибуты операндов должны быть такими, чтобы объявленный тип одного из них был подтипом объявленного типа другого и объявленный тип соответствующего атрибута результата будет ме- нее конкретным из двух объявленных типов (здесь под менее конкретным из двух типов Т и Т', один из которых является подтипом другого, подразумевается тот, который является супертипом).
Операторы проверки типа
В предыдущем разделе был приведен фрагмент кода, в котором применялись опера- торы вида IS_SQUARE, IS_CIRCLE и т.д., используемые для проверки, относится ли ука- занное значение к определенному типу. Рассмотрим эти операторы подробнее. Прежде всего, будем считать, что определение некоторого типа Т приводит к автоматическому определению оператора следующего вида.
IS_T ( X )
Здесь X— скалярное выражение, такое, что DT(X) является супертипом типа Т (проверяется при компиляции). Вычисление выражения в целом дает значение истина, если выражение X принадлежит типу Т, и значение ложь — в противном случае. Отме- тим, что объявленный тип указанного аргумента X должен быть супертипом указанно- го типа Т. Поэтому, например, если С — переменная объявленного типа CIRCLE, то приведенное ниже выражение будет недопустимым (ошибка типа будет обнаружена при компиляции).
IS_SQUARE ( С )
С другой стороны, оба следующих выражения допустимы и в результате дают значе- ние истина.
IS CIRCLE ( С ) IS~ELLIPSE ( С )
Наконец, если Е — переменная объявленного типа ELLIPSE, но конкретный тип ее те- кущего значения — некоторый подтип типа CIRCLE, то результат приведенного ниже вы- ражения также будет истиной6.
IS_CIRCLE { Е )
Мы также подразумеваем, что определение некоторого типа т приводит к автомати- ческому определению оператора следующего вида.
IS_MS_T ( X )
Здесь X — скалярное выражение, a DT(X) — супертип типа Т (опять же, это проверя- ется при компиляции). Вычисление выражения в целом дает значение истина, если вы- ражение X принадлежит типу Т, и значение ложь — в противном случае.
Замечание. Обратите внимание, что в то время как, например, оператор IS_ELLIPSE на естественном языке можно лучше всего сформулировать как "является эллипсом", то оператор IS_MS_ELLIPSE на естественном языке лучше всего сформулировать как "является конкретно эллипсом".
Ниже приводится пример, включающий типы прямоугольника, квадрата и оператор IS_MS_RECTANGLE.
VAR R RECTANGLE ;
IF IS_MS_RECTANGLE ( R )
THEN CALL ROTATE ( R ) ; END IF ;
Интуитивно ясно, что оператор ROTATE (Вращать) — это оператор, с помощью кото- рого заданный в качестве аргумента прямоугольник поворачивается на 90° вокруг цен- тра, и что в подобном вращении нет никакого смысла, если рассматриваемый прямо- угольник является квадратом.
Проверка типа также важна для реляционных операторов. Рассмотрим следующий пример. Пусть переменная-отношение R имеет атрибут А объявленного типа ELLIPSE, и допустим, что требуется получить такие кортежи переменной-отношения R, в которых значение атрибута А в действительности является окружностью с радиусом, большим 2. Можно попытаться решить эту задачу следующим образом.
R WHERE THE_R ( А ) > LENGTH ( 2.0 )
Однако это выражение будет квалифицировано как ошибочное при компиляции, по- скольку для оператора THE R требуется, чтобы аргумент имел тип CIRCLE, а атрибут А имеет объявленный тип ELLIPSE, а не CIRCLE. (Если бы проверка при компиляции не вы- полнялась, то ошибка была бы, конечно, обнаружена во время выполнения, причем это произошло бы при обработке первого же из кортежей, который является просто эллип- сом, а не окружностью.)
Очевидно, что необходимо как-то отсеять кортежи, в которых значение атрибута А является просто эллипсом, и только после этого проверить условие, что радиус должен быть больше 2. Рассмотрим теперь другую формулировку возможного решения.
R : IS_CIRCLE ( А ) WHERE THE_R ( А ) > LENGTH ( 2.0 )
Согласно этому выражению при выполнении операции должны возвращаться такие кортежи, в которых значение атрибута А является окружностью с радиусом, большим 2. Точнее, возвращается отношение, имеющее следующие свойства.
Оно имеет тот же заголовок, что и переменная-отношение R, но объявленный тип атрибута А в нем — CIRCLE, а не ELLIPSE.
Его тело содержит те кортежи из переменной-отношения R, в которых значение ат- рибута А будет иметь тип CIRCLE, т.е. будет окружностью и радиус этой окружно- сти будет больше 2.
Другими словами, то, что мы только что рассмотрели, — это новый реляционный оператор следующего вида.
R : IS_T ( А )
Здесь R — реляционное выражение, а А — атрибут отношения (скажем, г), обозна- чаемого этим выражением. Объявленный тип DT(A) атрибута А должен быть супертипом типа Т (проверяется при компиляции). Значение данного выражения в целом определяет отношение со следующими свойствами.
Оно имеет тот же заголовок, что и отношение г, но объявленный тип атрибута А в этом заголовке — Т.
Его тело содержит кортежи г, в которых атрибут А имеет значение типа Т, и, кроме того, объявленный тип атрибута А в каждом из таких кортежей будет Т.
Аналогично определяется другой новый реляционный оператор следующего вида. R : IS_MS_T ( А )