/
Text
основы
СИСТЕМ БАЗ
ДАННЫХ
Jeffrey D. Ullman
PRINCIPLES
OF
DATABASE
SYSTEMS
STANFORD UNIVERSITY
COMPUTER SCIENCE PRESS
ДЖ.У71Ь/И4Н
ОСНОВЫ
СИСТЕМ
БАЗ
ДАННЫХ
Перевод с английского М. Р. КОГАЛОВСКОГО
и В. В. КОГУТОВСКОГО
Под редакцией М. Р. Когаловского
МОСКВА
«ФИНАНСЫ И СТАТИСТИКА»
1983
ББК 32.973
У51
„ 2405000000—134
У ----------------131—83
010(01)—83
© 1980 Computer Science Press, Inc,
© Перевод на русский язык, предисловие, «Финансы и статистика», 1983.
ПРЕДИСЛОВИЕ К РУССКОМУ ИЗДАНИЮ
Имя профессора Стэнфордского университета (США) Джеффри Д. Уль-
мана хорошо известно в нашей стране благодаря вышедшим в издательстве
«Мир» монографиям «Теория синтаксического анализа, перевода и компиля-
ции» (1978 г.), написанной в соавторстве с А. Ахо, и «Построение и анализ
вычислительных алгоритмов» (1979 г.), подготовленной совместно с А. Ахо
и Дж. Хопкрофтом.
В предлагаемой читателю книге Дж. Ульман обращается к проблемати-
ке систем баз данных. И это отнюдь не случайно. Более десяти лет (до 1979 г.)
автор преподавал в Принстонском университете, где наряду с курсами по
другим дисциплинам читал и курс по системам баз данных. На основе
конспектов прочитанных Ульманом лекций и написана настоящая книга.
Вместе с тем ему принадлежит ряд интересных математических результа-
тов в теории реляционных баз данных, исследовании поиска по частичному
соответствию ключей, секретности статистических баз данных, опублико-
ванных в соавторстве в различных периодических изданиях и представлен-
ных в трудах крупных научных конференций. В течение ряда лет Дж.
Ульман является редактором раздела «Базы данных» в «Journal of АСМ».
В последние годы в нашей стране были подготовлены и опубликованы
переводы популярных за рубежом монографий Дж- Мартина «Организация
баз данных в вычислительных системах», выдержавшей два издания (М.,
Мир, 1978 и 1980), и К. Дейта «Введение в базы данных» (М., Наука, 1980),
серьезного анализа концепций и языковых спецификаций систем управле-
ния базами данных сетевой структуры — монографии Т. Олле «Предложе-
ния КОДАСИЛ по управлению базами данных» (М., Финансы и статистика,
1981). Опубликован также перевод официального издания «Журнала раз-
вития языка описания данных» Комитета по языку описания данных
КОДАСИЛ (М., Статистика, 1981). Однако интерес к этой весьма актуаль-
ной и перспективной области вычислительной технологии продолжает
оставаться активным. Поэтому предлагаемая читателю книга будет полез-
ным дополнением к имеющейся литературе и, несомненно, найдет многочис-
ленных читателей.
Вместе с тем книга Дж. Ульмана существенно отличается от других
опубликованных изданий в рассматриваемой области. Главное ее отличие
заключается в том, что автор уделяет основное внимание приложениям
математического аппарата к решению различных проблем баз данных, об-
суждению и систематизации наиболее ценных результатов, полученных в
этой области и имеющих весьма важное значение для дальнейшего развития
теории систем баз данных, а также их практической разработки. Книга
Дж. Ульмана убедительно показывает возможности успешного использо-
вания математического инструментария для описания, исследования и
разработки различных аспектов систем баз данных, например для оценки
методов организации данных в среде хранения, проектирования и исследо-
вания структуры реляционных баз данных, оптимизации запросов,
5
исследования различных подходов к защите статистических баз данных,
анализа параллельных процессов в базах данных.
Немаловажный фактор, определяющий ценность настоящей книги,
заключается и в том, что материалы, посвященные большинству обсуждае-
мых в ней проблем, рассредоточены в многочисленных зарубежных перио-
дических изданиях, трудах конференций, научных отчетах. Чтобы полу-
чить из таких разрозненных публикаций цельное представление о пробле-
ме, результатах и состоянии исследований, нужно выполнить большую ра-
боту, которая к тому же не каждому под силу.
Проанализируем кратко содержание книги. Первые три ее главы
имеют вводный характер и обеспечивают основу для детального рассмотре-
ния более специальных вопросов в других разделах работы. Лаконично и
в нетрадиционной манере здесь обсуждаются основные концепции систем
баз данных. Важное место при этом уделяется принципам многоуровне-
вого представления данных в таких системах, получившим в настоящее
время широкое признание среди специалистов. С целью обеспечения еди-
ной платформы для обсуждения и сопоставления наиболее популярных
моделей данных — реляционной, сетевой и иерархической — вводится
некоторая «каноническая» модель реальности, в качестве которой автор
предлагает использовать известную модель объектов-связей, разработан-
ную П. Ченом.
Детально излагаются современные методы организации среды хранения
данных в системах баз данных: списковые структуры, хешированные фай-
лы, техника индексирования, В-деревья, использование записей перемен-
ной длины и т. д. Здесь вновь обсуждение ведется на единой основе — опи-
санной содержательно общей модели организации среды хранения. Для
каждого метода организации хранения данных отмечены его сильные и
слабые стороны, приведены алгоритмы выполнения операций поиска,
включения, модификации и удаления данных, а также сравнительные
оценки характеристик основных методов.
Вводная часть книги завершается рассмотрением моделей данных, на
которых базируется большинство существующих коммерческих и экспери-
ментальных СУБД — реляционной, сетевой и иерархической. Для каждой
из моделей освещены вопросы ее реализации, представления данных и вы-
полнения модельных операций. Для интерпретации рассматриваемых мо-
делей используется модель объектов-связей, а проблемы реализации обсуж-
даются в терминах понятий, введенных при описании методов организации
хранения данных.
Вторую тематическую часть книги образуют следующие ее пять глав
(гл. 4—8), содержание которых посвящено детальному обсуждению функ-
циональных возможностей широкого спектра языковых средств СУБД.
Центральное место в этой части посвящено системам реляционного
типа. Обеспечивая теоретическую и концептуальную основу анализа реля-
ционных языков, автор вводит (гл. 4) основные понятия реляционной алгеб-
ры и реляционного исчисления с переменными-кортежами, а также исчис-
ления с переменными на доменах, показывает их эквивалентность. В этом
контексте на примере ISBL, SQUARE и SEQUEL, QUEL и Query-by-
Example демонстрируются принципиальные возможности всего спектра ре-
ляционных языков.
Пожалуй, наиболее ценными в книге являются специально выделен-
ные в этой ее части главы, посвященные проблемам проектирования реля-
ционных баз данных и оптимизации реляционных запросов. Материалы
этих глав вместе с математическими разделами гл. 4 позволяют читателю по-
6
лучить конструктивное представление о теории проектирования реля^
ционных баз данных и являются чрезвычайно актуальными. На основе
этой теории в нашей стране и за рубежом проводятся исследования и прак-
тические разработки инструментария, предназначенного для автоматизации
проектирования баз данных. Хотя в настоящее время теория проектирова-
ния реляционных баз данных по существу уже сформировалась, в имею-
щейся литературе она отражена еще недостаточно. Изложение и трактовка
этой теории Дж. Ульманом, который лично внес значительный вклад в ее
развитие, без сомнения, вызовет большой интерес не только вновь изучаю-
щих проблематику баз данных, но и специалистов.
Разработчикам СУБД реляционного типа будут чрезвычайно полезны
систематически изложенные в специальной главе книги результаты, в том
числе принадлежащие и ее автору, связанные с оптимизацией запросов в
реляционных базах данных. Помимо обсуждения общей техники, критери-
ев и стратегий оптимизации, а также эквивалентных преобразований вы-
ражений реляционной алгебры, автор приводит алгоритм их оптимизации,
детально рассматривает алгоритм оптимизации выражений в языке QUEL
(язык запросов реляционной СУБД INGRES, разработанной в Калифор-
нийском университете), рассматривает известные результаты о минимиза-
ции конъюнктивных запросов.
Обсуждение предложений КОДАСИЛ относительно СУБД сетевой
структуры, а также возможностей широко распространенной системы
IMS носит в книге несколько конспективный характер. Тем не менее автору
удалось, на наш взгляд, донести до читателя принципиальные особенности
сетевых и иерархических СУБД, а также их языковых средств. Читатель
должен, однако, иметь в виду, что спецификации языков определения дан-
ных и манипулирования данными, разработанные КОДАСИЛ, рассматрива-
ются на основе отчета DBTG 1971 г. и к настоящему времени уже в сущест-
венной степени пересмотрены.
Большой интерес представляют две заключительные главы книги, пос-
вященные проблемам защиты целостности данных и управления доступом,
а также параллельным процессам в среде базы данных. Эти вопросы ни в
каких других источниках систематически не изложены. Используемые в
настоящее время подходы к разработке механизмов СУБД, обеспечивающих
защиту целостности данных и управление доступом, автор демонстрирует
на примере разработанной в исследовательском центре фирмы ИБМ реля-
ционной СУБД Query-by-Example, в которой эти механизмы достаточно
развиты. Значительное м^ето при этом уделяется изучению проблемы
секретности для статистических баз данных. Сформулированы важные ма-
тематические результаты для случая линейных запросов, и приведено их
доказательство.
Несомненно, интересной для читателя, прежде всего для разработчика
СУБД, будет глава о параллельных процессах в базах данных. По сущест-
ву, автор описывает конструктивные механизмы, обеспечивающие эффектив-
ное и надежное параллельное исполнение транзакций. Последовательно
представляется ряд моделей транзакций таким образом, что каждая сле-
дующая модель является более детальной по отношению к предыдущей и
благодаря этому позволяет добиться большей степени параллелизма. Об-
суждаются такие важные понятия, как бесконечные ожидания и тупики.
Специфицируются протоколы для параллельных транзакций — соглаше-
ния, которым должны удовлетворять транзакции с тем, чтобы исключить
при параллельном их исполнении тупиковые ситуации и бесконечные ожи-
дания, а также обеспечить возможность сохранения или, по крайней мере,
7
восстановления непротиворечивого состояния базы данных. Исследуются
свойства расписаний, предусматривающих параллельное исполнение тран-
закций, и прилагаются необходимые для этого алгоритмы.
Книга Дж. Ульмана написана ясным живым языком, изложение мате-
риала в ней иллюстрируется облегчающими восприятие многочисленными
примерами из самых разнообразных сфер человеческой деятельности —
авиационного транспорта, автомобилестроения, спорта, кулинарии, тор-
говли и т. д. Каждая глава книги сопровождается специально подобранны-
ми упражнениями различной степени трудности и весьма полезными
краткими библиографическими обзорами. Книга снабжена обширным
списком литературы.
Особо хотелось бы отметить некоторые терминологйческие трудности.
Переводчики стремились тщательно следовать терминологии «Краткого
англо-русского терминологического словаря по банкам данных», подго-
товленного Рабочей группой по программному обеспечению банков данных
Междуведомственной научно-технической комиссии по программному
обеспечению ЭВМ ГКНТ СССР. Однако в ряде случаев потребовалось
ввести новые термины, ранее не употреблявшиеся в отечественной литера-
туре. При обсуждении вопросов, связанных с древовидными структурами,
в математической литературе традиционно используется терминология
генеалогических деревьев. Этой традиции придерживается и автор. Такая
терминология сохранена в переводе всюду, кроме гл. 8, где пришлось счи-
таться с тем фактом, что в нашей стране в области иерархических СУБД
применяется иная терминология.
В переводе, чаще всего без специальных оговорок, был исправлен ряд
имеющихся в оригинале опечаток и неточностей.
Тщательный подбор материала, серьезно продуманная композиция
книги, ясная логика и доходчивый стиль изложения, а также другие отме-
ченные достоинства позволяют считать эту работу безусловной удачей ав-
тора и надеяться, что она не только послужит хорошим пособием по кур-
сам баз данных для студентов вузов и аспирантов, но и будет полезной
специалистам, занятым разработкой СУБД, проектированием систем баз
данных и их практическим использованием.
М. Р. Когаловский
ПРЕДИСЛОВИЕ
Курс лекций по системам баз данных в настоящее время, очевидно,
играет центральную роль в учебных программах для студентов старших
курсов и аспирантов, специализирующихся в области вычислительной
науки. Однако в отличие от более традиционных и уже сформировавших-
ся системных дисциплин, подобных компиляторам и операционным систе-
мам, где много лет удачно сочетаются теория и практика, предмет систем
баз данных остается все еще в большой степени описательным.
Настоящая книга подготовлена по материалам заметок, использован-
ных мною в курсе лекций в Принстоне, где я предпринял попытку включить
системы баз данных в число основных дисциплин вычислительной науки.
Лекции читались для студентов старших курсов и аспирантов первого года
обучения. В них я пытался связать идеи баз данных с концепциями из
других областей, таких, как языки программирования, алгоритмы и струк-
туры данных. Было включено значительное количество описательного
материала, поскольку студенты, пользующиеся стандартными языками
программирования, могут найти языки запросов несколько необычными.
Структуры данных, связанные с базами данных, также заметно отличаются
от видов структур, используемых в обычном программировании, посколь-
ку большие базы данных делают практичными многие структуры, которые
в противном случае представляли бы только теоретический интерес.
Однако я связал комплекс проблем с подходящей теорией и ввел
принципиальные концепции, касающиеся отношений и параллелизма,
которые также были сочтены полезными. Большую часть книги я посвятил
описанию отношений, реляционной алгебры и реляционного исчислемия и
языкам запросов, разработанным с использованием этих концепций. Де-
тально обсуждаются здесь и возможности применения теории реляционных
баз данных для проектирования хороших систем, а также задачи оптими-
зации запросов в языках запросов, основанных на отношениях. Целая
глава посвящена также недавно разработанным протоколам для обеспе-
чения непротиворечивости в базах данных, которыми параллельно опери-
рует множество процессов.
Упражнения
Каждая глава включает упражнения для проверки усвоения основных
концепций, а в отдельных случаях и для расширения некоторых идей.
Наиболее трудные упражнения помечены двумя звездочками, а упражнения
средней трудности — одной.
ДЖ. Д. УЛЬМАН
9
ГЛАВА 1
ОБЩЕЕ ПРЕДСТАВЛЕНИЕ О СИСТЕМЕ БАЗ ДАННЫХ
В настоящей главе рассматриваются различные уровни абстракции,
характерные для типичной системы управления базами данных, и основ-
ные функции такой системы. Обсуждается модель «реального мира», поз-
воляющая оценивать способность систем баз данных представлять реаль-
ные данные и манипулировать ими. Эта модель, называемая моделью
«объектов-связей», изучается в разд. 1.4.
1.1. СИСТЕМА БАЗ ДАННЫХ
Рассмотрим предприятие, которое располагает большим количеством
данных, хранимых в течение длительных периодов времени в ЭВМ, например
авиалинию. Эти данные могут, в частности, содержать сведения о пасса-
жирах, рейсах, самолетах и о персонале и представлять типичные для
конкретной предметной области отношения. Такими отношениями явля-
ются, например, продажа билетов (каким пассажирам, на какие рейсы и
места проданы билеты), формирование экипажей (кто должен быть коман-
диром корабля, вторым пилотом и т. д., на каком рейсе) и регистрация тех-
нического обслуживания (когда и кем обслуживался каждый самолет в
последний раз).
Данные подобного рода, более или менее постоянно хранимые в ЭВМ,
мы называем базой данных. Для использования и (или) модификации этих
данных одним или несколькими лицами необходимо программное обеспе-
чение, называемое системой управления базами данных (СУБД). Главная
роль СУБД заключается в обеспечении пользователя инструментарием,
позволяющим оперировать данными в абстрактных терминах, не связан-
ных со способами их хранения в ЭВМ. В этом смысле СУБД действует как
интерпретатор языка очень высокого уровня, подобного АПЛ, средствами
которого можно идеально специфицировать, что должно быть сделано, не
обращая или почти не обращая внимания на используемые системой де-
тальные алгоритмы и представление данных. Однако в случае СУБД
данные, видимые пользователем, и данные, хранимые в ЭВМ, оказываются
иногда зависимыми даже в меньшей степени, чем массивы языка АПЛ и
представление их в памяти. СУБД должна выполнять также и ряд дру-
гих функций. Основные из них состоят в следующем:
1. Обеспечение секретности. Не каждый пользователь должен иметь
доступ ко всем данным. Например, если хранятся сведения о кадрах, то
доступ к данным о зарплате должен предоставляться только руководящему
персоналу, обладающему таким правом. Мы обсудим этот аспект функцио-
нирования СУБД в гл. 9.
2. Защита целостности данных. СУБД может проверять некоторого
рода ограничения непротиворечивости данных (т. е. требуемые их свойст-
10
ва), если ей это предписано. Наиболее легкими для проверки являются
ограничения, связанные со свойствами значений, например требование,
чтобы число пассажиров, которым проданы билеты иа определенный рейс,
ие превышало вместимости самолета. Несколько сложнее проверяются
ограничения, формулируемые в виде равенства или неравенства значений,
безотносительно к самим значениям. Так, два самолета не могут быть на-
значены на один и тот же рейс. В гл. 5 освещаются отдельные аспекты
структурной целостности данных, а в гл. 9 — общие проблемы целостности.
3. Синхронизация. Часто имеет место ситуация, когда исполняется
несколько программ, одновременно осуществляющих доступ к базе данных.
СУБД должна обеспечивать защиту от нарушений их непротиворечиво-
сти, являющихся следствием двух квазиодновременных операций над не-
которым элементом данных. Предположим, нйпример, что приблизитель-
но в одно и то же время два агента по продаже билетов запрашивают место
на рейс 999. Каждый запрос приводит к исполнению конкретной програм-
мы, которая проверяет число имеющихся мест (допустим, осталось одно
место), вычитает единицу и запоминает число оставшихся мест в базе Дан-
ных. Если СУБД не будет обрабатывать эти две транзакции (два обращения
к указанной программе) последовательно, то может оказаться, что двум
пассажирам продано одно и то же место. Меры по обеспечению соответст-
вующей синхронизации рассматриваются в гл. 10.
4. Защита от отказов и восстановление. Должны быть предусмотрены
средства, обеспечивающие регулярное создание копий базы данных для
ее восстановления после устранения сбоев оборудования или ошибок про-
граммного обеспечения. Этот вопрос также обсуждается в гл. 10.
1.2. УРОВНИ АБСТРАКЦИИ В СУБД
Должно быть очевидно, что существует множество уровней абстракции
между ЭВМ, имеющей дело с битами, и конечным пользователем, имеющим
дело с такими абстракциями, как рейсы или закрепление экипажа за са-
молетом. Довольно стандартная точка зрения на уровни абстракции пока-
зана иа рис. 1.1. Мы видим на трех различных уровнях абстракции
единую базу данных, которая может быть одной из многих, использующих
одну и ту же СУБД. Следует подчеркнуть, что реально хранится только
физическая база данных. Мы предпочитаем представлять ее себе не на
уровне бит, а на несколько более высоком уровне — как совокупность
файлов и, возможно, несложные структуры данных.
Группа
пользователей
Группа
пользователей
Группа
пользователей
Рис. 1.1. Уровни абстракции в системе баз данных
И
Концептуальная база данных — это абстрактное отображение физи-
ческой базы данных (или, что равносильно, физическая база данных есть
реализация концептуальной базы данных), а представления являются
абстракциями некоторых частей концептуальной базы данных. Различия
в уровнях абстракции между представлениями и концептуальной базой
данных, вообще говоря, невелико. И представления, и концептуальная
база данных имеют дело с абстракциями такого рода, как «пассажир», и
с такими абстрактными связями, как «купил билет на».
Схемы и экземпляры
Кроме показанных на рис. 1.1 градаций по уровням абстракции, су-
ществует другое, ортогональное измерение нашего восприятия баз данных.
На стадии проектирования базы данных мы интересуемся ее планами. В
процессе же эксплуатации базы данных мы имеем дело с содержащимися
в ней актуальными данными. Текущее содержимое базы данных называет-
ся экземпляром базы данных. Заметим, что данные в базе данных часто
изменяются, в то время как планы остаются неизменными в течение дол-
гих периодов времени (но не обязательно навсегда).
План представляет собой перечень типов объектов, относящихся к
базе данных, связей между ними и способов, с помощью которых объекты
и связи некоторого уровня абстракции выражаются на следующем, более
низком (более конкретном) уровне. Для обозначения планов используется
термин схема. Таким образом, мы говорим о концептуальной схеме как о
плане концептуальной базы данных и называем план физической базы
данных физической схемой. План представления часто для простоты назы-
вается подсхемой.
Пример 1.1. Для иллюстрации различия между схемами и экземплярами
предположим, что имеется база данных цветочных растений. Концептуальная схема
может включать типы объектов ЦВЕТОК, МЕСТО_ ПРОИЗРАСТАНИЯ и др. Наряду
с другими связями в ней может быть предусмотрена и связь ПРОИЗРАСТАЕТ— В
между ЦВЕТОК и МЕСТО— ПРОИЗРАСТАНИЯ. Тогда в концептуальной базе данных
могут содержаться объекты роза и тюльпан типа ЦВЕТОК вместе с информацией о
том, что тюльпан ПРОИЗРАСТАЕТ-В Голландия, в то время как роза ПРОИЗРАСТА-
ЕТ_В Техас и роза ПРОИЗРАСТАЕТ- В Тралн, а объекты Голландия, Техас и Трали
являются экземплярами типа МЕСТО— ПРОИЗРАСТАНИЯ.
Если перейти к следующему, более низкому уровню, то в схеме физической
базы данных можно, например, объявить, что объекты типов ЦВЕТОК и МЕСТО-ПРО-
ИЗРАСТАНИЯ являются строками литер длины 10 и что ПРОИЗРАСТАЕТ—В пред-
ставляется связанными списками мест произрастания для каждого цветка, причем все
списки имеют заголовки, полученные путем применения конкретной функции хеширо-
вания к названию цветка.
Физическая база данных
Физическая база данных находится на самом нижнем из рассматривае-
мых уровней абстракции. Она размещается на устройствах внешней памяти,
например на магнитных дисках или лентах. Сама по себе физическая база
данных может быть представлена на нескольких уровнях абстракции —
от уровня записей и файлов в языке программирования, подобном ПЛ/1,
возможно, через уровень логических записей, поддерживаемый операцион-
ной системой, в обстановке которой работает СУБД, до уровня бит и
физических адресов на запоминающих устройствах. В гл. 2 обсуждаются
основные структуры данных, используемые для реализации физической
базы данных, а в гл. 4, 7 и 8 — характерные особенности реализации не-
которых важных существующих систем управления базами данных.
12
Концептуальная схема и ее модель данных
Как уже отмечалось, концептуальная схема — это абстракция реаль-
ного мира, имеющая отношение к предметной области и соответствующая
именно уровню пассажиров, рейсов и т. д., который мы обсуждали в связи
с авиалинией. Для спецификации концептуальной схемы и, весьма вероят-
но, некоторых деталей, касающихся ее реализации физической схемой,
СУБД предоставляет так называемый язык определения данных. Он являет-
ся языком высокого уровня и позволяет записывать концептуальную
схему в терминах некоторой «модели данных». Примером подходящей мо-
дели данных может служить ориентированный граф (в жаргоне — сете-
вая модель), где вершины представляют множество однородных объектов
(например, все пассажиры или все рейсы), а дуги — ассоциации (например,
назначение самолета для выполнения рейса).
Выбор модели данных представляет собой трудную задачу, поскольку
такая модель должна обладать структурой, достаточно богатой для описа-
ния существенных аспектов реального мира. Кроме того, необходимо иметь
возможность автоматически определять эффективную реализацию концеп-
туальной схемы физической схемой. Следует подчеркнуть, что, хотя СУБД
могут использоваться и для построения небольших баз данных, многие
базы данных тем не менее состоят из миллионов байт и неэффективная
реализация может оказаться для них гибельной. Если нам не известно,
где именно в физической базе данных должна находиться конкретная пор-
ция информации, то, чтобы ее найти, может потребоваться несколько ча-
сов на просмотр всей базы данных.
Существуют по крайней мере три основные модели, которые исполь-
зуются в системах баз данных:
1. Иерархическая модель. Является деревом, где вершины могут пред-
ставлять такие наборы объектов, как рейсы, и сыновья вершины ассоции-
руются с их отцом в некоторой конкретной связи. Например, вершины,
соответствующие всем пассажирам, купившим билеты на рейс, могут быть
сыновьями вершины для данного рейса.
2. Сетевая модель. Это — модель ориентированных графов, о кото-
рой уже упоминалось выше.
3. Реляционная модель. Базируется на теоретико-множественном по-
нятии отношения, т. е. множества кортежей длины k при некотором фикси-
рованном k. Например, сведения о продаже билетов могут быть представ-
лены множеством ПРОДАЖА_______БИЛЕТОВ, состоящим из триплетов.
НОМЕР_РЕЙСА ДАТА ПАССАЖИР,
так, что
ПРОДАЖА _ БИЛЕТОВ = {(n, d, р)| пассажиру р продано место на рейс п на дату d)
Эти.три модели данных представлены в гл. 3, где обсуждаются теория
и техника, специфичная для каждой из них. В гл. 4—6 рассматривается
реляционная модель. Глава 7 посвящена предложениям DBTG, весьма
важным с точки зрения сетевой модели, а гл. 8 — системе IMS — одной из'
главных СУБД, использующих иерархическую модель. В разд. 1.4 при-
водится несколько более общая модель, называемая моделью объектов-
сгязей, которая в некотором смысле обобщает три другие упомянутые
модели1.
1 Необходимо предостеречь читателя от возможной ошибки: ие следует отождест-
влять модель данных со структурой данных. — Примеч. ред.
13
Представления
Представление, или подсхема1, — это абстрактная модель некоторой
части концептуальной базы данных или концептуальной схемы. Например,
авиалиния может иметь автоматизированную службу продажи билетов,
использующую данные и совокупность программ, которые связаны с рей-
сами и пассажирами. Но ни сами программы, ии те, кто с ними работают,
не обязаны знать о файлах персонала или о запланированных для летчи-
ков рейсах. Диспетчеру, вероятно, потребуется информация о рейсах,
самолетах, и частично о персонале (например, кто из летчиков допу-
щен к полетам на «Боинге-747»), но ему не нужны сведения о зарплате
персонала или о пассажирах, зарезервировавших билеты на какой-либо
рейс.
В некотором смысле представление является небольшой концептуаль-
ной базой данных и находится иа одном с ней уровне абстракции. Однако,
представление может быть и «более абстрактным», чем концептуальная
база данных, так как данные, доступные с помощью представления, могут
конструироваться из этой базы данных, но фактически в ней не присут-
ствовать.
Приведем канонический пример. Для отдела кадров может поддержи-
ваться представление, которое включает возраст каждого служащего. Одна-
ко поддерживать сведения о возрасте в концептуальной базе данных
нецелесообразно, так как они должны были бы ежедневно изменяться для
большого числа служащих. Концептуальная база данных должна, скорее,
включать дату рождения служащего. Если пользовательская программа,
имеющая дело с представлением, которое содержит информацию о возрасте,
запрашивает из базы данных возраст служащего, СУБД транслирует
этот запрос в следующий: «текущая дата минус дата рождения». Послед-
ний приобретает смысл для концептуальной базы данных, и вычисление вы-
полняется над соответствующими данными, взятыми из физической базы
данных.
Второй, более полезный способ конструирования представлений, явля-
ющихся абстракциями концептуальной базы данных, строится на том,
что возможны различные ассоциации в подсхеме и лежащей в ее основе-
концептуальной схеме. Например, в концептуальной базе данных рейсы
могут быть некоторыми множествами пассажиров. В то же время в представ-
лении для службы продажи билетов пассажир может рассматриваться
как некоторое множество рейсов, на которые у него есть билет. Степень важ-
ности такого различия зависит от модели данных, используемой для определе-
ния концептуальной базы данных и представления. В действительности
представление и концептуальная база данных совсем не обязательно долж-
ны определяться с помощью одной и той же модели данных, хотя в боль-
шинстве систем баз данных, поддерживающих и представления, и концеп-
туальные схемы, в обоих случаях применяется одна и та же модель данных.
1 Автор допускает здесь неточность, отождествляя базу данных н ее схему. Поль-
зуясь терминологией автора, следовало бы сказать, что представление — это абстракт-
ная модель некоторой части концептуальной базы данных, в то время как подсхема—
абстрактная модель какой-либо части концептуальной схемы. Подсхема играет по
отношению к представлению роль, аналогичную роли схемы для базы данных. — При~
меч. ред.
14
1.3. РАЗЛИЧИЕ ВОСПРИЯТИЙ БАЗЫ ДАННЫХ
Для того чтобы спроектировать, реализовать и использовать большую
базу данных, требуются усилия многих людей.. Вернемся вновь к нашему
примеру с авиалинией. Конечный пользователь базы данных, такой, как
агент по предварительной продаже билетов, обычно не является програм-
мистом. Он может сидеть у терминала и печатать простую команду, напри-
мер BOOK (заказать билет). Эта команда вызывает некоторую программу,
которая, в частности, инициирует диалог с агентом, запрашивая у него ин-
формацию в фиксированном порядке: «ввести имя пассажира», «ввести
желаемый номер рейса». Получив нужную информацию, программа обра-
щается к базе данных и определяет, имеется ли для пассажира место. В
случае положительного результата программа модифицирует базу данных,
чтобы отразить факт бронирования некоторого места. Если желаемого мес-
та нет, она информирует об этом агента.
Рассмотренная операция выглядит весьма просто. Но как написать
программу, которая могла бы обмениваться сообщениями с базой данных?
В конце концов, предполагается (см. рис. 1.1), что пользователи взаимодей-
ствуют только с представлениями, которые являются двухуровневыми
абстракциями физической базы данных. Ответ на вопрос заключается
в том, что существует несколько специализированных языков, используе-
мых для определения баз данных на этих уровнях абстракции и для ма-
нипулирования базой данных.
Проектирование концептуальной схемы
Как уже отмечалось, концептуальная схема специфицируется в неко-
тором языке, который поставляется как часть СУБД и называется языком
определения данных. Он является не процедурным языком, а, скорее,
нотацией для описания типов объектов и связей между ними в терминах
конкретной модели данных. Язык определения данных используется при
разработке и модификации проекта базы данных. Он не служит для полу-
чения или модификации самих данных и почти всегда включает операторы,
описывающие (хотя и в несколько абстрактных терминах) физическую ор-
ганизацию базы данных. Детальный проект физической базы данных про-
дуцируется программами СУБД, обрабатывающими операторы языка опре-
деления данных1.
Для реализации большой базы данных проект концептуальной схемы
разрабатывается обычно администратором базы данных, чаще всего в
сотрудничестве с программистами и при консультации лиц, курирующих
создание базы данных, например управления компании. Используя язык
определения данных, администратор базы данных и его персонал специфи-
цируют концептуальную схему и ее реализацию как физическую базу
данных. С вводом базы данных в эксплуатацию администратор базы
данных становится ответственным за все операции, которые воздействуют
на базу данных в целом. Прн этом на него возлагаются следующие функ-
ции:
1. Создание подсхем для представлений.
1 В соответствии с концепциями СУБД с многоуровневой архитектурой определе-
ние среды хранения базы данных должно быть функцией специального языка. В под-
ходе КОДАСИЛ, например, для этой цели предусмотрен язык описания хранения
данных. — Примеч. ред.
15
2. Предоставление полномочий на использование базы данных или
определенных ее частей.
3. Модификация концептуальной схемы с целью устранения недостат-
ков первоначального проекта или в связи с изменением требований пред-
приятия.
4. Модификация реализации концептуальной схемы физической, если
сведения об использовании базы данных показывают, что другая органи-
зация была бы более эффективной.
5. Изготовление копий базы данных и восстановление ее при повреж-
дениях.
Для описания подсхем и их соответствия концептуальной схеме тре-
буется язык определения данных подсхемы, который часто оказывается
аналогичным языку определения данных, хотя в ряде случаев используе-
мая им модель данных отличается от модели данных языка определения
данных. В действительности может существовать несколько различных
языков подсхемы, основанных на различных моделях данных. Функция
(2) санкционирования доступа к базе данных требует применения специали-
зированного языка, описывающего желаемые привилегии и их получателей.
Этот язык может быть частью языка определения данных или языка мани-
пулирования данными. Функции (3) и (4) выполняются с использованием
языка определения данных, а функция (5), обеспечивающая надежность
системы, — с помощью особого инструментария, являющегося частью
СУБД.
Прикладные программы
Предположим, что разработан проект концептуальной схемы для авиа-
линии и принято решение о создании автоматизированной системы продажи
билетов. Подсхема для этой системы и ее смысл в терминах концептуаль-
ной схемы определяются персоналом прикладных программистов, а пол-
номочия на доступ к частям концептуальной базы данных, соответствую-
щим этому представлению, предоставляются администратором базы данных.
Цепочка абстракций иллюстрируется рис. 1.2.
—
Представление
Концептуальная
база данных
Физическая
база данных
Определение н отобра-
жение, записанные в
языке определения дан-
ных подсхемы
Определение и отобра-
жение, записанные в
языке определения дан-
ных
Рис. 1.2. Цепочка абстракций
Реализация на физиче-
ских устройствах
Теперь прикладные программисты готовы писать программы, аналогич-
ные упоминавшейся ранее программе BOOK, которые осуществляют за-
просы и манипулирование в терминах представления, а через него —
концептуальной и физической базами данных. Манипулирование, базой
данных требует применения специализированного языка, называемого
языком манипулирования данными или языком запросов, в котором можно
выразить, например, следующие команды:
1. Произвести выборку из базы данных числа свободных мест на рейс
999 на 20 июля.
16
2. Принять число свободных мест на рейс 123 на 31 августа равным 27.
3. Найти какой-либо рейс из ORD (аэропортО’ Хейр в Чикаго) в
JFK (аэропорт имени Джона Ф. Кеннеди в Нью-Йорке) на 24 августа.
4. Произвести выборку всех рейсов из ORD в JFK на 24 августа.
Не во всех языках манипулирования данными предусмотрена воз-
можность получения неопределенного количества данных в одном шаге.
Типичным представителем такого запроса является команда (4). В боль-
шинстве языков подается команда, подобная команде (3), позволяющая’
получить первый рейс. Затем следует команда вида едать следующий рейс-
из ORD в JFK на 24 августа», которая повторяется до тех пор, пока не.
будет получен ответ: «Рейсов больше нет».
Прикладная программа, как правило, должна не только осуществлять
простое манипулирование базой данных, но и решать ряд различных
Рис. 1.3. Данные, видимые прикладной программой
вычислительных задач. Например, программа BOOK должна выводить на
терминал и читать с терминала, принимать решения (счетчик.мест = 0 ?)
и выполнять арифметические действия (счетчик_мест = счетчик_мест— 1).
По этим причинам прикладная программа обычно пишется на общепри-
нятом языке программирования (например, на ПЛ/1 или Коболе), который
называется включающим языком. Она инициирует команды языка манипу-
лирования данными, вызываемые одним из двух следующих способов в за-
висимости от характеристик СУБД:
1. Команды языка манипулирования данными инициируются путем
вызова специальных процедур, предоставляемых СУБД. Эти процедуры
имеют доступ к определению подсхемы и концептуальной схемы. Необхо-
димое связывание может обеспечиваться операционной системой, в обста-
новке которой работает СУБД.
2. Команды являются операторами в некотором языке, который пред-
ставляет собой расширение включающего языка. В этом случае приклад-
ная программа пишется в расширенном языке. Результатом исполнения
команд языка манипулирования данными являются вызовы процедур,
предоставляемых СУБД. -
Как можно заметить, различия между подходами (1) и (2) невелики.
Представление данных, видимых прикладной программой, иллюстри-
руется рис. 1.3. Сплошными линиями на рисунке показаны передача дан-
ных и манипулирование данными, а пунктирными — причинная связь.
Таким образом, передачи данных между рабочей областью программы и
17
базой данных вызываются командами манипулирования данными, которые,
в свою очередь, инициируются прикладной программой. Передачи данных
и вычисления внутри рабочего пространства вызываются операторами при-
кладной программы, как и в любой ординарной ситуации в программиро-
вании.
Независимость данных
Цепочка абстракций на рис. 1.2 (представление — концептуальная
база данных — физическая база данных) обеспечивает два уровня «неза-
висимости данных». Очевидно, что администратор базы данных может из-
менять физическую схему, не изменяя концептуальной схемы и не требуя
переопределения подсхем. Этот вид независимости называется физической
независимостью данных. Нетрудно видеть, что модификации в организации
физической базы данных могут повлиять на эффективность прикладных
программ. Однако никогда не потребуется переписывать эти программы
только в связи с изменением реализации концептуальной схемы физичес-
кой. Таким образом, создается возможность «настраивать» физическую
базу данных для достижения эффективности и вместе с тем исполнять при-
кладные программы так, как будто никаких изменений не произошло.
Второй вид независимости, обеспечиваемый связью между представле-
ниями и концептуальной базой данных, — логическая независимость дан-
ных. По мере использования базы данных может потребоваться модифика-
ция концептуальной схемы, например, с целью включения информации о
новых типах объектов или дополнительной информации об уже представлен-
ных в ней объектах. Так, может возникнуть необходимость в том, чтобы
авиалиния предоставляла агентству по охране окружающей среды данные
об уровнях шума и загрязнения атмосферы на своих рейсах, в то время как
информация по этому вопросу в настоящее время отсутствует в базе данных
и, следовательно, должна быть в нее добавлена. Одни модификации концеп-
туальной схемы можно выполнить, не затрагивая существующих подсхем,
другие же становятся возможными, если переопределить отображение
подсхемы в концептуальную схему. При этом также не требуется каких-
либо изменений в прикладных программах. Единственный вид изменений
в концептуальной схеме, который не может быть осуществлен путем пере-
определения соответствия между подсхемой и концептуальной схемой, —
это удаление информации, соответствующей представленной в подсхеме.
Такие изменения, естественно, требуют переработки некоторых приклад-
ных программ или отказа от них.
1.4. МОДЕЛЬ РЕАЛЬНОГО МИРА
Приведенный краткий обзор функциональных возможностей СУБД
порождает ряд важных вопросов, которые мы должны рассмотреть в сле-
дующих главах, в частности:
1. Каковы структуры данных, подходящие для реализации типичной
физической базы данных?
2. Какими свойствами обладают модели данных и как они должны быть
представлены физическими структурами?
Чтобы ответить на эти два вопроса, мы должны понимать, какого рода
информацию потребуется хранить в системе базы данных. Введем нефор-
мальную модель данных, называемую моделью объектов-связей. Эта мо-
дель не относится к числу моделей данных; использованных в существую-
18
щих языках определения данных, хотя и тесно связана с некоторыми из
них. В настоящей работе она служит, скорее, для обоснования видов
структур и моделей данных, которые мы введем позднее, поскольку спо-
собность таких структур и моделей представлять структуры объектов-
связей очевидна. Интуитивно ясно также, что модель объектов-связей
выполняет (правда, не идеальным образом) адекватные функции ио модели-
рованию объектов реального мира, таких, как коммерческое предприятие
или документы, хранимые в школах, госпиталях, правительственных
учреждениях и т. д., где должны, по всей вероятности, применяться систе-
мы баз данных. Однако, если мы будем рассматривать структуры, определен-
ные в модели объектов-связей как концептуальные схемы1, мы не допустим
грубой ошибки.
Объекты
Термин «объект» не поддается всеобъемлющему определению. Достаточ-
но сказать, что объект — это нечто существующее и различимое, т. е. мы
можем отличать один объект от другого. Например, каждый стул есть объект.
Объектами являются также конкретные человек и автомобиль. Можно'
считать объектом любого муравья, если имеется способ отличать его от.
других муравьев. В противном случае мы не воспринимаем муравья как
объект. Объектами могут быть и понятия более высокого уровня, например
паук, грызун, бабуин и растение в биологической базе данных. Если не
быть слишком строгими, то к объектам можно отнести и такие понятия, как.
любовь и ненависть.
Группа всех подобных объектов образует набор объектов. Так, набора-
ми объектов могут быть:
1. Все люди. 3. Все автомобили.
2. Все животные. 4. Все эмоции.
Примеры 1 и 2 показывают, что термин «подобные объекты» не являет-
ся точно определенным, и можно установить бесконечное число различных
свойств, которые будут определять набор объектов. Один из ключевых мо-
ментов в проектировании модели реального мира, имеющий отношение к.
конкретной базе данных, —это выбор наборов объектов.
Атрибуты и ключи
Объекты обладают свойствами, называемыми атрибутами, которые ас-
социируют некоторое значение из домена значений данного атрибута с
каждым объектом в наборе объектов. Обычно домен атрибута является
множеством целых чисел, действительных чисел или строк литер, но мы
не исключаем и другие типы значений. Например, можно сказать, что
объекты в наборе объектов «люди» имеют такие атрибуты, как имя (строка
литер), рост (действительное число) и т. д.
Выбор подходящих атрибутов для наборов объектов является вторым
ключевым моментом в проектировании модели реального мира. Атрибут
или множество атрибутов, значения которых уникально идентифицируют
каждый объект в наборе объектов, называется ключом этого набора объек-
тов. В принципе, каждый набор объектов имеет ключ, поскольку мы при-
няли гипотезу о том, что каждый объект отличим от остальных. Но если
для набора объектов мы выбрали совокупность атрибутов, не содержащую
1 Строго говоря, понятия схемы базы данных н структуры базы данных не экви-
валентны. Схема определяет структуру базы данных и ряд других ее характеристик. —
Примеч. ред.
19
ключа, то отличить один объект в наборе от другого окажется невозмож-
ным. Часто в качестве атрибута, который служит ключом, предоставляет-
ся произвольно выбранный последовательный номер. Например, в наборе
объектов, включающем только граждан США, может использоваться в
качестве ключа единственный атрибут — «номер социальной безопасности».
Возможны случаи, когда объекты в наборе различаются не по атрибу-
там, а по их связи с объектами другого типа. Наиболее важным видом
«встроенных» связей (связи, определенные пользователем, будут описаны
позднее) является связь есть1. Мы говорим А есть Ви записываем «А есть
В», если набор объектов В является обобщением набора объектов А, или,
что равносильно, А есть специальный вид В.
Пример 1.2. Рассмотрим базу данных автомобилей с набором объектов МАР-
КИ, имеющим атрибуты ТИП и МОДЕЛЬ. Объектом в наборе МАРКИ является,
например, «Datsun-280». Мы могли бы рассмотреть н набор объектов АВТОМОБИЛИ
с атрибутом СЕРИЙНЫЙ— НОМЕР, который можно было бы считать ключом этого
набора. Однако вполне вероятно, что два типа автомобилей используют одни и те же
серийные номера. Чтобы сделать объекты в наборе АВТОМОБИЛИ уникальными,
нам потребуется связь между наборами АВТОМОБИЛИ и МАРКИ, представляющая
тот факт, что любой автомобиль имеет конкретную марку. Тогда каждый экземпляр из
набора объектов АВТОМОБИЛИ будет однозначно определяться по его СЕРИЙНОМУ—
НОМЕРУ и атрибуту ТИП связанного с ним объекта из набора МАРКИ.
Пример 1.3. Проиллюстрируем связь есть на примере базы данных авиа-
линии, рассмотренном выше. Нам может потребоваться набор объектов СЛУЖАЩИЕ с
атрибутом НОМЕР—СЛУЖАЩЕГО — уникальным номером каждого служащего.
Вероятно, потребуется и другой набор объектов— ПИЛОТЫ. Очевидно, ПИЛОТЫ
есть СЛУЖАЩИЕ. Набор объектов ПИЛОТЫ может не содержать никаких атрибутов,
но иметь связь с набором объектов ТИПЫ- САМОЛЕТОВ, указывающую, кто из
пилотов допущен к полетам на Боинге-747, ДС-10, и т.д. Однако поскольку любой
пилот является служащим, связь есть от набора ПИЛОТЫ к набору СЛУЖАЩИЕ
обеспечивает уникальный идентификатор каждого пилота—НОМЕР—СЛУЖАЩЕГО.
Связи
Связь между наборами объектов представляет собой просто упорядо-
ченный список наборов объектов. Конкретный набор объектов может поя-
вляться в этом списке более одного раза. Если имеется связь REL между
наборами объектов Ег, Е2, ..., Eh, то предполагается, что существует
множество кортежей размерности k, имя которого REL. Такое множество
мы называем набором связей. Каждый кортеж (elt е2, ..., ek) в множестве
REL подразумевает, что объекты elt е2, .... ek, где ех принадлежит на-
бору Ег, е2 — набору Е2 и т. д., находятся в связи REL друг с другом
как группа. Наиболее общим, несомненно, является случай, когда k — 2,
но иногда списки состоят из трех или более наборов объектов.
Пример 1.4. Допустим, мы имеем набор объектов ЛЮДИ и связь ЯВЛЯЕТ-
СЯ— МАТЕРЬЮ, список наборов объектов которой есть ЛЮДИ, ЛЮДИ. Мы предпо-
лагаем, что набор связей ЯВЛЯЕТСЯ- МАТЕРЬЮ включает все пары (рх, р2), такие,
что человек р2 является матерью человека рх.
Альтернативный способ представления этой информации заключается в том,
чтобы постулировать существование набора объектов МАТЕРИ и связи МАТЕРИ есть
ЛЮДИ. Такой способ оказался бы более приемлемым, если бы в базе данных хранились
значения атрибутов матерей, которые не хранятся для людей вообще. Тогда связь
ЯВЛЯЕТСЯ— МАТЕРЬЮ была бы представлена списком наборов объектов ЛЮДИ и
МАТЕРИ и, чтобы получить информацию о матери какого-либо человека как о челове-
ке, нам потребовалось бы образовать (в смысле обычных теоретико-множественных
отношений) связи ЯВЛЯЕТСЯ- МАТЕРЬЮ и есть.И
1 В оригинале «isa» — отношение обобщения, используемое в теории семантических се-
тей. — Примеч. ред.
20
Вид функциональной зависимости
Для эффективной реализации базы данных часто оказывается необхо-
димой классификация связей в соответствии с тем, сколько объектов из
одного набора может ассоциироваться и со сколькими объектами из друго-
го набора. Простейшей и наиболее редкой формой связи двух наборов
объектов является связь «один к одному», при которой для каждого объек-
та в одном из наборов существует в лучшем случае один ассоциированный
с ним объект другого набора. Примером такой ситуации может служить
связь ЯВЛЯЕТСЯ- РУКОВОДИТЕЛЕМ между двумя наборами объектов
СЛУЖАЩИЕ и ОТДЕЛЫ в базе данных некоторой фирмы. Можно пред-
положить, что эта связь, указывающая руководителя для каждого отдела,
является связью вида «один к одному». Заметим, что указанное свойство
есть не что иное, как предположение о реальном мире, которое проектиров-
щик базы данных может по своему выбору принять или не принять. В рас-
сматриваемом случае более правдоподобным было бы, вероятно, предполо-
жение, что один и тот же человек может руководить двумя отделами или
даже что. отдел имеет двух руководителей. Однако, если в данной органи-
зации принято назначать для каждого отдела своего руководителя, то при
проектировании физической базы данных можно воспользоваться тем
фактом, что ЯВЛЯЕТСЯ-РУКОВОДИТЕЛЕМ представляет собой
связь «один к одному». Заметим также, что этот вид связи не подразуме-
вает обязательного существования для каждого объекта одного набора
связанного с ним объекта из другого набора. Например, большинство
служащих, конечно, не являются руководителями какого-либо отдела, и
могут иметься отделы, которые в настоящее время не имеют руководителя.
Гораздо чаще встречается связь вида «многие к одному», при которой
каждый объект в наборе £2 ассоциируется с нулем или более объектов в
наборе Ег, но каждый объект в Ех ассоциируется на более чем с одним
объектом в Е2. Говорят, что эта связь является связью вида «многие к од-
ному» от Ех к Е2, т. е. (частичной) функцией от Et к Е2. Например, если
каждый курс ведется одним преподавателем, то имеется связь вида «мно-
гие к одному»: ЧИТАЮТСЯ от набора объектов КУРСЫ к набору объектов
ПРЕПОДАВАТЕЛИ.
Можно обобщить концепцию «многие к одному». Если существует не-
которая связь между наборами объектов Ег, Е2, ..., Е^м. для данных объек-
тов из всех наборов, кроме Et, имеется по крайней мере один связанный
объект из набора Е,, то мы говорим, что эта связь есть связь вида «мно-
гие к одному» от Е1г .... Ei_lt Ei+1,...,Ek к Е,.
Нередко приходится иметь дело также со связью вида «многие ко многим»,
при которой отсутствуют ограничения на множества пар объектов, при-
надлежащих набору связей. Но эта форма связи оказывается трудно под-
держиваемой в двух основных моделях данных — сетевой и иерархичес-
кой. Примером связи «многие ко многим» является связь ЭКСПОРТИРУЮТ
между наборами объектов СТРАНЫ и ПРОДУКТЫ, поскольку страна
обычно экспортирует более одного продукта и несколько продуктов экспор-
тируются одной единственной страной.
Пример 1.5. Спроектируем (в некоторой степени) полную базу данных для
авиалинии, используя модель объектов-связей. Ниже мы перечислим наборы объектов
и их атрибуты. Домен каждого атрибута объявляется так же, как в типичном языке
программирования: CHAR (и) означает строку литер длины п, alNT-(zi)—целое число,
состоящее не более чем из п цифр. Комментарии ограничиваются комбинациями лп
тер «/*» и «*/».
1. Набор объектов ПАССАЖИР с атрибутами;
ИМЯ CHAR (30)
АДРЕС CHAR (30)
ТЕЛЕФОН ШТ (10)
Совокупность атрибутов ИМЯ и АДРЕС образует ключ этого набора объектов.
2. Набор объектов РЕЙС с атрибутами:
НОМЕР _ РЕЙСА ШТ (3)
АЭРОПОРТ- ВЫЛЕТА CHAR (3)/*все коммерческие
аэропорты в США имеют
трехбуквенные коды, на-
пример LAX, SFO, ORD,
JFK*/
АЭРОПОРТ-НАЗНАЧЕНИЯ CHAR (3)
ВРЕМЯ-ВЫЛЕТА INT (4) /*время вылета дается
в часах и минутах*/
ВРЕМЯ-ПРИБЫТИЯ ШТ (4)
Мы предполагаем для простоты, что рейсы беспосадочные, хотя на практике-
авиалинии часто используют один и тот же номер для последовательности участков,
рейса. Атрибут НОМЕР- РЕЙСА является здесь ключом. Для этой цели может при-
меняться также пара АЭРОПОРТ- ВЫЛЕТА и ВРЕМЯ- ВЫЛЕТА. На практике был
бы выбран один ключ (в данном случае, вероятно, НОМЕР- РЕЙСА, поскольку он
является однокомпонентным), который бы назывался просто «ключом».
3. Набор объектов ВЫЛЕТ с атрибутом
ДАТА ШТ (3) /* предполагается,
что даты нумеруются с
начала года и что ин-
формация о рейсах хра-
нится не более года.
Например, дата 33 —
это 2. февраля */
Каждый объект здесь представляет собой конкретный рейс на конкретную дату.
Атрибут ДАТА сам по себе не определяет какой-либо объект этого набора. Позднее мы
введем связь ВЫПОЛНЯЕТ между наборами ВЫЛЕТ и РЕЙС с тем, чтобы полностью
определить объекты набора ВЫЛЕТ.
4. Набор объектов МОДЕЛЬ_САМОЛЕТА с атрибутами:
ИЗГОТОВИТЕЛЬ CHAR (10)
НОМЕР-МОДЕЛИ CHAR (10)
Эти два атрибута вместе образуют ключ.
5. Набор объектов САМОЛЕТ с атрибутами
ПОРЯДКОВЫЙ-НОМЕР ШТ (5)
Мы считаем, что порядковый номер назначается авиалинией и служит ключом для
каждого самолета компании. Заметим, что набор объектов МОДЕЛЬ- САМОЛЕТА
состоит из родовых понятий, таких, как «Боинг-747», а не из индивидуальных самоле-
тов, которые принадлежат набору САМОЛЕТ.
6. Набор объектов ПЕРСОНАЛ с атрибутами:
НОМЕР _ СЛУЖАЩЕГО ШТ (6)
ИМЯ CHAR (30)
АДРЕС CHAR (30)
ЗАРПЛАТА INT (6)
Здесь НОМЕР- СЛУЖАЩЕГО является ключом для набора объектов ПЕРСО-
НАЛ. Тот факт, что и ПЕРСОНАЛ и ПАССАЖИР имеют атрибуты ИМЯ и АДРЕС,
здесь несуществен.
7. Набор объектов ПИЛОТ — без атрибутов. Для идентификации пилотов исполь-
зуется связь ПИЛОТ есть ПЕРСОНАЛ. Причина, по которой набор ПИЛОТ выбран
22
а качестве отдельного набора объектов, заключается в том, что он может быть связан
с набором МОДЕЛЬ- САМОЛЕТА связью ДОПУЩЕН-К- ПОЛЕТАМ. В то же время
поддержание этой информации и для нелетного персонала привело бы к неэффективно-
му использованию пространства в базе данных.
Существуют н другие связи между наборами объектов в рассматриваемой базе
данных;
1. Связь вида «многие ко многим» КУПИЛ- БИЛЕТ- НА между наборами ПАС-
САЖИР и ВЫЛЕТ, указывающая бронированные места.
2. Связь ВЫПОЛНЯЕТ вида «многие к одному» от набора ВЫЛЕТЫ к набору
РЕЙСЫ. Здесь каждый вылет имеет единственный номер рейса, хотя одни и тот же
номер рейса используется изо дня в день.
3. Связь вида «многие ко многим» НАЗНАЧЕН- НА между наборами ПЕРСОНАЛ
и ВЫЛЕТ, указывающая экипаж для каждого вылета.
4. Другая связь вида «многие ко многим» ДОПУЩЕН- К- ПОЛЕТАМ между на-
борами ПИЛОТ и МОДЕЛЬ- САМОЛЕТА.
5. Связь ТИП вида «многие к одному» между наборами САМОЛЕТ и МОДЕЛЬ-
САМОЛЕТ А, указывающая общий тип каждого самолета. Здесь каждый самолет
имеет один общий тип, но авиакомпания может владеть, например, многими самолета-
ми типа ДС-10.Н
Диаграммы объектов-связей
Весьма полезно суммировать информацию в проекте, используя диаг-
раммы объектов-связей. На таких диаграммах применяются следующие
обозначения:
1. Прямоугольники представляют наборы объектов.
2. Овалы представляют атрибуты. Они связываются со своими набора-
ми объектов (ненаправленными) ребрами.
Рис. 1.4. Диаграмма объ-
ектов-связей материнст-
ва
3. Ромбы представляют связи. Они соединяются с составляющими их
наборами объектов ненаправленными ребрами. С целью указания порядка
наборов объектов в списке для данной связи ребра могут нумероваться,
хотя это имеет значение лишь тогда, когда один и тот же набор объектов
появляется в списке более одного раза. Однако при связи вида «многие к
одному» от Л к В мы проводим дугу (направленное ребро) к В. В общем
случае, если связь вовлекает три и более наборов объектов и имеет вид
«многие к одному» для некоторого набора объектов А, мы проводим дугу
к Л и ненаправленные ребра к другим наборам объектов. Сложные отобра-
жения вида «многие к одному» для нескольких наборов объектов не пред-
ставляются с помощью такого соглашения о ребрах. При связи вида «один
к одному» показывается ребро со стрелками на концах. В виде исключения,
если А есть В, мы проводим дугу только к В.
П р и м е р 1.6. Диаграмма для набора объектов ЛЮДИ со связью ЯВЛЯЕТСЯ—
МАТЕРЬЮ (из примера 1.4) показана на рис. 1.4.
На рис. 1.5 приведена диаграмма для схемы базы данных из примера 1.4.|
УПРАЖНЕНИЯ
1.1. Многие языки программирования могут рассматриваться какоснованные на
некоторой конкретной модели данных. Например, можно считать, что Снобол исполь-
зует модель данных литерных строк. Считаете ли вы, что другие языки программиро-
23
ваиия также используют конкретную модель данных? Что это за модель данных?
Удобен ли какой-либо из этих языков для реализации базы данных?
1.2. Предположим, что в концептуальной схеме некоторой предметной области
имеется атрибут ДАТА, который принимает целочисленные значения от 1 до 366.
Допустим также, что мы хотим сконструировать представление, которое включает атри-
буты МЕСЯЦ и ДЕНЬ. Как определить эти атрибуты в терминах атрибута ДАТА в
концептуальной схеме?
1.3. Допустим, что мы неформально определяем данные в базе данных отделов,
универмага. При этом:
а) представляется каждый служащий. Данными о служащем являются его номер,,
фамилия, адрес н отдел, в котором он работает;
Рис. 1.5. Диаграмма объектов-'связей для базы данных авиалинии
б) представляется каждый отдел. Данными об отделе являются его служащие
руководитель и продаваемые товары;
в) представляется каждый продаваемый товар. Данными о товаре являются его
наименование, изготовитель, цена, номер модели (присвоенный изготовителем) и внут-
ренний номер товара (присвоенный универмагом);
г) представляется каждый изготовитель. Данными об изготовителе являются-его-
название, адрес, товары, поставляемые в универмаг, и их цены.
Постройте для этой базы данных диаграмму объектов-связей. Заметим, что одна,
информация может быть представлена атрибутами, а другая — связями.
1.4. Укажите для диаграммы объектов-связей из упражнения 1.3:
а) ключ каждого набора объектов;
б) связи видов «один к одному» и «многие к одному».
Назовите любые сделанные вами предположения, которые могут или не могут
поддерживаться в зависимости от факторов, не указанных в упражнении 1.3.
*1 .5. Модифицируйте концептуальную схему базы данных авиалиний (пример
1.5) так, чтобы рейсы могли состоять более чем нз одного участка, т. е. чтобы кроме
24
аэропортов вылета и назначения рейс мог иметь ассоциированный с ним список горо-
дов.
1.6. Приведите диаграмму объектов-связей для генеалогической базы данных,
демонстрирующей связи отцовства, материнства и супружества.
1.7. Используйте модель объектов-связей для описания данных, имеющих отно-
шение к хорошо знакомой вам организации, например школе или фирме.
Библиографические замечания
Три уровня абстракции (физический—концептуальный—представление) были
предложены в отчете CODASYL DBTG 1971 г.1 [39]. Они являются также центральной
идеей отчета ANS1/SPARC 1975 г. [7], где они называются соответственно внутренним,
концептуальным и внешним уровнями. Работа Цикритзиса и Клуга [172] является
неформальным введением к пересмотренной версии этого отчета. Три уровня абстрак-
ции представлены в большом числе существующих систем баз данных. Некоторые из
этих систем описываются в гл. 4, 7 и 8. Модель объектов-связей детально обсуждается
в работе Чена [35].
Было описано множество других моделей. Одна из наиболее ранних моделей
предложена Бахманом [12]. Читатель, желающий получить детальную информацию
по данному вопросу, может познакомиться с книгами Найсена [125], Дука и Най-
сена [61], Цикритзиса и Лоховского [177] или со статьями Найсена [124] н Кершберга,
Клуга и Цикритзиса [99].
1 Точнее, они были предложены впервые в предыдущем отчете CODASYL DBTG,
опубликованном в октябре 1969 г. — Примеч. ред.
25
ГЛАВА 2
ФИЗИЧЕСКАЯ ОРГАНИЗАЦИЯ ДАННЫХ
Прежде чем перейти к обсуждению различных уровней абстракции
баз данных, используемых при их проектировании, необходимо хорошо
уяснить, что легко выполнить на физическом уровне, а что — трудно.
Основная проблема в физическом представлении базы данных — это хра-
нение файла, содержащего записи с идентичным форматом. Формат записи
представляет собой список имен полей, причем каждое поле занимает
фиксироваииое число байтов и имеет фиксированный тип данных. Запись
состоит из значений каждого поля. Над файлом требуется выполнять сле-
дующие типичные операции:
1. Включить запись.
2. Удалить запись.
3. Модифицировать запись.
4. Найти запись с конкретным значением в конкретном поле или с
некоторой комбинацией значений в комбинации полей.
Сложность организации хранения файла зависит от конкретной ком-
бинации операций, которые мы намерены выполнять над ним. Если
допускается, операция 4, называемая поиском, что чаще всего действитель-
но имеет место, мы должны также рассмотреть, специфицируются ли иско-
мые записи значениями данных, адресом или их комбинацией и может ли
участвовать в различных операциях поиска только одно или несколько
различных полей. Основные методы организации файлов приводятся в
разд. 2.2 — 2.5. Далее в разд. 2.6 описывается хранение файлов, записи
которых могут содержать более одного значения какого-либо поля. Такие
записи мы называем записями переменной длины. Наконец, в разд. 2.7 и
2.8 обсуждаются методы организации файлов, обеспечивающие выполнение
некоторых более общих видов поиска.
2.1. МОДЕЛЬ ОРГАНИЗАЦИИ ВНЕШНЕЙ ПАМЯТИ
Когда говорят о «внешней» или «вторичной» памяти, обычно имеют в
виду дисковую память, хотя все, о чем здесь пойдет речь, относится также
к барабанам и, в меньшей степени, к магнитным лентам или более новым
видам динамической памяти, таким, как магнитные пузырьковые запоми-
нающие устройства или запоминающие устройства с зарядовой связью.
Файловые системы, использующие дисковую память, обычно разделяют
диск на физические блоки равного размера. Типичный размер физического
блока от 2е до 212 байт, но в дальнейшем изложении мы не будем фиксиро-
вать какой-либо конкретный его размер (кроме примеров). Каждый физи-
ческий блок (или просто блок) имеет адрес, который является абсолютным
адресом на диске или другом запоминающем устройстве.
26
Файл хранится в одном или более блоках, причем в каждом блоке
могут храниться несколько записей. Внутри блока могут оставаться бай-
ты, не занятые какой-либо записью. Мы предполагаем, что существует
некоторая файловая система, которая способна установить соответствие
между именами файлов и абсолютными адресами их блоков.
Запись имеет адрес, который может рассматриваться либо как абсо-
лютный адрес ее первого байта, либо как адрес блока, в котором она содер-
жится, вместе со смещением — числом байтов в блоке, предшествующих
началу этой записи.
Указатели
Мы часто будем иметь ^ело с указателями1 на записи или блоки. Указа-
тель иа блок может быть его абсолютным адресом. Иногда вторичная па-
мять организуется как виртуальная, и на блоки или записи можно ссылать-
ся, задавая их смещение от начала воображаемой области виртуальной
памяти2. При этом соответствие между смещениями в дайной области и
абсолютными адресами устанавливается файловой системой. Другой воз-
можный способ ссылки на запись заключается в том, чтобы указывать на
ее блок. В таком случае необходимо уметь находить требуемую запись в
блоке после того, как найден сам блок, т. е. мы должны обладать некото-
рой информацией о записи, чтобы идентифицировать ее. Подобная ситуация
возникает довольно часто, и нам следует это учитывать. Преимущество
указаниЯ”'На блоки заключается в том, что записи могут перемещаться
внутри блоков. Однако при этом не возникают ситуации, когда указатели
«зависают» (т. е. указывают не на то место, где в самом деле находится
запись).
Оценка быстродействия операций над базой данных
Основная операция внешней памяти — передача блока из вторичной
памяти в главную и наоборот. Мы называем эту операцию доступом к блоку.
Важно отметить, что в большинстве современных систем передача данных,
8 которой участвует вторичная память, требует обычно столько же или
более времени, чем поиск требуемых данных в блоке, когда он уже находит-
ся в основной памяти. К тому же во всех системах, кроме некоторых гипо-
тетических или экспериментальных, данные необходимо иметь в основной
памяти прежде, чем они могут быть использованы каким-либо способом.
Таким образом, когда мы говорим о быстродействии различных алгорит-
мов доступа к данным, следует подсчитывать число блоков, которые долж-
ны быть прочитаны в основную память или записаны из иее. Это число и
будет представлять нашу оценку быстродействия алгоритма.
Интерпретация первичных данных
При простейшей организации мы предполагаем, что каждый файл
имеет фиксированный формат записи, хотя в дальнейшем будут рассмот-
рены и более сложные файлы. Поля появляются в каждой хранимой запи-
си файла в одном и том же порядке, и для каждого из них предусмотрено
1 Наряду с термином «указатель» (pointer) в литературе часто используется в
том же смысле термин «ссылка» (refference). — Примеч. ред.
2 Такая область может рассматриваться как большая память произвольного дос-
тупа, где байты нумеруются от нуля до некоторого максимального числа.
27
соответствующее число байтов, которое не изменяется от записи к записи.
Любому полю соответствует также некоторый тип данных (такой, как
строка литер, действительное или целое число), который позволяет интер-
претировать его биты. При этих Предположениях мы можем однозначно
декодировать записи, если они размещаются с начала блока (или начиная
с некоторой фиксированной точки вблизи начала блока, когда несколько
байтов оставляется для другой информации).
Единственная проблема заключается в том, чтобы отличать записи от
свободного пространства, поскольку мы не можем предположить, что блок
всегда целиком заполнен записями. Одно из возможных решений — по-
местить счетчик числа записей в заголовок блока (фиксированное число
байтов в начале каждого блока, используемое для счетчика или какой-либо
другой информации). При этом в блоке сможет находиться любое возмож-
ное число записей. Позднее мы обсудим и некоторые альтернативные под-
ходы.
Ключи
Если вспомнить модель объектов-связей, рассмотренную в разд. 1.4,
то можно заметить, что файлы используются для хранения информации
двух типов:
1. Наборы объектов. Здесь каждая запись представляет собой объект,
а поля соответствуют его атрибутам.
2. Связи. Если используется связь «многие ко многим», мы можем
представить ее с помощью файла, состоящего из записи с двумя полями
(или с k полями, если мы имеем связь между k наборами объектов). Каж-
дому из этих полей соответствует тип данных — указатель. В случае свя-
зи между двумя наборами объектов любая запись состоит из пары указате-
лей (ръ р2)< гДе Pt указывает на запись об объекте из первого набора, а
р2 — на связанную с ней запись об объекте второго набора. При связи
«один к одному» или «многие к одному» возможны и другие представления,
которые будут обсуждаться позднее.
Между этими двумя типами файлов существует важное различие.
Оно заключается в том, что первый из них имеет нетривиальный ключ —
одно или более полей, совокупность которых уникально идентифицирует
запись, в то время как второй не обязательно обладает ключом, отличным
от множества всех полей. Очень часто запросы к файлу представляются в
следующей форме: найти запись при заданном значении поля или полей в
ключе1. Подобные запросы обычно обрабатываются легче, чем запросы более
общего вида. Именно поэтому мы начнем рассмотрение реализации фай-
лов с файлов такого рода.
Закрепленные и незакрепленные записи
Для определения стратегии реализации файлов важно, являются ли
записи файла «закрепленными» по фиксированному адресу. Записи стано-
вятся закрепленными, если где-либо в базе данных могут существовать
указатели на них. Например, мы упоминали выше о реализации отображе-
ний, при которой соответствующие объекты представлялись парой указа-
телей на записи о них. В разд. 1.4 обсуждалась также возможность уни-
1 Большая часть материала настоящего раздела не основывается на концепции
ключа, уникально определяющего запись. Мы могли бы точно так же запросить все
записи, соответствующие значению «ключа», и осуществить поиск при небольших до-
полнительных затратах.
28
калькой идентификации объекта только с помощью связи с некоторым дру-
гим объектом, причем запись о первом объекте должна иметь указатель на
запись о последнем. В таких ситуациях мы не сможем перемещать записи
об этих объектах, поскольку иначе указатели «зависнут», т. е. никогда не
будут более указывать на данные, на которые они указывали первоначаль-
но.
В самом общем случае организация файлов, при которой записи пере-
мещаются (например, при включении других записей), не может быть ис-
пользована, поскольку трудно предположить, где именно в полной базе
данных находится указатель или несколько указателей на запись. Настоль-
ко же опасным является удаление записей, так как должны быть найдены
любые указатели на них или должно допускаться их «зависание». К счастью,
исследуя общую организацию базы данных, мы в состоянии обнаружить
конкретный файл, на записи которого не ссылаются какие-либо указатели.
Для такого файла в нашем распоряжении имеются несколько более гибкие
формы организации, чем те, при которых записи закрепляются за их пер-
воначальным адресом.
Организации файлов в виде кучи
Наибо-лее очевидный подход к хранению записей файлов заключается
в последовательном-'размещении их в необходимом числе блоков, хотя
обычно не допускается, чтобы записи перекрывали границы блоков. Эту
организацию называют кучей в тех случаях, когда ее необходимо как-то
назвать. Блоки, используемые для кучи, могут быть связаны указателями.
При другом подходе предусматривается хранение таблицы их адресов.
Для этой цели может применяться, в частности, один или более дополни-
тельных блоков. Чтобы включить запись, ее необходимо поместить в
последний блок, если в нем имеется место, или получить новый блок,
если места больше нет. Удаления могут осуществляться установкой бита
удаления в удаляемой записи. Повторное использование пространства уда-
ленных записей для хранения вновь включаемых на их место записей яв-
ляется опасным, если существуют указатели на записи. Однако, если мы
уверены в том, что записи в файле являются незакрепленными, для отсле-
живания повторно используемого пространства можно применить одну из
ряда стратегий «сборки мусора» (см., например, Кнут [100]).
При заданном значении ключа поиск записи файла, организованного
в виде кучи, требует его полного просмотра или по крайней мере просмотра
половины файла (в среднем). Стоимость такой операции чрезмерно высо-
ка, если файл в запросе обладает большим числом блоков. Далее в этой
главе рассматриваются в основном альтернативные способы организации
файлов, которые допускают произвольный поиск с просмотром, возможно,
лишь их небольших фрагментов. При проектировании лучшей организации
файла мы должны попытаться избежать использования слишком боль-
шого дополнительного пространства и воздержаться от излишнего услож-
нения операций включения и удаления. В следующих четырех разделах
описываются некоторые идеи в этой области.
2.2. ХЕШИРОВАННЫЕ ФАЙЛЫ
Основная идея, лежащая в основе организации файлов с хеширован-
ным доступом, состоит в разделении записей файла между участками,
каждый из которых содержит один или более блоков памяти. Для любого
29
файла, хранимого таким образом, существует хеш-функция h, которая
использует в качестве аргумента значения ключа файла и продуцирует
целое число от нуля до некоторого максимального значения. Допустим,
что v есть значение ключа. Тогда h (о) указывает номер участка, в котором
должна находиться запись с этим значением ключа, если она присутствует
вообще.
Желательно, чтобы h «хешировала» v, т. е. чтобы h(v) принимала все
ее возможные значения примерно с равной вероятностью, когда v пробе-
гает совокупность значений ключа. О подходящих хеш-функциях говорилось
много, поэтому мы не будем всесторонне обсуждать здесь этот вопрос. Во
многих ситуациях полезна следующая стратегия:
Рис. 2.1. Организация
хешированного файла
1. Интерпретируем значения ключа как последовательность битов,
сформированную путем конкатенации значений всех полей ключа. Эта
последовательность имеет фиксированную длину, поскольку каждое поле
имеет фиксированную длину.
2. Делим последовательность битов на группы, состоящие из фикси-
рованного числа битов, например из шестнадцати. Последнюю группу
при необходимости дополняем нулями.
3. Складываем группы битов как целые числа.
4. Делим сумму на число участков и используем остаток как номер
участка.
На рис. 2.1 представлена организация хешированного файла с В участ-
ками. Показан также справочник участков, состоящий из В указателей:
по одному иа участок. Каждый указатель является адресом первого блока
данного участка.
Участок, содержащий только один блок, например участок 1, имеет
в этом блоке заголовок с null-указателем1, значение которого не может
быть адресом какого-либо блока. Участок, состоящий более чем из одного
блока, содержит в заголовке первого блока указатель на второй блок, в
заголовке второго блока — указатель на третий блок и т. д. Заголовок
последнего блока включает null-указатель. Так, участок В—1 на рис. 2.1
состоит из блоков Ь4, Ь5 и Ьв.
1 Указатель, имеющий неопределенное значение. — Примеч. ред.
30
Если В мало, справочник участков может находиться в основной па-
мяти. В противном случае он хранится в требуемом числе блоков, и блок
справочника участков, содержащий указатель на первый блок участка i,
будет вызываться в основную память, когда в результате хеширования
окажется вычисленным значение i.
В каждом блоке предусмотрено место для размещения фиксированно-
го числа записей. Если запись требует г байт, то предполагается, что-
каждая запись начинается со смещением, кратным г байт, от первого байта,,
следующего за заголовком блока. Пространство, используемое для хране-
ния одной записи, называется субблоком. При некоторых обстоятельствах
первые г байт могут быть свободными, в то время как последующий суб-
блок из г байт содержит некоторую запись. Необходимо как-то различать,
заполненные и свободные субблоки из г байт. Возможный, но опасный
метод заключается в том, что в свободный субблок помещается последова-
тельность бит, не являющаяся реальной записью. Мы должны знать для
этого последовательность бит, которая и в настоящее время, и в будущем
не будет представлять значение какой-либо записи. Существует более
безопасный метод, и именно этим методом мы воспользуемся в дальнейшем.
В заголовок блока помещается один бит для каждого субблока. Его нуле-
вое значение указывает, что субблок свободен, а единичное — что он со-
держит некоторую запись. Иногда полезно поместить в саму запись бит-
удаления, указывающий, была ли удалена запись. Тогда есть возможность
избежать повторного использования субблоков, на которые могут иметься
зависшие указатели.
Поиск
Предположим, что имеется значение v единственного поля ключа. В
том случае, когда ключ состоит более чем из одного поля, v является списком
значений полей ключа в фиксированном порядке. Вычислим h (v), которая
даст нам номер участка, например i. Далее обратимся в справочник участ-
ков и найдем первый блок участка i. После этого необходимо исследовать
каждый заполненный субблок в блоке и выяснить, содержит ли он запись
со значением ключа v. Положительный результат означает, что мы нашли
требуемую запись. Если же запись не найдена и заголовок блока имеет
указатель на дальнейшие блоки в участке I, исследуем каждый из этих
блоков поочередно. Процесс продолжается до тех пор, пока либо не будет
найдена запись со значением ключа v, либо не будет исследован последний
блок в цепи блоков участка I.
Модификация
Пусть необходимо модифицировать одно или более полей записи со
значением ключа v. Предположим, что должно быть модифицировано неко-
торое поле, являющееся частью ключа. Интерпретируем эту модификацию
как удаление с последующим включением (операция включения будет
описана позднее), потому что модифицированная запись может принадле-
жать другому участку1. В тех случаях, когда значение ключа не подверга-
ется модификации, поиск записи со значением ключа v осуществляется
так, как описано в разделе «Поиск». Если требуемая запись найдена,
1 Если записи закреплены, такая модификация невозможна.
31
модифицируем ее поля заданным образом. Если же запись не найдена,
имеет место ошибка, поскольку бессмысленно модифицировать несущест-
вующую запись.
Включение
Применим описанную ранее процедуру поиска. Обнаружение записи
с заданным значением ключа v может квалифицироваться как ошибка,
поскольку нет смысла включать запись, если в файле уже есть некоторая
запись с тем же значением ключа. Установив, что не существует записи
со значением ключа о, найдем первый свободный субблок среди блоков
участка h (о). Адрес этого субблока можно было запомнить во время про-
смотра участка в процедуре поиска1. Поместим включаемую запись в
этот субблок. Если во всех блоках участка h (о) свободных субблоков не
существует, вызовем файловую систему, чтобы получить новый блок.
Поместим в заголовок последнего блока участка указатель на этот новый
блок, в заголовок нового блока — null-указатель, а в первый субблок
нового блока — включаемую запись.
Удаление
Для удаления записи со значением ключа v вновь воспользуемся про-
цедурой поиска, позволяющей найти эту запись. Далее можно просто
сделать субблок, содержащий данную запись, свободным, установив в
нуль бит «заполнен/свободен» в его заголовке. При этом субблок стано-
вится доступным для повторного использования. Однако при наличии
указателей на запись мы не должны допускать повторного заполнения
субблока, поскольку зависший указатель может далее ошибочно указывать
на новую запись. В этом случае бит «заполнен/свободен» для удаляемой
записи нужно оставить в состоянии 1, и тогда субблок не может быть по-
вторно заполнен. В то же время бит удаления в самой записи устанавлива-
ем в 1, указывая, что запись была удалена. Если теперь, следуя по некоторо-
му указателю, мы обнаружим удаленную запись, то будет ясно, что этот
указатель завис. Такой указатель может быть либо удалей, либо установ-
лен в неопределенное значение.
Если записи не закреплены, можно спроектировать программу уда-
ления таким образом, чтобы при удалении записи, не являющейся по-
следней в участке, осуществлялся поиск последней записи и она пере-
мещалась в субблок удаляемой записи. При этом мы освобождаем
в участке последний блок (если он содержит лишь одну запись), кото-
рый может быть возвращен файловой системе для последующего ис-
пользования).
Пример 2.1. Допустим, что файл содержит информацию о динозаврах, а его
запись состоит из следующих полей:
НАЗВАНИЕ CHAR (20)
ПЕРИОД CHAR (10)
СРЕДА _ ОБИТАНИЯ CHAR (5)
ПИЩА CHAR (5)
ДЛИНА INT (4) /* в футах */
ВЕС INT (4) /* в тоннах */
1 Субблок в середине участка может стать свободным только если удаления фак-
тически приводят к исчезновению записи, а не к установке бита удаления. Предшест-
вующая стратегия приемлема лишь в том случае, когда в файле не существует ника-
ких указателей иа записи.
32
Поле НАЗВАНИЕ образует ключ для этого файла. Запись занимает 44 байта
при условии, что для целого числа требуется два байта. Предположим, что блоки имеют
длину 100 байт (в действительности эта величина гораздо больше). Тогда каждый блок
состоит из двух субблоков для записей, которым предшествует заголовок с указателем
(например, 4 байта) и двумя битами «заполнен/свободен» для двух субблоков. Два
бита могут с таким же успехом занимать полный байт. В результате в каждом блоке
остается 7 байт неиспользованного пространства.
Выберем простую функцию хеширования h (у), равную длине строки v по
модулю 5, т. е. остатку от деления длины на 51. Таким образом, мы имеем пять участков.
На рис. 2.2 представлен файл с десятью классами динозавров2. Заметим, что участок
4 свободен, и для него в справочнике имеется null-указатель.
Рис. 2.2. Хешированный файл
Предположим, что мы хотим включить в файл запись
(Эласмозавр, меловой, море, плотоядный, 40, 5)
После хеширования названия «Эласмозавр» получаем значение 2, поскольку это наз-
вание состоит из 12 литер3. Далее следуем по указателю, содержащемуся в статье с
номером 2 справочника участков, для нахождения первого (он оказывается и единствен-
ным) блока в участке 2. С помощью байта 5 в заголовке блока обнаруживаем, что оба
1 Это — неудачная функция хеширования для названий, длина которых имеет
тенденцию скапливаться вблизи 11—13 литер, поэтому не будет обеспечиваться
равномерное заполнение участков.
2 На самом деле некоторые из этих животных относятся к вымершим отрядам
рептилий, обычно не классифицируемых как «динозавры».
3 При размещении записей в данном примере используются англоязычные назва-
ния рептилий — Diplodocus (диплодок), Allosaurus (аллозавр), Pterodactil (птеро-
дактиль), Stegosaurus (стегозавр), Elasmosaurus (эласмозавр), Triceratops (трайсера-
топс), Plateosaurus (платеозавр), Brontosaurus (бронтозавр), Brachiosaurus (брахио-
завр), Compsognatus (компсогнат), Tyrannosaurus (тираннозавр). — Примеч. ред.
2 з»к. 1315
33
субблока содержат записи. Значение ключа первой записи находится в байтах 6—25,
которые содержат название «Платеозавр». Это не тот ключ, который иам требуется.
Значение ключа второй записи находится в байтах 50— 69, которые содержат название
«Бронтозавр», а не «Эласмозавр». Рассматриваем байты 1—4 блока с тем, чтобы найти
следующий блок в участке. Поскольку в этих байтах содержится null-указатель,
просмотрен весь участок. Таким образом, «Эласмозавр» не представлен в файле и задан-
ная запись может быть включена. Кроме того, мы не нашли свободного субблока.
Поэтому нужно получить новый блок и включить в него запись для эласмозавра.
Указатель в четвертом блоке на рис. 2.2 будет ссылаться на новый блок. Байты 1—4
нового блока становятся null-указателем, а пятый байт содержит биты 10.
Рис. 2.3. Пересмотренный файл динозавров
Пусть теперь мы вспомнили, что правильное научное название бронтозавра
(гремящего ящера) в действительности «Апатозавр» (невероятный ящер). В таком слу-
чае мы должны модифицировать запись для бронтозавра. Поскольку в данной операции
участвует ключ, удалим сначала запись для бронтозавра. Предварительно скопируем
значения неключевых полей, а затем включим запись для апатозавра с той же самой
информацией. С этой целью хешируем название «Бронтозавр» и получаем значение 2.
Следуя по указателю для участка 2, находим блок, второй субблок которого имеет зна-
чение ключа «Бронтозавр». Копируем эту запись и удаляем ее путем установки пятого
байта блока в 10. Предполагается, что записи являются закрепленными. Поэтому
запись для эласмозавра не может заместить запись для бронтозавра. Далее осущест-
вляем сборку записи:
(Апатозавр, юрский, озеро, травоядный, 70, 25)
и включаем ее в файл. Поскольку значение хеширования дли «Апатозавра» равно 1,
помещаем эту запись во второй субблок второго блока для участка 1. Состояние пере-
смотренного файла показано на рис. 2.3.
34
Анализ временных характеристик хеширования
Каждая из операций поиска, модификации, включения и удаления
требует одного доступа к внешней памяти для получения нужного блока
справочника участков (в предположении, что справочник не содержится в
основной памяти), а также доступов для просмотра участка, число кото-
рых не превышает число блоков в участке. В процессе поиска записи долж-
на быть просмотрена в среднем половина блоков. При выполнении любой
операции, отличной от поиска, кроме того, необходимо снова записать
модифицированный блок во внешнюю память. Если каждый участок со-
стоит в среднем из одного блока (это лучшее, на что можно было бы надеять-
ся), требуется два (для поиска) или три (для других операций) доступа, не-
зависимо от размера файла. Чтобы уменьшить число блоков в участках,
количество последних должно быть приблизительно равно числу записей
в файле, деленному на число записей, которые могут быть помещены в один
блок. На практике файл обычно постоянно растет. Поэтому необходимо
иногда осуществлять его реорганизацию, изменяя функцию хеширования
и увеличивая размер справочника участков. Такая реорганизация не
является настолько хаотической, как это может показаться, если принять
следующие два ограничения:
1. Функция хеширования вычисляется определенным образом. Про-
изводятся заданные вычисления над значением ключа и, в результате ко-
торых при любом v получаем очень большое целое число (существенно
большее, чем максимальное число участков, которое когда-либо могло бы
понадобиться). Полученное целое делится на число участков. Остаток
от деления принимается за значение функции.
2. При реорганизации число участков п умножается на фиксирован-
ное целое С (обычно выбирается С = 2).
Если мы решили удвоить число участков, то согласно ограничению 1
все записи из участка i будут попадать в участки I или i + п. В эти участ-
ки не попадут никакие записи других участков. Таким образом, мы можем
расщеплять поочередно по одному участку. Та же идея применима, если ум-
ножить число участков на любое целое С > 2. Тогда каждый из них может
быть разделен на С новых участков независимо от других участков.
2.3. ИНДЕКСИРОВАННЫЕ ФАЙЛЫ
Рассмотрим теперь другое представление файлов, доступ к которым
осуществляется по ключу. В этом случае записи файла сортируются по
значениям их ключа. Прежде всего следует отметить, что при любом доме-
не значений поля мы можем, в принципе, сравнивать значения из домена
и, таким образом, сортировать их. Это объясняется следующим. Для хра-
нения в файле значения должны быть представлены в виде строк бит фик-
сированной длины. Строки могут быть упорядочены, если интерпретиро-
вать их как целые числа и использовать числовой порядок. Над обычными
доменами значений, например строками литер, целыми и действительными
числами, определены общепринятые отношения порядка. Для целых и
действительных чисел это числовой порядок. Для строк литер мы имеем
лексикографический, или словарный, порядок, определенный следующим
образом:
ХГХ2 ... Xk< Y.Y2 ... Ym,
где Xj и Yj представляют собой литеры,
2*
35
если и только если
1) k<Z т и Xj ... Xk = У1 ... Yk или
2) для некоторого i min (k, т)
= Y Х2 = Y2, ...,
и двоичный код Xt численно меньше, чем двоичный код Уг.
Какой бы код литер не использовался в данной ЭВМ, мы вправе ожи-
дать, что порядок кодов букв является алфавитным, а порядок кодов
цифр — числовым. Таким образом, например, ’ЭЛЕМЕНТ’< ’ЭЛЕМЕН-
ТАРНЫЙ’ по правилу 1, а ’МАТЕМАТИКА’ < ’МОДЕЛЬ’ — по правилу
2 при I = 2.
Значения ключа, состоящего более чем из одного поля, можно сортиро-
вать в соответствии с произвольным порядком его полей. В результате сор-
тировки записей по первому полю образуются группы записей с одним и тем
же значением в этом поле. После сортировки каждой группы по значению
второго поля получаем группы записей с одним и тем же значением первых
двух полей. Полученные группы сортируются по третьему полю и т. д. За-
метим, что такое упорядочение является обобщением лексикографического
упорядочения для строк литер, где вместо списков литер мы упорядочива-
ем списки значений из произвольных доменов.
Пример 2.2. Пусть имеется ключ с двумя полями, принимающими целые
значения, и задан список его значений (2,3), (1,2), (2,2), (3,1), (1,3). Сортируя их по зна-
чению первого поля, получаем: (1,2), (1,3), (2,3), (2,2), (3,1). Первая группа, содержа-
щая значения ключа с 1 в первом поле, уже отсортирована по второму полю. Во второй
группе, состоящей из (2,3) и (2,2), необходима перестановка для того, чтобы она была
отсортирована по второму полю. Третья группа, включающая одну запись, естест-
венно, уже является отсортированной. Таким образом, сортированный порядок —
(1,2), (1,3), (2,2), (2,3), (3,1).И
Если нам нужно поддерживать файл, записи которого отсортированы
по значениям ключа, мы можем воспользоваться известным порядком для
того, чтобы быстро находить некоторую запись по заданному значению ее
ключа. Примерами поиска значений ключа в сортированном списке явля-
ются работа со словарем и с телефонной книгой. В обоих случаях в левом
верхнем углу каждой страницы указывается первое слово или имя на данной
странице1. Просматривая эти первые слова, можно опеределить страницу,
на которой должно находиться требуемое слово (в словаре) или имя (в те-
лефонной книге)2. Эта стратегия значительно лучше, чем просмотр всех
записей на каждой странице. Одну страницу нам, конечно, придется про-
смотреть полностью, но на всех остальных достаточно лишь просмотреть по
одной записи.
Возвращаясь теперь к представлению сортированного файла, который
называется главным, мы могли бы создать второй файл — (разреженный)
индекс, состоящий из пар (значение ключа, адрес блока). Пара (у, b) появ-
ляется в файле индекса, если первая запись в блоке с адресом b имеет зна-
чение ключа v. Первое поле представляет собой ключ файла индекса, кото-
1 В верхнем правом углу помещается последнее слово или имя, но эта информа-
ция является избыточной, поскольку первое слово или имя на следующей странице
дает эквивалентную информацию. Человеку неудобно листать страницы, но аналогич-
ная задача для ЭВМ не представляет трудностей.
2 На практике мы интуитивно учитываем распределение слов или имен с тем,
чтобы принять обоснованное предположение относительно местонахождения нашей
Цели, и не начинаем поиск с первой страницы. Позднее мы более подробно обсудим
адаптацию этой идеи к машинному поиску.
36
рый поддерживается сортированным по значениям своего ключа. В некото-
ром смысле файл индекса подобен любому другому файлу с ключом, и фак-
тически мы можем воспользоваться тем, что в файле индекса записи никог-
да не являются закрепленными указателями из другого места.
Существует, однако, важное различие между файлами индекса и обсуж-
даемыми обычными файлами. Вероятно, кроме выполнения операции
включения, удаления и модификации над файлами индекса, нам потребует-
ся получать ответы на запросы следующего вида: при заданном значении
ключа для индексированного файла найти в индексе такую запись (и2, Ь),
что v2 V!1 и либо (о2, Ь) является последней записью в индексе, либо сле-
дующая запись (о3, Ь) удовлетворяет условию <Х v3 (В этой ситуации го-
ворят, что о2 покрывает vv) Таким способом мы находим блок b главного
файла, содержащий запись со значением ключа t>l( поскольку файл индекса
с гарантией является сортированным.
Запросы указанного типа исключают некоторые способы организации
файлов индекса. Например, было бы неудобно использовать для них орга-
низацию хешированных файлов, рассмотренную в разд. 2.2, поскольку в
таком файле без его полного просмотра нельзя найти значение и2, покры-
вающее Oj.
Поиск в индексе
Пусть файл индекса хранится в известной совокупности блоков и тре-
буется найти запись (о2, Ь), такую, что v2 покрывает заданное значение клю-
ча Vj. Одна из стратегий заключается в использовании линейного поиска,
при котором просматриваются все записи индекса с самого начала до тех
пор, пока не будет найдена запись, покрывающая Этот метод целесооб-
разно применять только для небольших индексов, поскольку весь индекс
должен вызываться в основную память. Тем не менее даже линейный поиск
в индексе гораздо эффективнее линейного поиска в главном файле. Если
главный файл содержит с записей в блоке, то индекс имеет в с раз меньше
записей и его записи могут быть короче, чем записи главного файла. Вслед-
ствие этого большее число их может быть упаковано в один блок.
Лучшая стратегия — использование двоичного поиска. Если задано
значение ключа и индекс над блоками В1г В2....Вп, то рассматривается
средний блок2 Bfn/2i и сравнивается со значением ключа v2 в первой
записи этого блока3. При vx <Х v2 процесс повторяется в предположении,
что имеется индекс над блоками Вг ... Bfn/2]-i. Если же vx v2, то процесс
повторяется в предположении, что существует индекс над блоками
B(n/2i ...Вп. В конце концов для рассмотрения остается единственный блок.
Для нахождения в индексе значения ключа, которое покрывает исполь-
зуем линейный поиск в оставшемся блоке.
Поскольку на каждом этапе число блоков уменьшается вдвое, то не бо-
лее чем за flog2 (п + 1)1 наш поиск локализуется до одного блока. Таким
образом, при двоичном поиске в файле индекса требуется вызывать в основ-
ную память примерно log2 п блоков. После завершения поиска в индексе
1 Здесь есть любой используемый порядок на множестве значений ключа,
например лексикографический, если значения ключа являются строками литер.
2 [х] есть результат округления х до ближайшего целого сверху, т. е. наименьшее
целое, большее или равное х.
3 Заметим, что при этом требуется таблица адресов блоков, которая может на-
ходиться в основной памяти либо вызываться в нее в случае необходимости. Таким
образом, по значению целого i может быть определен адрес блока Bj.
37
становится в точности известно, какой блок главного файла должен быть
рассмотрен, а возможно, и перезаписан для выполнения операции над этим
файлом. Как показывает нижеследующий пример, общее число доступов к
блокам не является чрезмерно большим и составляет 3 + log2 п.
Пример 2.3. Предположим, имеется главный файл, состоящий из миллиона
записей, и в блок помещается десять записей. Тогда в индексе для этого файла 100 000
записей. Поскольку записи индекса короткие, допустим, что в блок может помещаться
100 таких записей. Следовательно, для индекса требуется 1000 блоков, т. е. в приведен-
ных выше вычислениях нужно принять п = 1000. Значит, операции доступа и переза-
писи для главного файла требуют 3 + log3l000, или 13 доступов к блокам. Рассматри-
ваемому случаю соответствуют три доступа при хешированной оргаиизацин. Однако
сортированные файлы обладают некоторыми преимуществами. Например, при хеширо-
ванной организации весьма трудно обрабатывать или перечислять записи в порядке
значений их ключа, в то время как при индексированной организации это делается
просто.!
Метод поиска в индексе, который может превосходить по быстродейст-
вию двоичный поиск, известен как интерполяция, или поиск с помощью
вычисления адреса. Этот метод основан на значении статистики предпола-
гаемого распределения значений ключа при условии достаточной надежно-
сти этого распределения. Пусть нам требуется, например, найти в телефон-
ной книге номер телефона Джона Смита (John Smith). В таком случае мы
открываем книгу не в середине, а отступив примерно на 75% от начала,
«зная», что приблизительно в этом месте находятся абоненты, фамилии ко-
торых начинаются с буквы S. Если мы попали в раздел, соответствующий
букве Т, то, переходя ко второму этапу двоичного поиска, мы должны вер-
нуться назад примерно на 5%, а не к середине книги.
Предположим вообще, что мы имеем алгоритм, который при заданном
значении ключа указывает, в какой части пути между двумя другими его
значениями v2 и vs может находиться значение Vj. Обозначим эту часть
/ (Vi, U2> va). Если индекс или его фрагмент находится в блоках Blt .... Вп,
то пусть v2 будет первым значением ключа в Вг и ц8 — последним значени-
ем ключа в В,1. Рассмотрим блок Bt, где i = \nf (vx, v2, u8)], и сравним
первое его значение ключа с ц. Далее, как и в двоичном поиске, повторим
процесс либо над Blt ..., Bt-lt либо над Bt, ..., Вп в зависимости от того,
где содержится значение, которое покрывает vt. Этот процесс продолжает-
ся до тех пор, пока не останется только один блок.
Нетрудно доказать следующее утверждение. Если известно предпола-
гаемое распределение значений ключа, то можно ожидать, что будет рас-
смотрено около l-(-log2 log2 п блоков файла индекса. Добавив два доступа
для чтения или записи блока главного файла, получим 3 + log2 log2 п. На-
пример, при условиях примера 2.3 это число немного превышает 6 (по срав-
нению с числом 13 для двоичного поиска).
Операции над сортированным файлом
с незакрепленными записями
Рассмотрим теперь, как выполняются операции поиска, включения, уда-
ления и модификации над сортированным файлом с записями, не закреп-
ленными указателями за фиксированными адресами. Эти четыре операции
потребуют включений, удалений и модификаций в файле индекса. Поэтому
нужно иметь в виду, что сам файл индекса является сортированным и со-
1 Если ..., В,, представляют полный индекс, то мы можем определить г2 и и2
без просмотра В1 и Вп, поскольку предполагается, что распределение ключей известно.
38
держит незакрепленные записи. Таким образом, описывая операции над
главным файлом, мы предусматриваем выполнение тех же самых операций
над файлом индекса, предполагая, что читатель знает, как реализовать эти
операции над индексом. Поскольку файл индекса не имеет индекса и стра-
тегии поиска для него уже описаны выше, мы не будем здесь подробно об-
суждать этот вопрос.
Исходный сортированный файл содержится в последовательности бло-
ков Ви В2, ..., Вк. Записи в каждом блоке хранятся в сортированном по-
рядке, причем записи блока Вг предшествуют записям блока Bi+1 в смысле
принятого упорядочения для i = 1, 2, .... k—1. В заголовке каждого
блока, как и в случае хешированной организации, находится информация,
указывающая, какой из субблоков содержит записи, а какой является сво-
бодным. Опишем каждую операцию в отдельности, предполагая, что ошиб-
ки типа попыток модификации несуществующей записи не имеют места.
Подобные ошибки обнаруживаются таким же образом, как и при хеширован-
ной организации.
Поиск
Предположим, что требуется найти в главном файле запись со значени-
ем ключа vv Прежде всего найдем в файле индекса блок, первая запись ко-
торого имеет значение ключа и2, такое, что v2 покрывает v2. Осуществим в
этом блоке поиск записи с ключом v2. Такой поиск может быть как линейным,
поскольку чтение блока обычно требует больше времени, чем поиск в нем,
так и двоичным. Мы можем при этом случайно обнаружить свободный блок
и решить, что он содержит запись с ключом vv Чтобы этого не произошло,
необходимо проверять биты в заголовке блока.
Модификация
Для модификации записи со значением ключа используем сначала
процедуру поиска для нахождения этой записи. Если модификация изме-
няет ключ, будем интерпретировать ее как удаление с последующим вклю-
чением. В противном случае осуществим модификацию и перезапишем дан-
ную запись.
Включение
С целью включения записи со значением ключа применим процедуру
поиска, чтобы найти блок Вь в котором должна была бы находиться такая
запись. В особом случае, когда предшествует значению ключа первой
записи блока Ви а следовательно, и каждому значению ключа в файле, по-
ложим i=l. Поместим новую запись в подходящее для нее место в блоке
Bt, сохранив сортированный порядок и переместив вправо записи со зна-
чениями ключа, большими, чем чтобы освободить место для новой запи-
си. При наличии в блоке В, по крайней мере одного свободного субблока в
него поместятся все записи. Если предшествует значению ключа v2 пер-
вой записи Bi (это может иметь место лишь при i = 1), необходимо модифи-
цировать статью файла индекса для блока Bt, используя только что опи-
санную процедуру модификации. Заметим, что, даже если запись со значе-
нием ключа v2 в файле индекса изменит это значение на vlt нет необходимо-
сти осуществлять удаление или включение, поскольку позиция данной
записи в файле индекса не будет изменяться. Следует, наконец, изменить
39
информацию «заполнен/свободен» в заголовке блока В;, чтобы отразить по-
явление в нем дополнительной записи. Итак, операция выполнена в пред-
положении, что в Bt имеется хотя бы один свободный субблок.
Допустим теперь, что блок уже заполнен настолько, что для новой
записи места нет. Существует множество стратегий, применимых в таких
ситуациях. В следующем разделе мы обсудим стратегию, при которой Вг
расщепляется на два полузаполненных блока. Эту стратегию можно было
бы использовать и в нашем случае. Альтернатива заключается в том, чтобы
проверить блок Bl+i. Мы можем найти Bt+l, если он существует, через
файл индекса, поскольку указатель на Bi+1 находится в записи этого фай-
ла, следующей за записью, к которой только что осуществлялся доступ
при поиске В{. Если Bi+1 имеет пустой субблок, то перемещаем лишнюю
запись из Bi в первый субблок Bi+i, передвигая другие записи вправо
до тех пор, пока не заполнится свободный субблок. Затем изменяем соответ-
ствующим образом информацию «заполнен/свободен» в заголовке и
модифицируем запись индекса для Вг+1, чтобы отразить появление нового
значения ключа в его первой записи.
Если блок Bi+1 не существует, поскольку i — k, или существует, но
полон, необходимо получить новый блок, который будет следовать по по-
рядку за Bt. Поместим лишнюю запись из Bt в новый блок. Включим далее
запись в файл индекса для нового блока, используя ту же стратегию, что и
для включения записи в главный файл.
Удаление
Как и при включении записи, в данном случае существует множество
стратегий. В следующем разделе будет, в частности, обсуждаться стратегия,
которая не допускает наличия блоков, заполненных менее чем наполовину.
Здесь мы рассмотрим лишь простейшую стратегию, вполне пригодную при
относительно небольшом числе удалений. Для удаления записи со значени-
ем ключа pj воспользуемся сначала процедурой поиска, чтобы найти эту
запись. Переместим все записи справа от нее на один субблок влево для
ликвидации промежутка1 и приведем в порядок биты «заполнен/свободен»
в заголовке. Если блок стал полностью свободным, возвратим его файло-
вой системе и удалим запись для данного блока в индексе с помощью той же
самой стратегии удаления. Если же блок после удаления записи со значе-
нием ключа Uj остался несвободным, то операцию можно считать закончен-
ной при условии, что удаленная запись не была первой в блоке. В против-
ном случае следует модифицировать запись индекса для этого блока.
Пример' 2.4. Рассмотрим снова иаш файл динозавров с блоками по 100 байт.
Вспомним из примера 2.1, что запись динозавра занимает 44 байта, так что можно упа-
ковать по две записи в блок. Запись индекса состоит из названия динозавра (20 байт)
н указателя на блок (4 байта). Таким образом, в блок может быть упаковано четыре
записи индекса. Первоначальная база данных показана на рис. 2.4, где информация о
динозаврах опущена.
Допустим, что в файл добавляется запись об эласмозавре. В результате просмотра
файла индекса, например, с помощью линейного поиска выясняем, что значение ключа
«Эласмозавр» покрывается зиачеиием «Диплодок». Следуя по указателю в записи
диплодока в файле индекса, приходим в третий блок файла динозавров. Просматривая
этот блок, устанавливаем, что «Эласмозавр» должен находиться между «Диплодоком»
и «Платеозавром». Поэтому помещаем запись эласмозавра в субблок, который содержит
1 Этот шаг несущественный. Если мы выбрали все-таки вариант с ликвидацией
промежутков, то можно использовать счетчик заполненных субблоков в заголовке вмес-
то бит «заполнен/свободен» для каждого субблока.
40
запись платеозавра, и последняя становится лишней. С помощью файла индекса опре-
деляем местоположение четвертого блока файла динозавров и обнаруживаем, что этот
блок также заполнен. Поэтому создаем новый блок, первоначально содержащий только
запись платеозавра, и помещаем его между третьим и четвертым блоками.
Далее вставляем запись для нового блока в файл индекса. Она замещает запись
птеродактиля в первом блоке файла индекса. В результате эта запись становится
лишней. Рассматривая таблицу блоков индекса, находим следующий блок индекса.
Убеждаемся в том, что в нем имеется место, и включаем запись индекса для птеродак-
тиля перед записью трайсератопса. Полученное состояние базы данных иллюстрирует-
ся рис. 2.5.
Виты
„заполнен/свободен ”
неиспользуемое
пространство
Рис. 2.4. Сортированный индексированный файл динозавров
Вспомним, что правильное название бронтозавра — апатозавр. По этой причине
с помощью индекса находим запись бронтозавра и удаляем ее из второго блока файла
динозавров. Запись компсогната перемещается влево, а биты «заполнен/свободен» уста-
навливаются в 10. После этого модифицируем запись в файле индекса для блока 2 файла
динозавров, изменяя значение ее ключа «Бронтозавр» на «Компсогнат». Заметим, что,
хотя поле ключа изменилось, порядок этой записи не изменился, и осуществлять уда-
ление и включение в файле индекса не требуется.
Теперь добавим запись апатозавра. Найдем в файле индекса, что ключ «Апатозавр»
покрывается ключом «Аллозавр». Поэтому отправимся в блок 1 файла индекса. Там Мы
вставим запись апатозавра во второй субблок, и запись брахиозавра станет лишней.
К счастью, имеется место в следующем блоке, и эта запись вставляется перед записью
41
компсогиата, которая, в свою очередь, перемещается назад к его началу. Модифициру-
ем, наконец, запись индекса для второго блока файла динозавров, изменяя значение
его ключа иа «Брахиозавр». Окончательное состояние файла показано на рис. 2.6.Ц
Рис. 2.5. Файл динозавров с добавленной записью эласмозавра
Цепные файлы
При выполнении операций включения записей иногда требуется найти
следующий блок главного файла. Вместо того чтобы воспользоваться для
этого файлом индекса, можно поместить указатель на следующий блок фай-
ла в заголовок каждого блока. Подобным же образом можно поместить ука-
затель на следующий блок в каждый блок файла индекса. Это позволило бы
нам обойтись без таблицы блоков индекса при линейном поиске в файле ин-
декса. В этом случае потребовался бы лишь адрес первого его блока.
Организация сортированных файлов
с закрепленными записями
Если записи закреплены за местом, в котором они были первоначально
запомнены, мы не можем, вообще говоря, поддерживать их в блоке в сорти-
рованном порядке. Мы столкнемся с трудностями, если даже попытаемся
добиться того, чтобы записи каждого блока предшествовали записям следую-
42
щего блока. Одно из возможных решений состоит в использовании такой же
организации файла, как и в случае незакрепленных записей (см. рис. 2.4).
Однако мы будем здесь рассматривать любой блок главного файла как пер-
вый блок участка. Поскольку осуществляется включение записей, к участ-
ку добавляют дополнительные блоки. Новые блоки объединяются в цепь с
помощью последовательности указателей, начинающейся в первом блоке
данного участка. Создается также свободный блок, начинающий участок,
Рис. 2.6. Файл динозавров после замены «Бронтозавра» иа «Апатозавра»
который содержит записи, предшествующие первой записи первого блока в
первоначальном файле. При такой организации индекс никогда не изменя-
ется. Первые записи каждого блока первоначального файла определяют
распределение записей по участкам, которое остается неизменным или по
крайней мере требует изменений лишь при достижении файлом столь больших
размеров, что будет иметь смысл реорганизация его в большом числе участ-
ков. Обсудим теперь, каким образом выполняются операции над файлом
с подобной организацией.
Инициализация
Отсортируем файл и распределим его записи по блокам. Мы можем при
этом принять, что блоки заполняются лишь частично, с тем чтобы обеспе-
чить пространство для дальнейшего роста и исключить длинные цепочки
43
блоков в одном участке. Предусмотрим один дополнительный блок в нача-
ле участка для тех записей, которые предполагается включить позднее и
которые будут предшествовать всем записям первоначального файла. Соз-
дадим индекс с записью для каждого блока, в том числе для свободного бло-
ка в начале файла. Запись индекса для этого блока содержит указатель и не
содержит ключа.
Поиск
Найдем запись индекса, значение ключа и2 которой покрывает требуе-
мое значение ключа цх. Если их меньше, чем первое значение ключа в файле
индекса (заметим, что это значение содержится во второй записи индекса),
то требуемой записью индекса является первая запись. Следуем по указа-
телю в выбранной записи индекса и попадаем на первый блок искомого уча-
стка. Для того чтобы найти запись с ключом цх, просматриваем этот и дру-
гие блоки участка, соединенные с ним цепью.
Модификация
Используемая здесь стратегия аналогична описанной для предыдущей
организации.
Включение
Для нахождения требуемого участка воспользуемся процедурой по-
иска. Просмотрим блоки участка с целью найти первое свободное место. Ес-
ли свободного субблока не существует, получим новый блок и поместим
указатель на него в заголовок последнего блока участка. Включим новую
запись в новый блок.
Удаление
Найдем требуемую запись с помощью процедуры поиска. Установим в
О бит «заполнен/свободен» для ее субблока. Однако в том случае, когда мо-
гут существовать указатели на удаляемую запись (см. разд. 2.2), следует
применить другую стратегию. Бит «заполнен/свободен» сохраняется в со-
стоянии 1, а для указания удаления записи бит удаления в самой записи ус-
танавливается в 1.
Пример 2.5. Пусть база данных первоначально состоит нз записей о пяти
динозаврах — брахиозавре, диплодоке, платеозавре, стегозавре н тираннозавре. В
этой базе данных заполняем блоки максимально плотно. Как и в предыдущих примерах,
полагаем, что блоки имеют длину 100 байт н поэтому могут содержать по две записи.
Первоначальная база данных показана на рис. 2.7. В ней имеется четыре участка,
которые содержат:
1. Любое название, предшествующее «Брахиозавру».
2. Любое название от «Брахиозавра» до «Платеозавра» (не включая последнее).
3. Любое название от «Платеозавра» до «Тираннозавра» (не включая последнее).
4. Название «Тираннозавр» и любые следующие названия.
Добавим теперь записи о перечисленных ниже динозаврах. Эти записи будут
размещены следующим образом:
1. Аллозавр. Попадает в первый субблок первоначально свободного блока пер-
вого участка.
2. Бронтозавр. Помещается во второй участок. Поскольку единственный блок
этого участка заполнен, получаем новый блок и помещаем запись бронтозавра в его
первый субблок.
3. Компсогнат. Это — другая запись для второго участка. Она помещается во
второй субблок второго блока.
44
4. Эласмозавр. Назначается также во второй участок. Получаем третий блок
для этого участка и помещаем рассматриваемую запись в его первый субблок.
5. Птеродактиль. Относится к третьему участку и помещается в новый блок.
6. Трайсератопс. Еще одна запись для третьего участка. Помещаем ее во второй
субблок второго блока этого участка. Допустим далее, что необходимо заменить наз-
вание «Бронтозавр» на «Апатозавр». Удаляем запись о бронтозавре из второго участка.
Никакие другие записи этого участка не перемещаются. Запись об апатозавре поме-
щается в первый участок — во второй субблок первого блока. Полученная в резуль-
тате структура показана на рис. 2.8.|
Рис. 2.7. Первоначальная организация файла
Дополнительные связи
Как и в случае сортированной организации с незакрепленными запи-
сями, иногда полезно связывать блоки индекса по порядку. Мы можем так-
же связать по порядку и участки. Один из способов, позволяющий сделать
это, предусматривает выделение пространства для дополнительного указа-
теля в каждом заголовке, который связывает первые блоки следующих друг
за другом участков. Другой способ дает возможность сохранить простран-
ство. Он заключается в замене null-указателя в конце цепи для каждого
участка указателем на первый блок следующего участка. Специальный бит
в заголовке показывает, имеем ли мы дело с указателем на следующий учас-
ток или на следующий блок того же самого участка.
Так как после инициализации записи помещаются в участок в произ-
вольном порядке, мы сталкиваемся с трудностями, если нам желательно
рассматривать их в сортированном порядке. Этих трудностей можно избе-
жать, добавив в каждую запись указатель на следующую запись в сорти-
рованном порядке. Такие указатели несколько отличаются от применяемых
45
Рис. 2.8. Конечная организация файла
На первую запись следующего участью
Рис. 2.9. Участок С указателями сортированного порядка
ранее, поскольку они'указывают не только блок, но и смещение в нем. Сме-
щение есть номер байта, в котором начинается хранимая запись, относитель-
но начала блока. Алгоритмы, необходимые для поддержки таких указате-
лей, хорошо известны1.
Пример 2.6. Второй участок файла, приведенного на рис. 2.8, с добавлением
указателей сортированного порядка представлен иа рис. 2.9. И
1 См., например, книгу Дж. Фостера «Обработка списков» (М., Мир, 1974)
или [100]. — Примеч. рвд.
46
2.4. В-ДЕРЕВЬЯ
Индекс представляет собой не что иное, как файл с незакрепленными
записями. Нет каких-либо причин, препятствующих использованию индекса
индекса, индекса этого индекса и т. д., пока индекс не вместится в один блок.
Фактически такая организация может быть значительно более эффективной,
чем файл с единственным уровнем индексирования. Общая схема для очень
больших файлов основана на иерархии индексов, соответствующей иерар-
хической природе устройств внешней памяти, на которых размещается файл.
Например, если файл находится на нескольких дисковых устройствах,
мы могли бы организовать его так, чтобы все записи на первом дисковом
устройстве имели значения ключа, предшествующие значениям ключа на
втором устройстве, которые, в свою очередь, предшествовали бы значениям
Рнс. 2.10. Иерархия индексов
ключа на третьем устройстве, и. т.д. Индекс первого уровня дает первое зна-
чение ключа на каждом устройстве. Аналогично упорядочиваются цилинд-
ры в устройствах, и индекс второго уровня дает первые значения ключа на
всех цилиндрах. Точно так же мы можем далее упорядочить дорожки в ци-
линдрах и использовать индекс третьего уровня, который даст первое зна-
чение ключа по каждой дорожке. Дорожки подразделяются на блоки, и соз-
дается четвертый уровень индекса. Если применяется такая организация,
то при инициализации файла полезно оставлять свободные блоки на всех
дорожках, свободные дорожки на всех цилиндрах, и т. д., что позволит ба-
зе данных существовать длительное время без реорганизации.
С помощью адекватной файловой системы можно построить более об-
щую схему, при которой блоки интерпретируются унифицированным об-
разом независимо от того, где они находятся во внешней памяти. Иерархию
индексов можно рассматривать как дерево, представленное на рис. 2.10.
При этом предполагается, что каждый используемый для индекса блок име-
ет пространство, рассчитанное на пять записей, хотя, как отмечалось в
разд. 2.3, некоторые блоки будут содержать меньше максимального числа
47
записей. Поскольку записи индекса не закреплены, будем предполагать,
что все заполненные субблоки находятся левее свободных в любом блоке.
На рис. 2.10 значения ключа являются целыми числами. Они заполнены в
первоначальном файле, а также в файлах индекса, насколько это было воз-
можно сделать.
Метод выполнения операций поиска, модификации, включения и уда-
ления над многоуровневыми индексами является простым обобщением ра-
нее рассмотренных методов. Проблема возникает в том случае, когда индекс
первого уровня превышает емкость блока. Очевидно, что принцип много-
уровневого индекса не зависит от числа уровней. Поэтому имеется возмож-
ность добавить еще один уровень к индексу, который ранее находился на
первом уровне и превысил размер блока. Мы приходим, таким образом, к
идее В-дерева (сбалансированного дерева), структура которого подобна
структуре, показанной на рис. 2.10, но с неспецифицированным числом
уровней. Однако мы настаиваем на том, чтобы дерево было сбалансирован-
ным, т. е. чтобы каждый путь от корня (блока индекса первого уровня) до
какого-либо листа имел одну и ту же длину.
Будем предполагать, что записи главного файла являются незакреплен-
ными, хотя разработка необходимой модификации для файлов с закреплен-
ными записями, где листья являются первыми блоками участков, не пред-
ставляет трудностей. В данном случае блоки главного файла трактуются
как часть В-дерева. Другой подход, который в большинстве ситуаций поз-
воляет экономить пространство, описывается в разд. 2.5. Главный файл мо-
жет храниться плотно упакованным в блоках без какого-либо конкретного
упорядочения записей. Тогда листья В-дерева содержат не записи главно-
го файла, а указатели на эти записи.
Для операций включения и удаления над В-деревом можно было бы
использовать ту же стратегию, что и в предыдущем разделе, применяя опе-
рации включения и удаления к узлам (блокам) дерева на всех уровнях. Тог-
да узлы содержали бы от одной записи до максимально возможного их чис-
ла. Для В-деревьев обычно применяется, однако, иная стратегия включе-
ния и удаления, которая обеспечивает заполненность всех узлов (за исключе-
нием, возможно, корня) не менее чем наполовину. Для удобства положим,
что число записей индекса, которые могут содержаться в одном блоке, яв-
ляется нечетным целым числом 2d — 1 3 и что максимальное число запи-
сей главного файла в блоке также представляет собой нечетное целое 2е —
— 1 > 3.
Прежде чем продолжить обсуждение, укажем еще одно различие меж-
ду В-деревьями и иерархией индексов, показанной на рис. 2.10. В блоках
индекса В-дерева значение ключа в первой записи опускается для экономии
пространства. Во время выполнения операций поиска считается, что все
значения ключей, меньшие значения ключа во второй записи блока, покры-
ваются его первым значением.
Поиск
Выполним поиск записи со значением ключа v. Найдем путь от корня
В-дерева к некоторому листу, в котором будет находиться требуемая запись,
если она существует. Начнем наш поиск в корне. Предположим, что в неко-
торый момент мы достигли узла (блока) В. Пусть В — лист, тогда проверя-
ем, имеется ли в этом блоке запись со значением ключа v. То обстоятельст-
во, что лист достигнут, нетрудно установить, если обеспечивается доступ к
текущему номеру уровней дерева.
48
В том случае, когда В не является листом, он представляет собой блок
индекса. Определим, какое значение ключа в блоке В покрывает v. Напом-
ним, что первая запись блока В не содержит ключа и что опущенное значе-
ние покрывает любые значения, меньшие значения ключа во второй записи.
В записи блока В, значение ключа которой покрывает V, находится указа-
тель на другой блок. Этот блок следует за В на пути, который мы строим,
и рассмотренные выше шаги повторяются с только что найденным блоком.
Модификация
Как и для других рассмотренных способов организации, модификация,
затрагивающая поле ключа, в действительности состоит в удалении и вклю-
чении записи. Модификация, при которой значение ключа остается неизмен-
ным, сводится к поиску изменяемой записи с последующей ее перезаписью1.
Включение
Чтобы включить в файл запись со значением ключа о, применим преж-
де всего процедуру поиска блока В, к которому эта запись относится. Если
в В содержится менее 2е — 1 записей, новая запись просто включается в
блок в сортированном порядке. Можно показать, что она никогда не может
быть первой в блоке, если В не является самым левым листом. Следователь-
но, ни при каких обстоятельствах нет необходимости модифицировать зна-
чение ключа в предшественнике В, поскольку, во всяком случае, в первой
записи каждого блока индекса опущено значение ключа.
Если в блоке В уже имеется 2е — 1 записей, создадим новый блок Вг
и разделим записи из В вместе с включаемой записью на две группы по е
записей каждая. Первые е записей поместим в блок В, а оставшиеся — в
блок Вг.
Пусть теперь Р — отец блока В. Напомним, что процедура поиска дает
путь от корня к блоку В. Таким образом, Р уже известен. Применим про-
цедуру включения рекурсивно с константой d вместо е для того, чтобы
включить в блок индекса Р запись для блока правее записи для блока В.
Заметим, что, если многие предки блока имеют максимальное число 2d — 1
записей, эффект включения некоторой записи в блок} В может распростра-
ниться на несколько уровней дерева. Однако затрагиваются при этом толь-
ко предки В. В том случае, когда влияние включения записи достигает кор-
ня, он расщепляется и создается новый корень с двумя сыновьями. Это един-
ственная ситуация, при которой блок индекса может иметь менее d записей.
Удаление
Пусть нужно удалить запись со значением ключа и. Используем сна-
чала процедуру поиска для нахождения пути от корня к блоку В, содержа-
щему эту запись. Если после удаления в блоке В еще остается е или более
записей, операция завершена. Если, однако, удаленная запись была пер-
вой в блоке, то мы должны обратиться к отцу блока В и изменить значение
ключа в записи для В, чтобы привести его в соответствие с новым первым
значением ключа этого блока. В том случае, когда В — первый сын его от-
ца, блок-отец не содержит значения ключа для В. Мы должны при этом ид-
1 Между этими операциями осуществляется, разумеется, собственно модификация
значений некоторых полей записи. — Примеч. ред.
49
ти к отцу отца, к его отцу и т. д. до тех пор, пока не найдем такого предка
Лх блока В, что Аг не является первым сыном своего отца Л2. Тогда новое
наименьшее значение ключа блока В помещается в запись блока Аг, кото-
рая указывает на Лх. Следовательно, запись (ць рА в каждом блоке индек-
са имеет значение ключа vlt равное наименьшему из всех тех значений ключа
первоначального файла, которые находятся среди листьев, являющихся по-
томками блока, указываемого pt. Таким образом, 5-дерево даже после уда-
ления продолжает вести себя как многоуровневый индекс1.
Предположим, что после удаления в блоке В осталось е — 1 записей.
Рассмотрим находящийся непосредственно слева или справа от него блок Вх
имеющий того же самого отца, что и В. Если Вх имеет более чем е записей,
мы распределяем записи В и по возможности равномерно, сохраняя, ко-
нечно, сортированный порядок. Модифицируем далее значения ключа для
fis fif в7 Bs ве Bw 8н
Рис. 2.11. Начальное 5-дерево
В и (или) Вх в блоке, являющемся отцом В. При необходимости распростра-
няем изменение по всем предкам В, у которых затрагиваются значения клю-
ча. Если Bt имеет только е записей, то объединяем В и Въ перенося записи
блока В в Bi. Последний в этом случае будет иметь в точности 2е — 1 запи-
сей. В блоке-отце В модифицируем запись для Вх (что может создать не-
обходимость в модификации некоторых предков В) и'удаляем запись для В.
Удаление такой записи требует рекурсивного применения процедуры уда-
ления с заменой е константой d.
Если удаление распространяется по всему пути вплоть до сыновей кор-
ня, может обнаружиться, что мы объединили двух его сыновей и других
сыновей у него не существует. Тогда узел, сформированный в результате та-
кого объединения, становится корнем, а старый корень удаляется. Это един-
ственный случай, когда число уровней уменьшается.
Пример 2. 7. Нетривиальные примеры В-деревьев трудно показать на одной
странице. Поэтому примем минимально возможные значения d и е, равные двум. Тогда
каждый блок независимо от того, является ли он внутренним или листом, содержит
три записи. С той же целью экономии места воспользуемся малыми целыми числами в
качестве значений ключа и опустим все другие поля в заголовке, включая биты «за-
полнен/свободен». Начальное В-дерево представлено на рис. 2.11.
Предположим, что нам требуется вставить запись со значением ключа 32. Преж-
де всего ищем путь к блоку, к которому эта запись относится, начиная с корня Вх.
1 Это свойство не является существенным, н мы могли бы обойтись без модифика-
ции ключей в блоках индекса.
50
Обнаруживаем, что значение ключа во второй записи блока Въ равное 25, покрывает 32.
Поэтому продвигаемся в В3 — блок, на который указывает вторая запись Вг. В блоке
В3 выясняется, что 32 меньше, чем значение ключа 64 во второй записи В3. Поэтому
следуем по первому указателю в В3 и приходим в блок В7. Очевидно, что 32 находится
в В7 между значениями 25 и 36. Но В7 будет теперь иметь четыре записи. Поэтому
запрашиваем новый блок В12 и помещаем записи со значениями ключей 25 и 32 в В7, а
со значениями 36 и 49 — в В12.
Рис. 2.12. В-дерево после включения записи со значением ключа 32
Далее мы должны включить запись со значением ключа 36 и указателем на В21
в блок В3. Это приведет к тому, что В3 будет иметь четыре записи. Поэтому получаем
новый блок В13. Записи с указателями иа В7 и В12 помещаем в В3, а с указателями иа
В3 и В9 — в В13. Затем включаем запись со значением ключа 64 и указателем иа блок
В13 в Вг. В результате Вг имеет четыре записи. Запрашиваем новый блок В14 и поме-
щаем записи с указателями иа В2 и В3 в В1( а записи с указателями иа В13 и В4 — в В14.
Поскольку В4 был корнем, создаем новый блок В16, который теперь становится корнем.
Он содержит указатели на Вх и В14. Результирующее В-дерево показано на рис. 2.12.
Рис. 2.13. В-дерево после удаления записи со значением ключа 64
Удалим запись со значением ключа 64. Процедура поиска определяет, что путь
к блоку, который содержит эту запись, есть В16, В14, В13, Bs. Удаляем из В8 запись,
которая, как выясняется, была первой в этом блоке. Поэтому мы должны распростра-
нить вверх по структуре дерева последствия того факта, что новое наименьшее значение
ключа в В8 равно 81. Поскольку В8 является самым левым сыном В13, мы не изменяем
последний. Не изменяется и В14, так как В13, — тоже его самый левый сын. Блок В14,
однако, ие является самым левым сыном В16. Поэтому в В15 имеется некоторое значение
ключа, которое должно быть изменено, и мы заменяем в нем 64 иа 81. Заметим, что
удаление никогда не приводит к изменению более чем одного значения ключа.
При удалении записи со значением ключа 64 возникает, однако, другая проблема.
Блок В8 содержит теперь только одну запись. Идем к его отцу В13 и находим, что у В8
нет брата слева. Поэтому проверяем правого брата В8— блок Вв. Так как В, имеет
51
только две записи, можно объединить его с В8. Далее обнаруживаем, что у В13 сущест-
вует единственный сын, и, следовательно, можно объединить В13 с его братом В4.
Блок В13 теперь обладает указателями на В1о и Вп. Значение ключа 196, сопровождаю-
щее указатель на Ви, находится в В4, тогда как значение ключа 144 для блока В1о — в
В14. Вообще, если мы объединяем блоки при удалении, необходимые значения ключей
содержатся либо в объединяемых блоках, либо в блоке, являющемся их общим отцом.
При объединении В13 и В4 оказывается, что у В14 существует единственный сын.
Поэтому Bj4 объединяется с В±. На этот раз у В16 только один сын, и, поскольку он
является корнем, мы удаляем его. В результате получаем В-дерево, приведенное иа
рис. 2.13. И
Анализ временных характеристик операций над В-деревьями
Рассмотрим файл с п записями, организованный в виде В-дерева с пара-
метрами d и е. В этом дереве не более п/е листьев, не более nJde отцов листь-
ев, n/d2e отцов отцов листьев и т. д. Если на путях от корня к листьям имеется
i узлов, то n^d!~le, так как в противном случае было бы менее одного уз-
ла на уровне корня, что невозможно. Отсюда следует, что
i 1 + -101ga(n/- = 1 + log*(«/«)•
loga а
Чтобы выполнить поиск, достаточно i операций чтения. Для операций
включения, удаления или модификации обычно необходимо записать лишь
один блок — лист, содержащий участвующую в операции запись. В патоло-
гических случаях, однако, может потребоваться приблизительно i дополни-
тельных операций чтения и i операций записи. Строгий анализ вероятности
получения блоков со слишком большим числом записей при включении или
со слишком малым числом записей при удалении весьма труден. Можно тем
не менее показать, что даже при d = е = 2 предполагаемое число дополни-
тельных операций чтения и записи (сверх i операций чтения, необходимых
для нахождения листа, и одной операции записи, чтобы его запомнить) пред-
ставляет собой правильную дробь. Этой дробью можно пренебречь, и пото-
му мы оцениваем число операций чтения/записи как 2 + logd (n/е). Даже
такая величина является умеренной, поскольку часто многие блоки содер-
жат более минимального числа записей. Следовательно, высота дерева впол-
не может быть меньше, чем 1 + logd (п/е).
Пример 2.8. Если п = 1 000 000, е = 5 и d = 50, то ожидаемое число
операций чтения/записи блоков равно 2 + log60 (200 000) 6. Эта оценка хуже, чем
в случае хешированного доступа (около трех чтений/записей), но превосходит оценки
для методов, использующих единственный уровень индексирования, за исключением,
возможно, таких ситуаций, когда может быть осуществлен интерполяционный поиск.
Преимущество В-дерева, так же как и методов, рассмотренных в разд. 2.3, по отноше-
нию к хешированному доступу заключается в том, что допускается удобное перечисле-
ние или поиск записей файла в сортированном порядке.
2.5. ФАЙЛЫ С ПЛОТНЫМ ИНДЕКСОМ
Предположим, что мы не желаем поддерживать наш файл в сортиро-
ванном виде. Допуская возможность хранения записей в произвольном по-
рядке, можно избежать появления в главном файле большого числа час-
тично заполненных блоков. Более того, при этом легко выполняются опе-
рации включения, для чего необходимо только хранить адрес дорожки по-
следнего блока в файле и вставлять в него новую запись. Когда последний
блок будет заполнен, мы просто получим новый блок от файловой системы.
Если удаления производятся часто, в файле появляются «дыры». Можно
52
просто игнорировать тот факт, что определенные субблоки становятся при
удалениях свободными. Другой подход предусматривает использование от-
дельного файла с записями, содержащими одно поле, которое является ука-
зателем на блок с одним или более свободными субблоками. Мы могли бы
даже сделать так, чтобы указатель идентифицировал свободный субблок в
блоке, хотя в этом случае не уменьшается число доступов к блокам.
При использовании несортированного файла проблема заключается в
том, что нам необходимо выбрать способ нахождения записи по заданному
значению ее ключа. Для эффективного поиска требуется еще один файл,
называемый плотным индексом. Он состоит из записей (о, р) для каждого
значения ключа и в главном файле, Где р — указатель на запись главного
файла со значением ключа V.
Чтобы найти, модифицировать или удалить некоторую запись главного
файла, нужно осуществить сначала поиск в файле плотного индекса, кото-
рый указывает блок главного файла, где находится требуемая запись. Далее
следует читать этот блок главного файла и перезаписать его в случае моди-
фикации и удаления. Таким образом, выполняются еще два доступа к бло-
кам в дополнение к доступам, необходимым для поиска в файле плотного
индекса. (Напомним, что «доступ» — это чтение либо запись блока.) При
включении запись помещается в конец главного файла, а указатель на нее —
в файл плотного индекса. Эта операция вновь требует на два доступа боль-
ше, чем операция над файлом плотного индекса.
Итак, мы видим, что для файла с плотным индексом требуется всегда
на два доступа больше, чем потребовалось бы для главного файла при такой
же организации (например, хешированной, индексированной или В-дере-
ва). Назовем, однако, два важных свойства плотных индексов, оправды-
вающие в некоторых ситуациях их применение:
1. Записи главного файла могут быть закрепленными, но записи файла
плотного индекса никогда таковыми Не являются. Поэтому для файла плот-
ного индекса можно использовать более простую или более эффективную
организацию, чем для главного.
2. Если записи главного файла большие, то общее число блоков в плот-
ном индексе может быть существенно меньшим, чем потребовалось бы для
разреженного индекса или В-дерева, построенных для главного файла. Кро-
ме того, нет необходимости в таком большом числе участков или среднем
числе блоков на участок для хешированной организации плотного индек-
са, как в случае использования хешированного доступа для главного файла.
Пример 2.9. Вернемся к примеру 2.8, где рассматривалось В-дерево при
d = 50 и е — 5 для файла из миллиона Записей. Поскольку записи плотного индекса
имеют тот же размер, что и записи во внутренних узлах В-дерева, при организации
плотного индекса в виде В-дерева можно принять d = е — 50. Таким образом, типич-
ное число доступов для поиска в плотном индексе равно 2 + log50 (20 000), что меньше 5.
Нужно еще добавить два доступа к главному файлу. Следовательно, если плотный ин-
декс будет организован в виде В-дерева, потребуется менее двух дополнительных
доступов к блокам (фактически 2 — log60 (Ю)) по сравнению с простой организацией
главного файла в виде В-дерева.
Существуют, однако, компенсирующие факторы для плотного индекса. При его ис-
пользовании мы можем целиком заполнять блоки главного файла.:В случае же организа-
ции В-дерева блоки листьев, содержащие главный файл, должны быть заполнены не ме-
нее чем наполовину (до целого). Поэтому мы можем сэкономить около 25% пространст-
ва памяти для главного файла. Пространство, используемое для листьев В-дерева в
плотном индексе, составляет лишь 10% пространства для главного файла, т. е. чистая
экономия составляет примерно 15% пространства. Более того, если главный файл
имеет закрепленные записи, мы вообще ие могли бы воспользоваться организацией fl-
дерева, описанной в разд. 2.4. Нам пришлось бы прибегнуть к организации В-дерева,
где листья являются участками, содержащими, возможно, несколько блоков. Таким
образом, плотный индекс плюс схема В-дерева, по-видимому, оказываются более
эффективными, чем простая схема В-дерева с участками.
Резюме
На рис. 2.14 перечислены четыре типа организации файлов, допускаю-
щих поиск, модификацию, включение и удаление записей по заданному зна-
чению ключа. При анализе временных характеристик было принято, что
п—число записей в главном файле и что записи главного файла могут запол-
няться по 2е — 1 в блок, а записи любого файла индекса — по 2d — 1 в
блок для унификации с В-деревьями.
Организация Время исполнения операции Преимущества и недостатки Проблемы, связанные с закрепленными записями
Хеширо- ванная >3 Самый быстрый из всех методов. Доступ замед- ляется, если файл рас- тет, так как участков становится больше. Нет возможности легкого доступа в порядке сор- тированных значений ключа Необходимо просмот- реть участки для поиска свободного пространст- ва во время включения либо допустить больше блоков в участке, чем в оптимальном варианте
Разрежен- ный индекс ~2-Mog п для двоичного по- иска ~2+log log п если вычисление адреса возможно и используется Быстрый доступ, если возможно вычисление адреса. Записи могут быть доступны в сорти- рованном порядке То же
В-дерево ~2-Н0 gd (п/е) Быстрый доступ. Записи могут быть доступны в сортированном поряд- ке. Нет тенденции к большему заполнению блоков То же
Плотный индекс 5^2+ время для операции над файлом плотного индекса Часто является более медленным на один или два доступа к блокам, чем если бы тот же ме- тод доступа, который ис- пользовался для файла индекса, был бы приме- нен к главному файлу. Позволяет экономить пространство Нет
Рис. 2.14. Сравнительная оценка методов доступа
2.6. ФАЙЛЫ С ЗАПИСЯМИ ПЕРЕМЕННОЙ ДЛИНЫ
Во многих ситуациях полезно хранить файл, записи которого имеют
более общую структуру по сравнению с рассмотренными в предыдущих раз-
делах. В частности, удобно разрешить вместо полей использовать повто-
54
ряющиеся группы полей, таких, что все поля в группе представляют один
и тот же вид объекта. Например, один из способов хранения отображения
«многие ко многим» набора объектов Ег в набор объектов Е2 состоит в том,
что создается файл с одной записью переменной длины для каждого объекта
типа Ei- Такие записи состоят из полей, представляющих некоторые объекты
типа Ег, например е, и из повторяющейся группы значений, каждое из ко-
торых есть некоторый объект типа Е2, находящийся в данном отношении
с е.
Пример 2.10. Пусть имеется файл штатов и связывающих их шоссе. Штаты
образуют набор объектов Elt а шоссе — набор объектов Е2. Запись переменной длины
для этого файла состоит из поля, значение которого есть название штата, например
строка литер длины 15, и из повторяющейся группы значений, каждое из которых есть
строка литер длины 3. Файл может начинаться так, как показано иа рис. 2.15. Заметим,
что запись для Аляски имеет нуль элементов в повторяющейся группе шоссе.
Алабама 110 120 159 165
Аляска Аризона 18 НО 117 119 140
Запись для Алабамы Запись для Запись для Аризоны
Аляски
Рис. 2.15. Файл штатов и шоссе
Следует подчеркнуть, что. файл, представленный на рис. 2.15, является
логическим, т. е. файлом более высокого уровня абстракции, чем файлы с за-
писями фиксированной длины, рассмотренные в предыдущих разделах.
Действительно, ключевым для данного раздела является вопрос о том, как
может быть осуществлена реализация логического файла с записями пере-
менной длины с помощью файла или файлов с записями фиксированной
длины.
На рис. 2.15 показаны фактические значения объектов, хотя их с тем
же успехом можно заменить указателями на записи для штатов и шоссе,
а атрибуты этих объектов хранить в другом файле. В самом деле, слишком
расточительно хранить информацию о шоссе в повторяющихся группах,
поскольку эта информация должна повторяться для каждого штата, через
который проходит данное шоссе. Более того, возникает опасность, что две
копии информации о некотором шоссе будут различаться. Однако, если ат-
рибуты штата хранятся в соответствующих им записях, нет никакой потери
эффективности или риска, так как каждый штат появляется в файле только
один раз. Фактически при связи между наборами объектов Ег и Е2 «многие
к одному» от Е2 к Ei (заметим, что связь штаты—шоссе не является связью
такого вида) мы могли бы точно так же хранить атрибуты объекта типа Е2
в единственной записи для объекта типа Elt которому она соответствует.
Таким образом, элементы повторяющейся группы могут состоять более
чем из одного поля. Фактически поля повторяющейся группы сами могли
бы быть повторяющимися группами, и таким способом можно было бы пред-
ставить в одном файле связь «многие к одному» от набора объектов Е2 к на-
бору объектов Еъ в другом — связь этого же вида от набора объектов Еа
к набору объектов Е2 и т. д. Примем следующее общее определение формата
записи переменной длины-.
1. Формат записи переменной длины есть список «элементов».
2. Элемент — это либо имя единственного поля, либо формат записи
переменной длины, который представляет повторяющуюся группу нуля
или более записей переменной длины с таким форматом.
55
Форматы записей переменной длины можно представлять с помощью
нотации, подобной регулярным выражениям. Элемент, который является
именем поля, представляется этим именем, а элемент, который является
повторяющейся группой с форматом а, — как (а)*. Формат записи перемен-
ной длины, состоящий из элементов с представлениями alt а2, ..., ак, пред-
ставляется как аъ а2, ..., ак. Читатель, хорошо знакомый с регулярными
выражениями, заметит, что множество возможных последовательностей имен
полей в записи с заданным форматом ничем не отличается от языка регуляр-
ных выражений, конструируемых таким образом. Однако для понимания
форматов записей переменной длины не требуется каких-либо знаний о ре-
гулярных выражениях. Достаточно помнить, что символ *, примененный
к формуле, означает «повторить нуль или более раз».
Назовем последовательность значений, соответствующих полям форма-
та записи переменной длины, экземпляром этого формата записи. Таким об-
разом, термин «экземпляр» применяется не только к полной записи. Мы мо-
жем говорить также об экземплярах повторяющейся группы, служащей
элементом некоторого большего формата записи переменной длины. Напом-
ним, что возможные форматы повторяющейся группы и записи переменной
длины одни и те же.
П р и м е р 2.11.
а) Формат записи файла из примера 2.10 может быть представлен следующим
образом:
ШТАТ (ШОССЕ)*
В данном случае он состоит из двух элементов: поля, называемого ШТАТ, и
повторяющейся группы записей переменной длины. Эти записи в действительности не
изменяются по длине, и каждая из них содержит одно поле с именем ШОССЕ. Типичный
экземпляр повторяющейся группы ШОССЕ — 195, а экземпляр полного формата
записи:
Нью-Джерси 178 180 195
б) Если требуется включить в эту запись атрибут НАСЕЛЕНИЕ, мы должны
использовать формат записи вида
ШТАТ НАСЕЛЕНИЕ (ШОССЕ)*
Пример экземпляра этого формата:
Нью-Джерси 7168164 178 180 195
в) Для того чтобы построить более сложный пример, мы могли бы включить
вместе с каждым шоссе во всех штатах его длину в милях и множество терминалов
(конечных пунктов) или точек входа для данного шоссе в штате. Формат записей с
этой информацией имеет следующий вид:
ШТАТ НАСЕЛЕНИЕ (ШОССЕ ДЛИНА (ТЕРМИНАЛ)* )*
Типичный пример записи с таким форматом:
Нью-Джерси 7168164 178
55 Филиппсбург Ньюарк
180
195
73 Хайнесбург Форт-Ли
68 Зап. Трентон Форт-Ли
Хранение записей переменной длины
Запись с повторяющимися группами не может быть произвольным об-
разом помещена в блок или блоки памяти, поскольку мы не располагаем
методом, позволяющим определить, где оказывается тот или иной тип поля.
Один из способов размещения заключается в том, чтобы хранить поля
56
в порядке очередности, максимально заполняя каждый блок. При этом
обычно не допускается, чтобы поле размещалось в двух блоках. Если мы
будем, однако, просто заполнять поля в блоки, мы столкнемся с большими
трудностями при декодировании последних в терминах полей. Действитель-
но, для того чтобы определить, где начинается некоторое поле, нужно знать
длины предыдущих полей. Однако мы не можем найти длину поля до тех
пор, пока не известен его тип. Таким образом, для каждого поля должно
быть указано имя или тип данных. Эта информация могла бы храниться в
заголовке блока или вместе с самими полями.
При первом подходе необходимо оставлять пространство в заголовке
для максимально возможного числа полей в блоке. Большая часть этого
пространства может не использоваться в среднем блоке. Второй подход тре-
бует просмотра всего блока с тем, чтобы выделить в нем любое заданное по-
ле. Некоторые альтернативные методы решения данной проблемы реали-
зованы в IMS—системе управления базами данных, в которой применяется
структура хранения, рассматриваемая в разд. 8.41.
Лучший подход часто сводится к тому, чтобы представить каждую
запись переменной длины с помощью одной или более записей фиксирован-
ной длины. Это можно сделать с помощью трех основных стратегий.
Метод зарезервированного пространства
Предположим, что установлено предельное значение числа экземпля-
ров повторяющейся группы. Заменим повторяющуюся группу с группами
полей. Так, мы могли бы предположить в примере 2.11 (в), что нет таких
шоссе, которые бы входили на территорию штата, выходили бы из нее, а
затем снова входили. В таком случае повторяющуюся группу (ТЕРМИНАЛ)*
можно было бы заменить полями ТЕРМИНАЛ! ТЕРМИНАЛ2 и был бы
приемлем пересмотренный формат записи:
ШТАТ НАСЕЛЕНИЕ (ШОССЕ ДЛИНА ТЕРМИНАЛ! ТЕРМИНАЛ2)*
Если повторяющаяся группа повторяется не более с раз, но может пов-
торяться менее с раз, мы должны иметь способ указания свободных полей.
Один из таких способов — использование «неопределенного значения»,
т. е. значения, которое не может иметь разумного смысла в этом поле. Если
не существует подходящего неопределенного значения, то допускается сле-
дующая альтернатива: добавляется поле, задающее фактическое число эк-
земпляров повторяющейся группы. При этом предполагается, что свобод-
ные поля следуют в группе за несвободными. Таким образом, мы могли бы
решить, что ни один штат не имеет более десяти шоссе, и заменить повторяю-
щуюся группу шоссе полем СЧЕТЧИК и десятью копиями группы. Отсю-
да новый формат записи:
ШТАТ НАСЕЛЕНИЕ СЧЕТЧИК
ШОССЕ1 ДЛИНА! ТЕРМИНАЛ!.1 ТЕРМИНАЛ2.1...
ШОССЕЮ ДЛИНАМ ТЕРМИНАЛ!.10 ТЕРМИНАЛ2.10
Это — формат записи фиксированной длины, и мы можем хранить файл
с такими записями с помощью методов, описанных в разд. 2.2—2.5.
1 В системе IMS хранимыми объектами являются не поля, а «сегменты», которые
представляют собой записи, как правило, фиксированной длины. Аналогия между
сегментами IMS и обсуждаемыми здесь полями остается, однако, в силе.
57
Метод указателей
Повторяющуюся группу можно также заменить указателем на первый
блок цепочки блоков, используемых для хранения экземпляров этой повто-
ряющейся группы. Так, в примере 2.11 (в) при замене формата записи пере-
менной длины тремя форматами записей фиксированной длины получаем:
ШТАТ НАСЕЛЕНИЕ УКАЗАТЕЛЬ-ШОССЕ
ШОССЕ ДЛИНА У КАЗАТЕЛЬ-ТЕРМИНАЛОВ
ТЕРМИНАЛ
На рис. 2.16 показано, как хранить нашу запись переменной длины в
блоках.
Рис. 2.16. Представление записи переменной длины с указа
телями
Комбинированный метод
Возможны различные комбинации двух описанных выше стратегий
Мы могли бы, очевидно, использовать указатели для одной повторяющейся
группы и некоторое фиксированное число повторений—для другой. В об-
щем случае предпочтение отдается фиксированному числу повторений, если
известно их реальное максимальное число, и среднее число повторений близ-
ко к этому максимуму. Если же среднее и максимальное значения существен-
но различаются, то оказывается слишком большим неиспользованное про-
странство. Методы, основанные на указателях, требуют меньшего прост-
ранства, но большего числа доступов к блокам для нахождения поля, чем
методы с фиксированным числом повторений. Так, в примере 2.11 (в) сле-
довало бы предпочесть фиксированное число повторений для повторяющей-
ся группы ТЕРМИНАЛ и указатели для повторяющейся группы ШОССЕ.
Другой способ комбинирования рассмотренных стратегий состоит в
том, что повторяющаяся группа заменяется пространством для небольшого
числа экземпляров и указателем на цепочку блоков, где могут находиться
дополнительные экземпляры. Эта стратегия полезна в тех случаях, когда
число экземпляров имеет тенденцию скапливаться около их среднего числа,
58
Тогда, если в записи фиксированной длины резервируется пространство для
числа экземпляров, несколько превышающего среднее, мы получим воз-
можность избавиться от нескольких указателей, не увеличивая существен-
но неиспользованное пространство.
Пример 2.12. Вернемся снова к примеру 2.11 (а) с форматом записи ШТАТ
(ШОССЕ)*. Предположим, что решено предоставить пространство для трех шоссе в
записи штата. Формат записи фиксированной длины примет тогда вид
ШТАТ СЧЕТЧИК ШОССЕ1 ШОССЕ2
ШОССЕЗ УКАЗАТЕЛЬ
Поле СЧЕТЧИК указывает, сколько из трех полей для шоссе заполнены. Предполо-
жим, что поля должны заполняться слева. Тогда значения счетчика достаточно для
того, чтобы установить, какие поля заполнены. Если такой способ заполнения полей
неприменим, вместо счетчика можно использовать битовый вектор, указывающий
Рис. 2.17. Записи штатов (шоссе), использующие зарезервироваииое про-
странство и указатели
какие поля являются свободными. Поле УКАЗАТЕЛЬ будет ссылаться на первый
из цепочки блоков, содержащих записи для шоссе — свыше трех на штат. Указатель
с неопределенным зиачеиием означает при этом, что дополнительных шоссе не сущест-
вует. На рис. 2.17 приведены записи для трех штатов в предположении, что в блоках
вмещаются две записи для штатов и четыре — для шоссе.
Операции над записями переменной длины
Рассмотрим логический файл записей переменной длины, который реа-
лизован с помощью главного файла с форматом записей фиксированной дли-
ны. Пусть при этом допускается использование дополнительных указате-
лей и блоков, не являющихся частью главного файла, как было описано
выше в связи с реализацией второго и третьего методов. Предположим, что
некоторое подмножество полей в формате записи фиксированной длины (за
исключением полей, являющихся указателями на блоки, которые содержат
экземпляры повторяющихся групп) служит ключом для записей перемен-
ной длины в логическом файле. Это предположение приобретет смысл, если
вспомнить нашу первоначальную мотивировку обсуждения записей перемен-
ной длины — представление связей «многие ко многим» или «многие к од-
ному» от набора объектов Е2 к набору Ег. Тогда записи будут содержать
атрибуты единственного объекта типа Ег и повторяющуюся группу для ас-
социированных объектов типа Е2. В этом случае атрибуты ключа для набора
объектов Ei служат ключом и для логического файла, и для файла, исполь-
зуемого в его реализации. Файлы с записями переменной длины могут
59
применяться для иных целей, чем представление связей. В таких случаях
главный файл реализации может не обладать ключом, отличным от полного
множества полей. Подобные ситуации встречаются, однако, редко.
Предположим далее, что некоторое множество полей реализующего
файла, состоящего из записей фиксированной длины, образует ключ. Тогда
можно организовать реализующий файл для поиска, включения, удаления
и модификации с помощью любого из рассмотренных в предыдущих разде-
лах методов, дополнив их некоторыми деталями. Эти дополнения связаны
лишь с созданием блоков или цепочек блоков для повторяющихся групп во
время включения при реализации, основанной на указателях, и с возвра-
щением файловой системе таких блоков, если имеет место удаление. Ис-
пользуемые при этом алгоритмы являются достаточно простыми, и мы не
будем на них подробно останавливаться.
Необходимо также рассмотреть новый класс операций над записями
переменной длины. Такие операции не имеют аналогов для записей фикси-
рованной длины. Обсудим включение и удаление экземпляров в повторяю-
щейся группе. Эти операции соответствуют модификации связи, если она
представлена логическим файлом. Независимо от того, представляются ли
повторяющиеся группы методом зарезервированного пространства, мето-
дом указателей или комбинированным, мы можем считать саму по себе пов-
торяющуюся группу небольшим файлом. Пусть для повторяющейся группы,
как и для главного файла, существует ключ. Этот ключ формируется из по-
лей повторяющейся группы, но не включает никаких полей указателей.
Для поддержки небольшого файла повторяющейся группы можно ис-
пользовать любой из методов, рассмотренных в предыдущих разделах. Од-
нако эти файлы обычно являются довольно короткими. Поэтому применение
какой-либо специальной организации нецелесообразно. Зная ключ для пов-
торяющейся группы, легко осуществить линейный поиск по ее экземпля-
рам. В этом случае поиск в группе при заданном значении ключа является
достаточно простым. Мы можем удалить экземпляр, как только он будет най-
ден; можем включить его в начало, в конец, либо в сортированном порядке
после того, как просмотрены имеющиеся экземпляры и установлено, что
экземпляра с заданным значением ключа не существует.
Если экземпляры в повторяющейся группе закреплены указателями,
то при выполнении включений и удалений следует проявлять осторожность.
Возникающие здесь проблемы обсуждались в разд. 2.2 применительно к опе-
рациям над участками закрепленных записей.
2.7. СТРУКТУРЫ ДАННЫХ ДЛЯ ПОИСКА
ПО НЕКЛЮЧЕВЫМ ПОЛЯМ
До сих пор мы рассматривали лишь такие операции над файлами, где
осуществляется поиск записи по заданному значению ключа и, возможно,
что-либо делается с этой записью. Гибкая система базы данных позволяет,
однако, получать по запросам информацию из записей, идентифицируемых
значениями поля или полей, которые не образуют ключ. Например, если
обратиться к нашему файлу динозавров, введенному в примере 2.1, то язык
манипулирования данными вполне позволил бы нам формулировать сле-
дующие команды:
1. Найти всех динозавров, относящихся к юрскому периоду.
2. Найти места обитания плотоядных динозавров.
3. Найти всех динозавров, которые жили на суше и имели по крайней
мере 50 футов в длину.
60
В данном разделе мы рассмотрим, какм образом организовать файл,
чтобы по заданным значениям некоторых конкретных множеств полей, от-
личных от ключа, эффективно получать записи с этими значениями. В общем
случае наиболее полезным является метод, заключающийся в создании «вто-
ричных индексов», которые связывают значения поля или полей с записями,
обладающими такими значениями. Мы будем изучать здесь именно этот
метод. Проблема же «поиска по частичному соответствию» — нахождение
соответствующих записей по заданным значениям для произвольного под-
множества полей — освещается в следующем разделе.
Вторичные индексы
Пусть имеется файл, записи которого содержат некоторое поле F. Это
поле принимает возможные значения из множества значений D, домена
для F. Поле F может быть элементом множества полей, которое образует
ключ, или оно может в ключ не входить. Возможно, что значение поля F
однозначно определяет запись, хотя мы этого не предполагаем. Вторичный
индекс по полю F представляет собой связь между доменом D и множест-
вом записей рассматриваемого файла1. Файл со вторичным индексом по по-
лю F называют инвертированным (по полю F). В терминах разд. 2.6 мы мо-
жем представить вторичный индекс как логический файл с форматом:
ЗНАЧЕНИЕ (ЗАПИСЬ)*
Экземпляр поля ЗНАЧЕНИЕ есть значение из D. Экземпляр поля
ЗАПИСЬ может быть либо указателем на запись с заданным значением в
поле F, либо значением ключа для записи с требуемым значением в поле F.
Если используется первый вариант, то указатель может ссылаться на
субблок или блок, в котором она содержится. В последнем случае для на-
хождения требуемой записи (записей) необходим поиск блока. Таким об-
разом, записи файла являются закрепленными, по крайней мере, внутри
блока. Указатель может также ссылаться на участок, содержащий требуе-
мую запись (записи), если в применяемой организации записей фиксиро-
ванной длины предусмотрены участки. Тогда для поиска записи необхо-
дим просмотр полного участка. Однако записи при этом не закрепляются (за
исключением закрепления внутри участка), если на данный файл нет иных
указателей, кроме указателей во вторичном индексе.
При использовании второго варианта записи главного файла не закреп-
ляются указателями из вторичного индекса. Однако в отличие от первого
варианта в данном случае потребуется несколько дополнительных доступов
к блокам для выполнения поиска записи по заданному значению ее ключа.
В то же время при первом варианте мы непосредственно приходим к этой
записи или по крайней мере к содержащему ее блоку или участку.
Пример 2. 13. На рис. 2.18 мы снова видим файл динозавров. Вероятно,
имеется некоторого рода первичный индекс по ключевому полю НАЗВАНИЕ, но мы
его не приводим и ие указываем, как записи распределяются по блокам. Здесь дан
вторичный индекс по полю ПЕРИОД, использующий метод, основанный на втором
варианте. Вторичный индекс состоит только нз трех записей переменной длины,
реализованных с помощью метода указателей. Этот индекс не имеет индекса по собст-
венному ключевому полю ЗНАЧЕНИЕ. Поскольку динозавры существовали в течение
лишь трех геологических периодов, в таком индексе нет необходимости.
На рисунке показан также вторичный индекс по полю ВЕС, использующий ва-
риант с указателями на записи главного файла. Записи этого индекса отсортированы по
1В отличие от него обсуждавшийся в разд. 2.3 индекс, который связывает значения
ключа с записями, называется первичным.
61
\йллозавр Юрский
суша плотоядный
3535 5 [-
[Брахиозавр Юрсний озеро травоядный 80 50 [
[Бронтозавр Юрский озеро травоядный 70 25 |
—^Компсогнат Юрсний суша плотоядный 2 0 |
—^[Диплодон Юрсний озеро травоядный 90 15 |
[Эласмозавр Меловой море плотоядный НО i |~—
[Ппатеозавр Третичный суша травоядный 30 5 —
—^^Птеродактиль Меловой воздух плотоядный 1 О |
.—•[Стегозавр Юрский суша травоядный 20 2 |
[Трдйсе~атопс Меловой суша травоядный 25 10 }*--
-—[Тираннозавр Меловой суша плотоядный 50 8 |
Главный файл
Индене для вторичного
индекса
Рис. 2.18. Вторичные индексы:
а) для поля ВЕС; б) для поля ПЕРИОД
62
своему ключу (по полю ЗНАЧЕНИЕ), и поиск в нем осуществлиется с помощью разре-
женного первичного индекса, рассмотренного в разд. 2.3.
Предположим, что нам нужно найти длины всех динозавров юрского периода.
Проверяем начальный блок этого индекса и находим в нем запись для периода
«Юрский». Следуя по ее указателю, приходим к цепочке блоков, содержащих названия
требуемых динозавров. Далее, в главном файле просматривается каждая из записей.
Найденные названия служат прн этом значениями ключей и каждый раз используется
алгоритм поиска, соответствующий организации, при которой для главного файла не
специфицирован первичный индекс.
Рассмотрим после этого запрос: «Найтн названия всех динозавров, имеющих
вес от пяти до десяти тонн». Начнем с первичного индекса для вторичного индекса по
полю ВЕС. В нем существует только две записи со значениями ВЕС, равными 0 и 15.
Поскольку 0 покрывает н 5, и 10, необходимо следовать по указателю для значения 0.
Вообще, прн поиске в диапазоне между тип необходимо следовать по указателям в
записях, значения ключей которых покрывают т и п, и по указателям во всех записях
между этими двумя. В данном примере мы идем лишь по одному указателю. Он приводит
в блок со значениями поля ВЕС,равными 0,2, 5,8 н 10. Последние три из них находятся
в требуемом диапазоне. Поэтому следуем по их указателям. Указатель для значения 5
отсылает нас к блоку с тремя указателями на записи главного файла. Продвигаясь
по этим указателям, получаем названия «Аллозавр», «Эласмозавр» и «Платеозавр».
Каждый из указателей, для значений 8 и 10 приводит нас к блокам с одним указателем,
и в результате мы получаем названии «Тираннозавр» и «Трайсератопс».|
2.8. ПОИСК ПО ЧАСТИЧНОМУ СООТВЕТСТВИЮ
Часто задаются запросы, в которых специфицированы значения двух
или более полей, но так, что эти поля еще не образуют полного ключа. Пред-
положим, что нужно найти записи со значением Uj в поле F\, и2 в поле
F2, ..., vh в поле Fh. Если Sj есть множество записей со значением vt в по-
ле Ft для i = 1, 2, ..., k, то требуемое множество записей есть Г) S2 Г) ...
... Г) Sh. Ниже описываются два метода решения этой задачи. Первый ос-
нован иа применении множественных вторичных индексов, а второй — на
специальной форме функции хеширования. Поскольку эта задача предус-
матривает нахождение частично специфицированных записей, она извест-
на как задача поиска по частичному соответствию.
Использование множественного вторичного индекса
Для решения указанной выше задачи не обязательно фактически ис-
кать все записи из затем — из 32 и т. д. Скорее, если существуют вто-
ричные индексы по некоторым или всем полям Ft, мы можем получить толь-
ко указатели на записи из тех множеств St, для которых существует вторич-
ный индекс по полю Ft. Когда эти множества не слишком велики, их пере-
сечение может быть построено в основной памяти. Далее мы следуем по каж-
дому указателю в пересечении и проверяем, имеет ли указываемая запись
заданные значения в оставшихся полях, для которых не существует вторич-
ного индекса. Заметим, что если заданы указатели на блоки или участки, а
не на индивидуальные записи, то необходимо рассмотреть каждую запись в
блоке или участке. При этом у нас нет уверенности, что хотя бы одна запись
имеет все специфицированные значения во всех полях со вторичными ин-
дексами. Блок может, например, содержать запись со значением ог в поле
F\ и отличную от нее запись со значением и2 в поле F2. В этом случае указа-
тель на блок содержался бы в Sj fl 32, хотя на самом деле ни одна запись в
блоке не имеет значения Uj в поле Fj и о2 — в поле F2. Такую ситуацию мож-
но назвать ложным результатом.
С целью минимизации размера списка указателей, с которыми предсто-
ит иметь дело, следует сначала получить наименьшее множество St среди
63
всех полей Fit имеющих вторичный индекс. Эвристически можно выбирать
поле Fi с наибольшим множеством различных значений, представленных в
базе данных, если, конечно, такая статистика известна или может быть пред-
сказана. Например, при запросе данных о плотоядных динозаврах юрско-
го периода нужно сначала осуществить поиск во вторичном индексе по по-
лю ПЕРИОД, а затем по полю ПИЩА, если такие индексы существуют,
так как периодов — три, а видов пищи — два.
Распространяя этот принцип, необходимо второе множество Sj в пере-
сечении выбрать таким, чтобы оно имело второй наименьший ожидаемый
размер и т. д. Следовательно, в среднем пересечение будет сокращаться на-
столько быстро, насколько это возможно.
Функции раздельного хеширования
Рассмотрим теперь другой интересный метод организации, в котором не
используются индексы (ни первичные, ни вторичные). Тем не менее эта ор-
ганизация обычно существенно облегчает проведение поиска записей в си-
туации, когда заданы значения для любого множества полей. Естественно,
что поиск будет более быстрым, если значения специфицированы для боль-
шего числа полей.
При использовании рассматриваемого метода осуществляется доступ
к большему числу блоков, чем при организации файла, предусматриваю-
щей вторичные индексы по всем полям. Поэтому в случае очень больших
файлов метод поиска по частичному соответствию не рекомендуется. Но по-
скольку здесь не нужно пространство для индексов, этот метод может быть
подходящей альтернативой для файлов, требующих порядка тысячи бло-
ков. Кроме того, из-за отсутствия вторичных индексов не расходуется вре-
мя на их модификацию при выполнении операций включения или удаления
над главным файлом.
Существо метода заключается в том, что мы принимаем все поля за
ключ, хотя некоторое подмножество полей действительно может служить
ключом, и хешируем записи, используя полное множество полей как ключ.
Применив теперь обычную функцию хеширования, мы могли бы определить
участок, к которому относится запись, при условии, что она нам в точности
известна. Однако при более тщательном конструировании функции хеширо-
вания можно ограничивать число участков, где должны находиться соот-
ветствующие записи, всякий раз, когда известно значение одного или бо-
лее полей. «Хитрость» состоит в разбиении битов номера участка на несколь-
ко частей таким образом, чтобы каждое поле определяло одну из частей.
Тогда всякий раз, когда известно одно или более полей, мы уже что-либо
знаем о номерах участков, в которых может находиться требуемая за-
пись (записи).
Предположим сначала, что число участков является степенью двой-
ки, например 2В, и что логический адрес участка есть последователь-
ность В бит. Перевод логических адресов участков в физические адреса
блоков осуществляется с помощью простого вычисления, если последние мы
можем выбирать сами. Если же адреса блокам назначает файловая система,
то следует воспользоваться таблицей перевода логических адресов в физи-
ческие. Далее, разделим В бит адреса участка на группы — по одной груп-
пе для каждого поля. При этом для группы некоторого поля может быть
назначено нуль бит.
Если имеются поля Flt F2, ..., Fk и для поля У7,- назначается bt бит,
участок записи (olt vs, ..., uft), где v( есть значение поля F(, определяется
64
путем вычисления ht (ог) для i = I, 2, k. Здесь ht — функция хеширо-
вания для значений поля Fit а значение, продуцируемое ht, является целым
числом, принадлежащим диапазону от нуля до 2Ь) — 1. Таким образом,
hi (vt) представляет собой последовательность bt бит. В качестве логичес-
кого адреса участка для записи (иь и2, .... vh) принимается последователь-
ность В бит hr (Vi)h2 (v2) ...hh (vh).
Пример 2.14. Допустим, что записи с тремя полями:
НОМЕР-СЛУЖАЩЕГО INT (5)
НОМЕР—СБ INT (9) /* Номер социальной
безопасности */
ОТДЕЛ CHAR (10)
необходимо хранить в 29 = 512 участках. Предположим также, что из девяти бит
адреса участков четыре соответствуют первому полю, три — второму и два — третьему.
Для поля НОМЕР— СЛУЖАЩЕГО воспользуемся функцией хеширования, предпи-
сывающей разделить номер служащего на 16 и взять остаток. Для поля НОМЕР-СБ
значение поля разделим на 8 и возьмем остаток. Наконец, для поля ОТДЕЛ разделим
число литер, отличных от пробела в названии отдела, на 4 и возьмем остаток1 * 3.
Если задана запись
(58651, 130326734, СДЕЛКИ),
то делим 58651 на 16 и получаем остаток 11, или 1011 как четырехбитовое двоичное
число. Номер социальной безопасности по модулю 8 есть 6, или ПО в двоичном виде.
Длина «СДЕЛКИ» по модулю 4 равна 2, или 10 как двухбитовое двоичное число. Таким
образом, участок, в котором будет находиться эта запись, есть 101.111.010— конка-
тенация значений хеширования 1011, НО и 10.
В том случае, когда задано значение поля Ft, можно вычислить bt бит
адреса участка, независимо от того, известны или не известны значения дру-
гих полей. Таким образом, при известном значении поля Ft число участков,
которые нужно просматривать, сокращается в 2bt раз. Например, чтобы
найти отдел, где работает служащий с номером 58651 (см. пример 2.14), нуж-
но просмотреть 32 участка, соответствующих 32 возможным значениям пяти
бит, относящихся к полям НОМЕР-СБ и ОТДЕЛ. Если известны НОМЕР-
СЛУЖАЩЕГО и НОМЕР-СБ для некоторого служащего, необходимо
просмотреть только четыре участка.
Оптимизация распределения бит между полями
Пусть известна статистика запросов, т. е. вероятность того, что для лю-
бого заданного множества полей в запросе будут специфицированы их зна-
чения. Предположим, что, если специфицируется значение поля Fit все его
возможные значения являются равновероятными. Следующая теорема дает
важный результат, связанный с адресацией участков в этом случае.
Теорема 2.1. Пусть при спецификации значения некоторого поля
все его значения являются равновероятными. Тогда минимум математичес-
кого ожидания числа просматриваемых для обработки запроса участков
достигается в том случае, когда адрес участка для записи (о1, v2, ..., vh) вы-
ражается как
hk (vk)+nk (И*..! (Ufe-J + nh_r (hh„2 (uft_2) +... +n2hi (uj...)),
1 Как и в примере с названиями динозавров, такая функция хеширования являет-
ся, вероятно, неадекватной для названий отделов, но используется здесь для простоты
изложения.
3 Зак. 1315
65
где функция хеширования йг (vt) изменяется от 0 до и лъ л2, ..., nh вы-
бираются таким образом, чтобы их произведение было равно числу участ-
ков.
Приведенная формула является в действительности обобщением наше-
го подхода, при котором в качестве адреса участка принимается последо-
вательность бит, вычисляемых раздельно для различных полей. В пред-
ложенных выше обозначениях имеем щ = 26С Таким образом, наш подход
не гарантирует оптимальности, но он дает результаты, достаточно близкие к
оптимальным. Вместе с тем простота использования последовательности
независимо получаемых бит как адреса участка, а не формулы h3 (v3) +
+ Зй2 (yi) + 12/ii (t>i) заслуживает внимания.
Доказательство теоремы 2.1 выходит за рамки данной книги. Должно
быть интуитивно ясно, что благодаря зависимости каждого бита адреса
участка от значения только одного, а не двух или более полей мы можем, по
всей вероятности, узнать значение некоторого бита и тем самым исключить
просмотр тех или иных участков при обработке случайного запроса. Этот
аргумент несложно обобщить для формулы адреса участка (см. теорему),
которую можно рассматривать как запись целых чисел с переменным осно-
ванием1. Доказательство теоремы 2.1 можно найти в [27].
Теорема 2.1 поддерживает наш подход к построению адресов участков с
помощью соединения строк бит, полученных независимо из нескольких по-
лей. Однако она не дает ответа на вопрос о том, какими должны быть значе-
ния tit или (при введенном ранее ограничении щ = 2Ь‘) какими должны
быть bi. Очевидно, bt зависят от частот, с которыми для различных множеств
полей специфицируются их значения в запросе.
Например, если во всех запросах специфицировано значение поля F2
и не специфицированы значения никаких других полей, то лучше всего бы-
ло бы принять bi — В и Ь2 = Ь3 = ... = bh = 0. Такая ситуация возни-
кает, когда Fr есть ключ, и наша организация представляет собой не что
иное, как схему хеширования из разд. 2.2. При этом каждый запрос требу-
ет просмотра только одного участка.
Другой пример: допустим, что для первой половины запросов специ-
фицируется только Flt а для второй половины — F2 и F3. Здесь, по-видимо-
му, наилучшее решение состоит в том, чтобы принять Ьг = В/2, Ь2 =
b3 = В/A и Ь^ = 0 для i > 3. Тогда нам потребуется просматривать 2В/2
участков на запрос всегда, а не только в среднем.
В нескольких частных случаях формула для bt может быть получена
в конечном виде. Этот вопрос рассматривается ниже.
Специфицировано значение только одного поля
Определим значение bit которое минимизирует математическое ожи-
дание числа просматриваемых участков в случае, когда специфицировано
значение только одного поля.
Теорема 2.2. Если во всех запросах специфицируется только одно
поле, причем р, есть вероятность того, что Е, — специфицированное поле и
1 Самая правая цифра есть разряд единиц, следующий разряд имеет вес «пц»,
третий разряд— вес «пд-! • и т. д.
Ь6
О Ь[ В для всех I, то математическое ожидание числа просматривае-
мых участков минимизируется при
k
В— 2
Ь; =--------------HofePo
Л
где k — число полей и 2® — число участков. Заметим, что только послед-
ний терм — Iog2 pi — зависит от i.
Доказательство. Если специфицировано Fb мы просматри-
ваем 2B~bi участков. Таким образом, математическое ожидание числа про-
сматриваемых участков равно S^(2s~4 Поскольку — В, используя
метод множителей Лагранжа, имеем, что приведенное выше выражение ми-
нимизируется, когда для всех i
fe / k \
2 pt2s-6<+^B-2 м=о,
или, что эквивалентно:
— (loge2)pl-2B~t><—Х, = 0
для всех I. Следовательно, существует некоторая константа, такая, что для
всех i
Pl-T~bi~C
или
log 2Pi = bi + loga с. (2.1)
Поскольку сумма Ь/ равна В, после суммирования (2.1) получаем
k
2 Iog2 pj = В 4-Hog2 с.
z=i
Поэтому
S logaP/—В
log2c = -^l—------ .
k
Подставляя это значение log2 с в (2.1), находим
к
В— 2 logiPj
bi = log2 pt — 1 og2 c --------h log2 pi,
К
что и требовалось доказать.
Существует несколько проблем, связанных с формулой из теоремы 2.2.
Прежде всего, что произойдет, если bt <Z 0 или bt > В? В первом случае мы
полагаем йг = 0, исключаем поле F, из рассмотрения и повторно применяем
теорему 2.2. Заметим, что может оказаться необходимым неоднократное
повторное применение теоремы, поскольку какое-либо bj, которое было по-
ложительным, может стать отрицательным при втором применении теоремы.
В случае > В полагаем это bt = В, а все другие—равными нулю.
Вторая проблема заключается в том, что формула для bt в теореме 2.2
может дать нецелое число бит. Чтобы найти оптимальное распределение
бит, необходимо руководствоваться следующим правилом. Пусть — ct -г
з*
67
+ dit где ct есть целое и 0 I. Тогда сумма dt всегда будет целой,
k
если В — целое. Если Zdt = D, тогда выбираем D величин bt с наиболыпи-
/=|
ми значениями dt и увеличиваем их до ct 4- 1. Уменьшаем оставшиеся вели-
чины bj до с}.
Пример 2.15. Рассмотрим файл из примера 2.14. Предположим, что в 75%
запросов специфицируется НОМЕР— СЛУЖАЩЕГО, в 24% — НОМЕР— СБ и в 1% —
ОТДЕЛ. Тогда рг = 0,75, р2 = 0>24 и р3 = 0,01. Пусть В = 9. Так как k = 3 и
з
2 log2 Р] = (—0,41) -f- (—2,05) + (—6,64) = —9,10, по формуле теоремы 2.2 получаем
bt = 9-(-9’10) + iog2 Pi = 6,03 + log2 Pl.
О
Таким образом, Ьг = 5,62, 62 = 3,98 и Ь3 = —0,61.
Поскольку Ь3 — число бит, выделенных для поля ОТДЕЛ, отрицательно, по-
лагаем его равным нулю и снова решаем задачу, как если имелось бы только два поля
0,75 0,24
с вероятностями спецификации рг = у_д щ = 0,758 и р2 = q|" = 0,242, Теперь
2
k — 2, и поэтому 2 log2 р — (—0,40) (—2,04) = —2,44, а
bi = 9~(7g,44) + 10g2 Pi = 5,72 + log2 Pi
Отсюда получаем = 5,32 и &2 = 3,68. Сумма дробных частей в 5,32 и 3,68 равна
единице, поэтому выбираем наибольшую из них —0,68 и увеличиваем до единицы.
Другую дробную часть — 0,32 — уменьшаем до нуля. Таким образом, оптимальное
распределение бит таково, что Ьг= 5, 6» = 4 и Ь3 = 0. Следовательно, пять бит адре-
са участка продуцируется из поля НОМЕР-СЛУЖАЩЕГО, четыре — из поля НО-
МЕР- СБ и ни одного — из поля ОТДЕЛ. При таком распределении математическое
ожидание числа просматриваемых участков равно:
0,75 (24) + 0,24 (25) + 0,01 (29) = 24,8 участка.
Значения полей специфицируются независимо
Значения величин Ьг можно выразить в явном виде и тогда, когда с ве-
роятностью Pi будет специфицировано значение поля Ft, и эта вероятность
не зависит от того, специфицируются ли значения других полей. Напри-
мер, если имеется три поля, то вероятность того, что в запросе специфици-
рованы значения первых двух полей, но отсутствует спецификация значения
третьего поля, равна Р1р2 (1 — р3). Отметим, что в отличие от условий тео-
ремы 2.2 здесь сумма вероятностей Pi не обязательно равна единице.
Теорема 2.3. Если значение поля Ft специфицируется с вероятно-
стью pt, которая не зависит от того, значения каких других полей специфи-
цированы, то в предположении, что 0 bt В для всех i математическое
ожидание требующих дросмотра участков минимизируется при
k ! п \
в— 2 log»!-—*—) f Pi \
bi ——'nL.--------^l + iog2(i-pj.
k
Заметим, что приведенная формула вытекает из теоремы 2.2, когда рт =
__ Рт
1—Рт '
68
Доказательство. Математическое ожидание числа просмат-
риваемых участков равно
2 п Pt п v-Pi)-2bi.
SC {1,2 ijies itfS
Эта формула эквивалентна следующей:
k
2вп а-pi) 2 пPM2'6*-
i=l SC {1. 2.*} «6S'* Pl '
Так как
2 П at= П (1+аг),
SC{I.2 А} « £ 3 1=1
то, полагая а, = (—^-;) 2~bl, получаем из первоначальной формулы
2ВП (1—pjfl +—£1—-2-6Л. (2.2)
(=1 \ X~pi !
Дальнейшее доказательство аналогично доказательству теоремы 2.2:
используются множители Лагранжа и берутся частные производные отно-
сительно bt. Оставляем его как упражнение для читателя.
С отрицательными или превышающими В значениями bt мы поступаем
так же, как при доказательстве теоремы 2.2. Используемый в нем метод
применяется при округлении нецелочисленных в оптимальном решении
Пример 2. 16. Предположим, мы имеем файл счетов со следующими полями:
(20) /* покупатель */
(20) /*покупаемое изделие*/
INTEGER (9)
: ИМЯ CHAR
F, : ТОВАР CHAR
F3 : КОЛИЧЕСТВО
F4 : ДАТА INTEGER (6)
Пусть вероятности того, что различные поля специфироваиы в запросе: р4 = 0,8,
рг = 0,5, р3 = 0,01 и р4 =0,2, и эти вероятности не зависят от того, специфицированы
ли другие поля. Например, вероятность запроса вида «иайти имена покупателей и
(или) проданное количество мужских сорочек по всем счетам на 20 июля 1978 г.» равна
(1—0,8) (0,5) (1—0,01) (0,2) = 0,0198. Таким образом, примерно в 2% запросов специ-
фицируются поля ТОВАР и ДАТА, но ие другие два поля. Пусть В = 9. Тогда
( Pi \ 1 - I 0,8 \ । 1 - / 0,5 \ । , _ I 0,01 \ .
1О§2 I ---I — logo I I 4“ IQS2 I " I Ч” logs I ————— I -4“
,= i pj) \ 1 — 0,8 ) б2\ 1--0,5 б2\ 1-0,01 )
+ = 2 + ° + (-6>63) + (-2) = -6,63.
Таким образом, по теореме 2.3 находим
& _ 9—(—6,63)
= 3,91 +10g2f-
\1— Pi
4
Отсюда ^=5,91, &2=3,91, Ь3 = —2,73 и 64 = 1,91. Так как Ь3 отрицательно, исклю-
чаем поле КОЛИЧЕСТВО из рассмотрения и полагаем Ь3 = 0. Заметим, что в отли-
чие от теоремы 2.2 здесь нет необходимости в пересчете вероятностей, когда мы исклю-
чаем некоторые поля. После повторного применения теоремы 2.3. имеем
=3-f-log2f—^—)
\1— Pil
для /= 1, .... 4. Следовательно, Ьг = 5, Ь3 = 3, Ь3 = 0 и 64=1, и не требуется каких-
либо операций с дробными частями.
69
Если применить теперь формулу (2.2) для определения среднего числа участков,
то
2®П (1-р4)(1+-^-2-^ = 2»(0,2)(1+4)(0,5)х
<=1 \ 1—Pi / \ 2 / \ z /
X (0,99)(i+-^L-)(0>8)(i+-2^-) = 58,3 (участка).
УПРАЖНЕНИЯ
2.1. Пусть имеется файл из миллиона записей. Каждая запись занимает 200 байт,
из которых 50 отводятся для полей ключа. В блоке предусмотрено место для 1000 байт,
помимо пространства для заголовка. Указатель на блок или субблок занимает 5 байт.
а) Сколько блоков потребуется для справочника участков, если использовать
хешированную организацию файла с 1000 участками?
б) Сколько блоков потребуется для участков в предположении, что все участки
имеют среднее число записей?
в) Каково среднее число доступов к блокам при поиске записи, которая действи-
тельно присутствует в файле (с учетом предположения п.(б))?
г) Сколько блоков используется для индекса, если предположить, что записи
закреплены, и применяется разреженный индекс, который уже был создан для файла
(все блоки заполнены и нет переполнений)?
д) Сколько доступов к блокам потребуется для поиска записи, если использовать
двоичный поиск в индексе?
е) Сколько потребуется блоков индекса (на всех уровнях, кроме уровня листьев),
если используется организация В-дерева и предполагается, что все блоки заполняют-
ся максимально возможным образом?
2.2. Пусть ключи являются целыми числами и наш файл состоит из записей с
ключами 1, 4, 9, ..., 152 = 225. Предположим, что в блок вмещается трн записи.
а) Каково распределение записей по участкам, если используется хешированная
организация, рассмотренная в разд. 2.2, с функцией хеширования «разделить на 7 н
взять остаток»?
**б) Объясните, почему полные квадраты в п.(а) хешируются так неоднородно?
в) Допустим, мы начали строить плотный индекс, организация которого предло-
жена в разд. 2.3, максимально плотно упаковывая в блоки нечетные полные квадраты.
Покажите организацию файла после вставки четных полных квадратов, предполагая
записи незакрепленными.
г) Повторите п.(в), предполагая записи закрепленными.
д) Покажите организацию В-дерева для файла, если вставлены пятнадцать запи-
сей в порядке их ключей. Предполагается, что В-дерево имеет параметры d = е = 2.
е) Предположим, что в качестве плотного индекса для файла используется
В-дерево при d = 2. Покажите полученную организацию, если записи вставлялись
так, что сначала следовали в числовом порядке четные квадраты, а затем — нечетные.
2.3. Допустим, поддерживается файл информации о штатах. Каждому штату
соответствует запись переменной длины с полем его названия и повторяющейся груп-
пой округов. Все группы округов имеют поля названия и населения, повторяющиеся
группы названий районов и повторяющиеся группы названий городов. Напишите
формат для записей штатов, имеющих переменную длину.
2.4. Пусть имеются записи переменной длины с форматом А (В)*. Поле А зани-
мает 20 байт, а поле В — 30 байт. Указатель требует 4 байта, а поле счетчика — 1 байт.
С каждым значением А ассоциировано от 2 до 8 значений поля В с вероятностями 0,05;
0,1; 0,2; 0,3; 0,2; 0,1; и 0,05 соответственно. При длине блоков 100 байт сравните сред-
нее число блоков на запись, если применяется:
а) метод зарезервированного пространства;
б) метод указателей с максимально плотной упаковкой записей в блоки, но с бло-
ками полей В, разделенных в соответствии с ассоциированными с ними полями А;
в) смешанный метод с пространством для р полей В вместе с каждым полем А.
Каково оптимальное значение р?
*2.5. Записи рассматриваемого файла имеют три поля: F, G и Н. Имеется 10 воз-
можных значений для F, 100 возможных значений для G и 20—для Н. Все 20 000 запи-
сей (F, G, Н) с равной вероятностью могут появляться в файле. Предположим, что во
всех запросах специфицируются значения в точности для двух полей, причем F н G
специфицируются с вероятностью 0,8, F и Н — с вероятностью 0,15 и G и Н — с вероят-
70
ностью 0,05. Предположим, наконец, что допускается возможность выбора двух нолей,
по которым нужно создать вторичные индексы. По каким двум полям должны иметься
вторичные индексы для того, чтобы математическое ожидание числа записей, подле-
жащих выборке, было минимальным? Предполагается, что в случае, когда существуют
вторичные индексы для обоих специфицированных полей, можно строить пересече-
ние множеств указателей в основной памяти перед выборкой любых записей.
2.6. При создании вторичных индексов имеет место компромисс между временем
включения/удалення и временем поиска. Допустим, что используется S иторичных
индексов и предполагаемое время поиска записи составляет 3—s с, а время включения
удаления —0,1 (s + I) с. Если в среднем производится 100 поисков на каждое включе-
ние или удаление, то при каком значении s мы получим минимальное вероятное время
выполнения операции?
2.7. Завершите доказательство теоремы 2.3.
2.8. Рассмотрите схему раздельного хеширования для поиска по частичному
соответствию из разд. 2.8. Адреса участков содержат 12 бит. Имеется четыре поля, и в
каждом запросе специфицируется в точности одно поле с вероятностями соответственно
1/2, 1/4, 1/8 и 1/8. Каково оптимальное распределение бит между полями в адресе участ-
ка?.
2.9. Имеют место условия, описанные в п. 2.8, с той лишь разницей, что в запросе
независимо специфицируется любое число полей. Вероятности того, что значения
специфицированы для четырех полей, равны соответственно 8/9, 1/2, 1/9 и 1/17. Ка-
ково оптимальное распределение бит в адресе участка?
Библиографические замечания
Структуры данных обсуждаются в ряде публикаций. Среди них особое внимепис
уделяется структурам организации внешней памяти большого объема (Кнут [101],
Хоровиц и Сани [89], Мартин [114], Готлиб и Готлиб [73]). Обзор методов хеширования
дается в книгах Морриса [120], Кнута [101] и Маурера и Льюиса [115]. Выбор схемы
физической базы данных из множества альтернатив освещается Готлибом и Томна
[74].
Быстрый поиск в упорядоченном списке рассматривается Яо и Яо [180|. Там же
доказывается сложность log logn для интерполяционного поиска. Об этом же идет речь
в работе Перла, Итаи и Авнн [133]. S-дерево, используемое в качестве плотного индек-
са, описанного в разд. 2.6, а не в общей его форме, рассмотренной в разд. 2.5, обсуж-
дается у Байера и Мак-Крейта [14]. Статьи Хелда и Стоунбрейкера [86] и Снайдера
[157] содержат интересную дискуссию о преимуществах использования В-деревьев в
системах баз данных. Яо [178] анализирует математическое ожидание заполнения
2—3 деревьев (В-деревьев с двумя или тремя сыновьями на узел) и показывает, что в
среднем внутренние узлы имеют примерно между 21 и 30% неиспользуемого простран
ства.
Выбор вторичных индексов описывается во многих работах, включая книгу
Лума и Линга [110], а также Школьника1. Вообще, принятая точка зрения состоит в
том, что содержимое базы данных может быть известно перед тем, как выбирать индек-
сы. Комер [49] показывает, что оптимальный выбор— NP-полная задача (см. Ахо,
Хопкрофт и Ульман [2] или Гарей и Джонсон [72] в связи с дискуссией о том, как из
NP-полноты следует, что проблема не может быть эффективно решена).
Использование функций раздельного хеширования для поиска по частичному
соответствию рассмотрено в общем виде Райвестом [140]. Разработка таких функций
хеширования исследована также Бурхардом [29]. Теорема 2.1 о форме функций опти-
мального хеширования доказана Болуром [27]. Теорема 2.2 для случая, когда в запро-
се специфицировано одно поле, принадлежит Ротни и Лозано [144], а теорема 2.3 заим-
ствована у Болура [27] и Ахо и Ульмана [5]. Аналогичная идея о так называемых кодах
с наложением имеет отношение и к системам баз данных. Этот вопрос рассматривается,
например, Робертсом [141].
1 В списке литературы в оригинале отсутствует библиографическое описание
этой работы. По-видимому, автор имеет в виду статью SchkolnickM. Secondary
Index Optimization. — Proc. ACM SIGMOD, 1975, p. 186— 192. — Примеч. ped.
ГЛАВА 3
ТРИ ЗАМЕЧАТЕЛЬНЫЕ МОДЕЛИ ДАННЫХ
В первой главе мы упоминали о роли модели данных как основы для
языков определения данных и манипулирования данными. Рассмотрим те-
перь три наиболее важные из таких моделей — реляционную, сетевую и ие-
рархическую. В следующих главах будет изучаться главным образом ре-
ляционная модель по причинам, которые мы укажем после подробного об-
суждения всех трех моделей. Коротко говоря, реляционная модель обла-
дает дескриптивной мощностью других моделей при меньшем числе базис-
ных понятий или специальных случаев, с которыми приходится иметь дело.
В гл. 4—6 детально освещаются некоторые аспекты реляционной модели,
в том числе ряд разработанных для нее языков манипулирования данными
высокого уровня.
Однако положение дел в настоящее время таково, что существующие
коммерческие системы почти все без исключения базируются на одной из
двух других моделей и, по всей вероятности, эта ситуация будет изменять-
ся медленно. В дальнейшем мы довольно подробно рассмотрим также ие-
рархическую и сетевую модели на основе доминирующих проектов систем
этих двух классов, а именно иерархической СУБД IMS (Information Ma-
nagement System) фирмы ИВМ и предложений Рабочей группы по базам дан-
ных (DBTG) Комитета по языку программирования КОДАСИЛ относитель-
но сетевых СУБД.
3.1. РЕЛЯЦИОННАЯ МОДЕЛЬ ДАННЫХ
В основе реляционной модели лежит математическое понятие теорети-
ко-множественного отношения, которое представляет собой подмножество
декартова произведения списка доменов. Домен — это просто множество
значений. Например, множество целых чисел есть домен. Доменами явля-
ются также множество литерных строк длины 20, действительные числа,
множество {0, 1} и т. д. Декартовым произведением доменов Dlt D2.Dh
(обозначается как х ... X Dh) называется множество всех корте-
жей (ип и2, ..., vh) длины k, таких, что Uj принадлежит Du о2 принадле-
жит Ь2 и т. д. Например, если k = 2, Dx — {0, 1} и D2 — {а, Ь, с}, то
Г>! У. В2 етъ \ \<й, о), ЬУ
Отношением называется некоторое подмножество декартова произве-
дения одного или более доменов. Поскольку речь идет о базах данных, нет
смысла обсуждать бесконечные отношения. Поэтому мы будем предпола-
гать, если не оговорено противное, что отношение является конечным. На-
пример, { (0, а), (0, с), (1, Ь)} есть отношение, подмножество определенно-
го выше D1x£>2. Другим примером отношения может служить пустое мно-
жество.
72
Элементы отношения называются кортежами. О каждом отношении,
являющемся подмножеством декартового произведения DiXD^X ... xDk,
можно сказать, что оно имеет арность k. Кортеж (uj, v2,.... yft) имеет k ком-
понентов, причем i-м компонентом является иг. Для обозначения кортежа
(ult v2, ..., vh) в дальнейшем часто используется сокращенная запись
VjV2 ...vh. Удобно представлять отношение как таблицу, где каждая строка
есть кортеж и каждый столбец соответствует одному компоненту. Столбцы
называются при этом атрибутами, и им часто присваиваются имена.
Пример 3.1. На рис. 3.1 представлено отношение с атрибутами ГОРОД,
ШТАТ и НАСЕЛЕНИЕ. Арность этого отношения равна трем. Например,
(Майами, Оклахома, 13880)
есть кортеж.
ГОРОД ШТАТ НАСЕЛЕНИЕ
Сан-Диего Техас 4490
Майами Оклахома 13 880
Питтсбург Айова 509
Рис. 3.1. Отношение
Альтернативная формализация отношений
Если присвоить столбцам отношений имена атрибутов, то порядок столб-
цов станет несущественным. С математической точки зрения мы рассматри-
ваем кортежи как отображения имен атрибутов в значения, принадлежащие
доменам атрибутов. При таком подходе оказываются эквивалентными отно-
шения, которые не были бы эквивалентными при более традиционном опре-
делении понятия отношения.
Пример 3.2. На рис. 3.2 показаны два варианта одного и того же отношения,
рассматриваемого как множество отображений. Например, кортеж (Буффало, Зап.
Виргиния, 831) как отображение / определяется следующим образом: f (ГОРОД) =
= Буффало, f (ШТАТ) = Зап. Виргиния, f (НАСЕЛЕНИЕ) = 831. Отметим, что
порядок перечисления кортежей не играет никакой роли с точки зрения обоих опреде-
лений. Однако при традиционном предстаилении кортежа как списка значений корте-
жи (Буффало, Зап. Виргиния, 831) и (Зап. Виргиния, 831, Буффало) не были бы оди-
наковыми, а отношения на рис. 3.2 также не представлялись бы одними и теми же-И
ГОРОД ШТАТ НАСЕЛЕНИЕ
Буффало Зап. Виргиния 831
Провиденс Юта 1608
Лас-Вегас Нью-Мексико 13 865
ШТАТ НАСЕЛЕНИЕ ГОРОД
Юта 1608 Провиденс
Зап. Виргиния 831 Буффало
Нью-Мексико 13865 Лас-Вегас
Рис. 3.2. Два представления одного и того же отноше-
ния
73
Поскольку существующие реляционные системы позволяют печатать
столбцы отношений в любом порядке, примем в качестве стандартного опре-
деление отношения как множества отображений.
Однако встречаются ситуации, например, при обсуждении реляцион-
ной алгебры в разд. 4.1, когда более естественно использовать определение
отношения как множества списков. К счастью, существует очевидный ме-
тод преобразования одного представления отношения в другое. Если зада-
но отношение в смысле множества списков, мы можем присвоить его столб-
цам произвольные имена атрибутов, после чего оно может рассматриваться
как множество отображений. Наоборот, если задано отношение в смысле
множества отображений, мы можем зафиксировать порядок атрибутов и
преобразовать его в множество списков.
Схемы отношений
Список имен атрибутов отношения называется схемой отношения. Если
отношение называется REL и его.схема имеет атрибуты Alt А2, ..., Ak, то
такую схему чаще всего будем записывать как REL (Ль Л2, .... Ак). Мож-
но заметить аналогию между схемой отношения и форматом записи, между
отношением и файлом, а также между кортежем и записью. Различия в каж-
дом случае являются различиями уровня абстракции. Так, одной из воз-
можных реализаций отношения служит файл записей, формат которых эк-
вивалентен списку атрибутов в схеме отношения, причем каждому кортежу
соответствует одна запись. Можно, однако, придумать много других реа-
лизаций отношения. Некоторые из них обсуждаются ниже.
Представление данных
Совокупность схем отношений, используемых для представления ин-
формации, называется схемой (реляционной) базы данных, а текущие значе-
ния соответствующих отношений — (реляционной) базой данных. Имеется,
конечно, возможность создавать отношения с любым множеством атрибутов
в схеме отношения и давать любую желаемую интерпретацию кортежам.
Однако мы можем представить себе типичный образец использования реля-
ционной базы данных, если вспомним дискуссию о модели объектов-связей
из разд. 1.4. Данные из диаграммы объектов-связей представляются двумя
видами отношений.
1. Набор объектов может быть представлен отношением, схема которо-
го содержит все атрибуты данного набора объектов. Если этот набор таков,
что его объекты идентифицируются с помощью связи с некоторым другим
набором, то схема отношения содержит, кроме того, атрибуты ключа второ-
го набора, но не его неключевые атрибуты. Каждый кортеж в отношении
представляет одни объект из набора объектов.
2. Связь между наборами объектов Et, Е2, ..., Ek представляется от-
ношением, схема которого состоит из атрибутов ключей каждого из этих
наборов. Мы предполагаем, что благодаря переименованию атрибутов, если
это необходимо, никакие два набора объектов не будут иметь атрибутов с оди-
наковыми именами. Кортеж t в таком отношении обозначает список объектов
е1( е2, ..., ек, где et — элемент набора объектов Et для каждого i. Таким
образом, et — единственный объект в Eit значения атрибутов которого, яв-
ляющихся ключевыми атрибутами Е{, находятся среди компонентов кор-
тежа t. Присутствие кортежа t в отношении указывает, что объекты et, е2, ...
...,ек ассоциируются с помощью связи в запросе.
74
Пример 3.3. Исследуем базу данных, в которой записаны сведения об игро-
ках в бейсбол и нх командах, средние бейтинги1 игроков и позиции в игре. Прежде
чем показать, как данные такого рода могут быть представлены в виде отношений,
рассмотрим диаграмму объектов-связей, которая представляет «реальный мир», отно-
сящийся к этому примеру. Объектами являются:
1. ИГРОКИ с атрибутами
ИМЯ
РОДИНА
ДЛТА_РОЖД
/*место рождения*/
/* дата рождения*/
где атрибут ИМЯ является ключом.
2. ПОЗИЦИИ с атрибутами
НАЗВАНИЕ-ПОЗИЦИИ
НОМЕР-ПОЗИЦИИ
/* например, подающий */
/* 1 — для подающего, 2 — для ловя-
щего...*/
Любой из этих атрибутов может служить ключом, но мы примем в качестве ключа
НОМЕР-ПОЗИЦИИ.
3. КОМАНДЫ с атрибутами
СПОРТКЛУБ /* объясняется ниже*/
ГОРОД
ГОД
Атрибут СПОРТКЛУБ является уникальным идентификатором, который мы
назначаем для бейсбольного спортклуба. Поскольку спортклуб является предприя.
тием, он существует как некоторый объект даже в том случае, если он переезжает в
другой город или изменяет свое название (например, команда «Редз» из Цинциннати
называлась ранее «Ред Легз»), В данном примере текущее название спортклуба исполь-
зуется всегда как значение атрибута СПОРТКЛУБ. Команда (в отличие от спортклуба)
представляет собой совокупность игроков, тренеров и т. д., работающих в спортклубе
или выступающих за него в текущем году. Ключом для набора объектов КОМАНДА
является СПОРТКЛУБ и ГОД.
4. СРЕДНИЙ-БЕЙТИНГ — множество средних бейтингов. Этот набор объек-
тов имеет один атрибут ЗНАЧЕНИЕ-БЕЙТИНГА, значения которого представляются
в тысячных долях (промилле). Очевидно, что ЗНАЧЕНИЕ-БЕЙТИНГА является
ключом.
Рассмотрим следующие связи:
1. Связь СЕЗОН между наборами объектов ИГРОКИ, КОМАНДЫ и СРЕДНИЙ-
БЕЙТИНГ. Игрок р, команда t и средний бейтинг Ь находятся в связи СЕЗОН, если
р играет за команду t и его средний бейтинг есть Ь. Заметим, что СЕЗОН является
тернарной связью «многие к одному» от наборов ИГРОКИ и КОМАНДЫ к набору
СРЕДНИЙ-БЕЙТИНГ в том смысле, что если заданы некоторые игрок и команда,
то этот игрок имеет единственный средний бейтинг. Вспомним, что «команда» сущест-
вует в течение одного конкретного года, поэтому обычно игрок принадлежит несколь-
ким командам и имеет несколько средних бейтингов, ио в точности один средний бей-
тинг в год.
2. Связь ИГРЫ между наборами объектов ИГРОКИ и ПОЗИЦИИ. Это— связь
«многие ко многим», указывающая, в каких позициях действовал игрок в своей спор-
тивной карьере.
1 От англ, «batting» — характеристика мастерства владения игрока битой во
время игры. — Примеч. ред.
75
Диаграмма объектов-связей для описываемой базы данных показана на рис. 3.3.
Стрелка, проведенная от связи СЕЗОН к набору СРЕДНИЙ-БЕЙТИНГ, указывает,
что СЕЗОН есть связь «многие к одному» от наборов ИГРОКИ и КОМАНДЫ к набору
СРЕДНИЙ-БЕЙТИНГ.
Выберем теперь схемы отношений, которые будут представлять наборы объектов
и связи. Запишем сначала схему отношения для каждого объекта, за исключением
набора СРЕДНИЙ-БЕЙТИНГ. Хотя ничто не мешает нам иметь однокомпонентное
отношение (называемое унарным), такое отношение ничего бы нам не говорило. Оно
является просто множеством, состоящим из всех возможных средних бейтингов. Отно-
шения для других трех наборов объектов:
ИГРОКИ (ИМЯ, РОДИНА, ДАТА.РОЖД)
КОМАНДЫ (СПОРТКЛУБ, ГОРОД, ГОД)
ПОЗИЦИИ (НАЗВАНИЕ-ПОЗИЦИИ, НОМЕР.ПОЗИЦИИ)
Связь ИГРЫ представляется отношением, атрибуты которого образуют ключи
наборов объектов ИГРОКИ и ПОЗИЦИИ. Каждый нз этих наборов имеет ключ
Рис. 3.3. Диаграмма объектов-связей для бейсбольной базы
данных
состоящий нз одного атрибута: ИМЯ и НАЗВАНИЕ-ПОЗИЦИИ соответственно.
Таким образом, появляется отношение
ИГРЫ (ИМЯ, НАЗВАНИЕ-ПОЗИЦИИ)
Для связи СЕЗОН нам необходимы ключи наборов объектов ИГРОКИ, КОМАН-
ДЫ и СРЕДНИЙ-БЕЙТИНГ. Ими являются ИМЯ, (СПОРТКЛУБ, ГОД) н ЗНАЧЕ-
НИЕ-БЕЙТИНГА соответственно. Таким образом, получаем отношение
СЕЗОН (ИМЯ, СПОРТКЛУБ, ГОД, ЗНАЧЕНИЕ.БЕЙТИНГА)
На рнс. 3.4 показаны некоторые кортежи, которые появились бы в этих пяти
отношениях, если бы они содержали все текущие данные1. Отметим, что кортежи не
обязательно должны появляться в каком-либо определенном порядке и здесь они по-
казаны, конечно, не все. Например, отношение СЕЗОН содержит кортежи для Раса
за все годы между 1914-м и 1935-м.
1 Источник. Turkin and Thompson. The Official Encyclopedia of Base-
ball. Barnes and Co.
76
имя РОДИНА ДАТА—РОЖД
Джордж Рас Тирус Кобб Джек Робинсон Балтимор, штат Мэри- ленд Нарроуз, штат Джорд- жия Каир, штат Джорджия 6.02.1895 18,12,1886 31.01.1919
Отношение ИГРОКИ
СПОРТКЛУБ ГОРОД год
Ред Соке Бостон 1917
Доджерз Бруклин 1949
Тайгерз Детройт 1911
Отношение КОМАНДЫ
НАЗВАНИЕ _ позиции НОМЕР — позиции
Подающий I
Ловящий 2
Первая база 3
имя НАЗВАНИЕ- позиции
Стенли Мьюжл Тирус Кобб Тнрус Кобб Первая база Центральное поле Первая база
Отношение ПОЗИЦИИ Отношение ИГРЫ
имя СПОРТКЛУБ ГОД ЗНАЧЕНИЕ- БЕЙТИНГА
Стенли Мьюжл Кардинелз 1948 0,376
Джордж Рас Ред Соке 1917 0,325
Джордж Рас Янкиз 1923 0,393
Тнрус Кобб Тайгерз 1911 0,420
Джек Робинсон Доджерз 1949 0,342
Отношение СЕЗОН
Рис. 3.4. Фрагменты пяти файлов для бейсбольной базы дан-
ных
77
Реализация реляционной базы данных
Очевидно, отношение может быть представлено в виде файла, формат
записей которого состоит из полей, соответствующих атрибутам в схеме
отношения в некотором фиксированном порядке. Многие языки определе-
ния данных, основанные на реляционной модели, дают пользователю воз-
можность (наряду с другими факультативными возможностями) специфи-
цировать организацию файла. Обычно пользователь может осуществлять
выбор какого-либо подмножества возможностей, описанных в разд. 2.2—2.5,
таких, как хеширование или индексирование. Для отношений с небольшим
числом кортежей лучшей является, вероятно, иная альтернатива — «куча».
Р> этом случае кортежи перечисляются как записи в файле без определен-
ного порядка. Многие реляционные языки манипулирования данными об-
ладают еще одним полезным свойством — они предоставляют пользователю
возможность специфицировать по своему усмотрению вторичные индексы по
некоторым атрибутам или множествам атрибутов1.
Поскольку многие способы организации файлов зависят от существова-
ния ключа записей, реляционный язык определения данных также должен
обеспечивать механизм для спецификации одного атрибута или их множест-
ва в качестве ключа отношения. Понятие ключа отношения имеет, по сущест-
ву, тот же смысл, что и понятие ключа в контексте файлов или наборов объ-
ектов. Предполагается, что отношение не должно иметь двух кортежей, в
которых совпадают все атрибуты ключа. Например, ИМЯ и ГОД образуют
ключ отношения СЕЗОН на рис. 3.4. Мы считаем, что не найдется двух кор-
тежей, подобных следующим:
ИМЯ СПОРТКЛУБ ГОД ЗНАЧЕНИЕ- БЕЙТИНГА
Джордж Рас Ред Соке 1917 0,325
Джордж Рас Янкнз 1917 0,302
поскольку, как предполагалось ранее, каждый игрок в данном году играл
только за одну команду (в противном случае будем записывать лишь коман-
ду, в которой игрок закончил сезон).
Атрибуты, которые образуют ключ отношения, служат, очевидно, так-
же и ключом для файла. Интересно заметить, что, если мы проектируем на-
ши схемы отношения в соответствии с описанным выше методом, отношения
для наборов объектов заимствуют ключ из набора объектов. Точно так же
отношения, конструируемые для представления связей «многие к одному»
от набора объектов Ег к набору Ег, могут заимствовать ключ из Ег. Толь-
ко отношения для связей «многие ко многим» могут не иметь никакого клю-
ча, кроме тривиального, состоящего из всех атрибутов. Общая проблема на-
хождения и использования ключей в отношениях хорошо разработана, и
мы познакомимся с некоторыми разделами теории этого вопроса в гл. 5.
1 В ряде реляционных языков действительно предусматриваются подобные воз-
можности. Однако в соответствии с новыми представлениями об архитектуре СУБД
спецификация необходимости использования индексирования является функцией не
языка пользователя, а механизмов среды хранения. — Примеч. ред.
'Ь
Следует подчеркнуть, что нет необходимости представлять каждый кор-
теж в виде записи, хотя данному соглашению отдается наибольшее предпоч-
тение в реализациях существующих систем. Например, отношение с атри-
бутами А, В и С можно представить в виде логического файла с записями
переменной длины, имеющими формат А (В (С)*)*. Этот логический файл
реализуется одним из способов, предложенных в разд. 2.6. Такая органи-
зация сохраняет пространство, если в домене атрибутов А и (или) В име-
ется относительно немного значений. Так, отношение КОМАНДЫ из при-
мера 3.3 удобно представить как логический файл СПОРТКЛУБ (ГОРОД
(ГОД)*)*. Атрибут СПОРТКЛУБ имеет наименьший домен, включающий
примерно две дюжины значений. В указанном логическом файле каждое
из них появляется в точности один раз, а в отношении КОМАНДЫ — во
множестве кортежей, число которых равно числу лет его существования.
Подобным же образом каждый город появляется в одном кортеже этого от-
ношения для любого года, в течение которого в данном городе находился
спортклуб. В то же время в логическом файле такой город появляется лишь
один раз.
Операции над реляционными базами данных
Основными операциями, с помощью которых модифицируется база дан-
ных, являются включение, удаление и модификация (см. гл. 2.). Если для
описания базы данных используется реляционная модель, указанные опе-
рации естественно применять к кортежам. Реализация этих операций опи-
сывается далее в предположении, что отношения представляются с помощью
файлов, причем кортежи и записи находятся во взаимно-однозначном соот-
ветствии, и что файлы организованы одним из способов, рассмотренных в
гл. 2. Однако читатель должен быть в состоянии восполнить детали реализа-
ции, если используется логический файл, состоящий из записей перемен-
ной длины. При любом другом подходе реализатор должен позаботиться
о том, чтобы операции включения, удаления и модификации могли выпол-
няться без чрезмерных трудностей.
1. Включение. Для этой операции задаются кортеж и отношение, в ко-
торое он должен быть включен. Выбираем из кортежа значения атрибутов,
образующих ключ файла. Для того чтобы включить построенную из корте-
жа запись, необходимо воспользоваться этими значениями, следуя указани-
ям гл. 2 для соответствующей организации файла. Осуществить преобразо-
вание кортежа в запись нетрудно. Поскольку кортеж состоит из логических
элементов данных, он может, например, иметь в качестве значения атрибу-
та строку литер, слишком короткую для соответствующего поля записи,
которое содержит строки литер фиксированной длины. Тогда для формиро-
вания значения поля мы должны дополнить значение атрибута пробелами.
Подобным же образом, значение атрибута может быть целым, в то время как
соответствующее поле принимает действительные значения. Здесь вновь
требуется простое преобразование.
2. Удаление. Предположим, что задано отношение и значения по крайней
мере тех атрибутов, которые образуют ключ этого отношения и реализую-
щего его файла. Следовательно, процедура удаления для соответствующей
организации может быть применена непосредственно к лежащему в основе
файлу. Большинство систем допускает удаление множества кортежей даже
в том случае, когда не задан ключ. При этом необходимо просматривать
полный файл независимо от используемой стандартной организации.
79
3. Модификация. Здесь заданы отношение, значения атрибутов ключа
и новые значения для изменяемых атрибутов. В этом случае опять произво-
дится простое преобразование значений атрибутов в значения полей и к
файлу можно применить соответствующую процедуру модификации, опи-
санную в гл. 2. Если не заданы значения атрибутов ключа, то мы снова бу-
дем вынуждены просматривать полный файл.
Запросы в реляционной базе данных
Операция поиска в отношении также не преподносит каких-либо сюр-
призов. Однако использующие реляционную модель языки манипулирова-
ния данными обычно располагают развитым множеством команд, которые
позволяют строить целый ряд «запросов» для получения данных из одного
или более отношений. В следующей главе приводятся некоторые примеры
формулировки «запросов» в существующих реляционных системах управ-
ления базами данных. Здесь же мы рассмотрим несколько типичных запро-
сов и проблемы, которые они порождают.
Пример 3.4. Вернемся к реляционной базе данных, представленной на
рнс. 3.4, и рассмотрим запрос, который сводится к поиску значений некоторых атри-
бутов из кортежей отношения, удовлетворяющих данному условию. Например, мы
можем запросить имя и спортклуб для всех тех игроков, у которых бейтинг был не ниже
0,300 в течение по меньшей мере одного сезона в период игры за этот спортклуб. Чтобы
выполнить такой запрос, необходимо просмотреть кортежи отношения СЕЗОН или,
точнее, записи представляющего его файла. Всякий раз, когда встречается кортеж,
для которого ЗНАЧЕНИЕ-БЕЙТИНГА больше или равно 0,300, мы выбираем из
него значения атрибутов ИМЯ и СПОРТКЛУБ. Проверку записи для каждого корте-
жа можно было бы исключить, если бы для данного файла имелся вторичный индекс
по атрибуту ЗНАЧЕНИЕ-БЕЙТИНГА. Удобно также отсортировать вторичный
индекс, являющийся логическим файлом с записями переменной длины формата ЗНА-
ЧЕНИЕ-БЕЙТИНГА (ЗАПИСЬ)*, по его ключу ЗНАЧЕНИЕ-БЕЙТИНГА. Ни
одно из этих средств не является, однако, необходимым. Они лишь ускоряют обработку.
После того как собраны все требуемые пары (ИМЯ, СПОРТКЛУБ), мы можем
нх напечатать. Иными словами, мы создали отношение со схемой (ИМЯ, СПОРТКЛУБ).
Но математическое понятие отношения [не допускает дубликатов кортежей. Следова-
тельно, необходимо в принципе удалить дубликаты кортежей, которые будут появлять-
ся всякий раз, когда игрок имеет бейтинг не менее 0,300 в течение двух илн более се-
зонов его выступления за один и тот же спортклуб. Можно, например, отсортировать
отношение по атрибуту ИМЯ, а каждую группу кортежей с одним и тем же значением
ИМЯ — по атрибуту СПОРТКЛУБ. Тогда дублирующие кортежи станут соседними
по порядку и их можно будет легко удалить. Многие реляционные СУБД не ликвиди-
руют, однако, дублирующие кортежи, за исключением тех случаев, когда пользователь
специально указывает, что это нужно сделать.
Приведем еще один пример, для чего снова обратимся к базе данных, приведен-
ной на рис. 3.4. Йредположим, что требуется найти спортклуб, за который Тнрус
Кобб играл в 1911 г. Поскольку атрибуты ИМЯ и ГОД образуют ключ отношения
СЕЗОН, достаточно просто просмотреть файл, представляющий это отношение,
найти нужную запись и определить, что атрибут СПОРТКЛУБ в этой записи
имеет значение «Тайгерз».
Предположим далее, что вместо спортклуба Кобба в 1911 г. мы запрашиваем го-
род, в котором он в этом году играл. Такая информация недоступна из отношения
СЕЗОН. Мы можем, однако, получить ответ, определив сначала описанным выше
способом, что Кобб играл в 1911 г. за «Тайгерз», а затем, используя («Тайгерз», 1911)
как значение ключа в отношении КОМАНДЫ, установить, что этот спортклуб нахо-
дился в 1911 г. в Детройте.!
Процесс продвижения по логически связанным данным от отношения к
отношению с целью получения требуемой информации называется навига-
цией (см. последнюю часть примера 3.4). В гл. 4 будут рассмотрены некото-
рые методы, благодаря которым реляционные языки манипулирования дан-
80
ними обеспечивают пользователю возможность осуществлять навигацию,
т. е. связывать информацию из двух или более отношений. Вообще, навига-
ция в более широком смысле, означающая следование по связям между не-
сколькими частями базы данных, является компонентом любого языка ма-
нипулирования данными, независимо от модели данных.
3.2. СЕТЕВАЯ МОДЕЛЬ ДАННЫХ
Сетевая модель данных является, грубо говоря, моделью объектов-свя-
зей, где допускаются только бинарные связи «многие к одному»1. Указан-
ное ограничение позволяет использовать для данных простую модель ори-
ентированных графов. Кроме того, упрощается реализация связей, что бу-
дет показано при обсуждении конкретной реализации сетевой модели в гл. 7.
Для сетевой модели не существует установившейся терминологии. Поэ-
тому мы введем свою терминологию и постараемся согласовать ее с терми-
нологией, принятой в настоящей работе для файлов и других моделей дан-
ных. Аналогом набора объектов в сетевой модели служит тип логической
записи. Тип логической записи представляет собой, по существу, отношение,
т. е. поименованное множество кортежей. Однако, как и в модели объектов-
связей, мы допускаем возможность сущестования двух идентичных записей
одного и того же типа логической записи. Эти записи различаются только
благодаря их связям с логическими записями другого типа. В сетевой модели
мы воспользуемся термином логическая запись вместо «кортеж» и формат ло-
гической записи2 вместо «схема отношения». Имена компонентов в формате
логической записи будем называть полями.
Мотивируем сначала наше решение о целесообразности введения раз-
личной терминологии для реляционной и сетевой моделей. Напомним, что
в сетевой модели типы логических записей используются главным образом
для представления того, что мы называли наборами объектов, в то время как
в реляционной модели отношение служит для представления и объектов, и
связей. Хотя и невозможно избежать эксцентричных применений любой мо-
дели данных, попытка слить понятия отношения и типа логической записи,
по нашему мнению, противоречила бы их интуитивному назначению.
В контексте сетевой модели понятие связь является синонимом бинар-
ной связи «многие к одному». Чтобы представить типы записей и их связи,
нужно изобразить ориентированный граф, называемый сетью, который в
действительности представляет собой упрощенную диаграмму объектов-
связей. Узлы этого графа должны соответствовать типам записей. Если су-
ществует связь «многие к одному» от типа записи 7\ к типу записи Т2, то мы
проводим дугу от узла для 7\ к узлу для Т2, и говорим, что имеется связь
от Tj к Т2. Узлы и дуги помечаются именами их типов записей и связей.
1 Некоторые более общие определения сетевой модели допускают связи «многие
ко многим», требуя только, чтобы они были бинарными.
2 Мы опускаем слово «логическая» из терминов «логическая запись» или «тип
(формат) логической записи» всякий раз, когда Это не приводит к путанице с сущест-
вующей терминологией для файлов.
8 В некоторых работах по этому вопросу дуги изображаются с противоположной
ориентацией. Однако мы выбрали такое их направление для обеспечения согласован-
ности с понятием функциональной зависимости, обсуждаемым в гл. 5. Наша точка зре-
ния заключается в том, что стрелки означают «одиозиачно определяет». Таким образом,
поскольку каждая запись типа 7\ связана в лучшем случае с одной записью типа
Т9, стрелка должна быть направлена к Т2.
81
Представление диаграмм объектов-связей
Как уже указывалось, наборы объектов непосредственно представляют-
ся типами логических записей. Атрибуты набора объектов служат полями
формата логической записи. В том случае, когда некоторый объект одно-
значно определяется лишь через связь с другим объектом, в формат добав-
ляется еще одно поле — порядковый номер в наборе объектов, уникально
идентифицирующий каждый его объект. Этот порядковый номер может быть
полем только на логическом уровне. В реализации в качестве «порядкового
номера» объекта можно использовать адрес представляющей его записи.
Среди связей модели объектов-связей непосредственно представляются
связями сетевой модели только бинарные и имеющие вид «многие к одному»
(или, в частном случае, «один к одному»). Можно, однако, воспользоваться
следующим приемом представления произвольных связей. Пусть существу-
ет некоторая связь 7? между наборами объектов Ег, Ег, Еь. Создадим
новый тип логической записи Т, представляющий кортежи (elt ег, ek)
длины k из объектов, которые находятся в связи R. Формат этого типа запи-
си может состоять из единственного поля, которое является порядковым
номером, идентифицирующим логические записи данного типа, хотя во
многих ситуациях было бы удобно добавить в формат нового типа записи
Т другие содержащие информацию поля. Создадим далее связи Llt Ьг, ...,
Lk, где Lt есть связь от типа записи Т к типу записи 7\-для набора объек-
тов Et. Цель заключается в том, чтобы запись типа Т для (еп е2, ..., efe) бы-
ла связана с записью типа 7\ для и, таким образом, каждая связь име-
ла вид «многие к одному».
Пример 3.5. Представим в терминах сетевой модели информацию об игроках
в бейсбол и командах, содержащуюся в диаграмме объектов-связей на рис. 3.3. Созда-
дим сначала типы логических записей ИГРОКИ, КОМАНДЫ и ПОЗИЦИИ. Поля
соответствующих форматов логических записей совпадают с атрибутами одноименных
отношений из примера 3.3. По причинам, которые будут указаны прн рассмотрении
связи СЕЗОН, не существует типа логической записи, соответствующего набору объек-
тов СРЕДНИЙ-БЕЙТИНГ.
Рассмотрим теперь связь «многие ко многим» ИГРЫ между наборами объектов
ИГРОКИ и ПОЗИЦИИ. Для представления этой связи необходим новый тип записи,
который назовем ИП (ИГРОКИ-ПОЗИЦИИ). Формат записи типа ИП состоит нз по-
рядкового номера ИП_ ИД. Существует две связи в сетевой модели— связь ИП-ИГ-
РОКИ от типа записей ИП к типу записи ИГРОКИ и связь ИП-ПОЗИЦИИ от типа
записей ИП к типу записей ПОЗИЦИИ.
Необходимо также представить тернарную связь СЕЗОН между наборами объек-
тов ИГРОКИ, КОМАНДЫ и СРЕДНИЙ-БЕЙТИНГ. Создадим новый тип логичес-
кой записи ИКС (ИГРОКИ—КОМАНДЫ-СРЕДНИЙ-БЕЙТЙНГ) с полем порядково-
го номера ИКС-ИД, а также связь ИКС_ИГРОКИ от типа записи ИКС к типу записи
ИГРОКИ и связь ИКС_КОМАНДЫ от типа записи ИКС к типу записи КОМАНДЫ.
Можно также создать связь от ИКС к типу записи, соответствующему набору объектов
СРЕДНИЙ-БЕЙТЙНГ, ио в этом нет необходимости, поскольку связь СЕЗОН одно-
значно определяет средний бейтинг для заданного игрока в команде. Таким образом,
мы можем включить атрибут ЗНАЧЕНИЕ—БЕЙТИНГА в формат записи ИКС,
что позволяет обойтись без типа записи СРЕДНИЙ-БЕЙТИНГ и связи от ИКС к
этому типу записей. Заметим, что, в принципе, атрибуты ИГРОКИ и КОМАНДЫ
с тем же успехом могли быть включены в формат ИКС. Но такой подход приводит к
нерациональному использованию памяти, так как значения атрибутов каждой команды
в этом случае повторяются для каждого ее игрока, а значения атрибутов игрока по-
вторяются для каждой команды, за которую он играл.
Ниже перечислены определенные нами типы логических записей, где, как и для
схем отношений, R (Hi, А2, .... Лл) обозначает тип записи R с форматом Л1( А2, .... А^:
ИГРОКИ (ИМЯ, РОДИНА, ДАТА-РОЖД)
КОМАНДЫ (СПОРТКЛУБ, ГОРОД, ГОД)
ПОЗИЦИИ (НАЗВАНИЕ-ПОЗИЦИИ, НОМЕР-ПОЗИЦИИ)
82
ИП (ИП_ИД)
ИКС (ИКС-ИД), ЗНАЧЕНИЕ-БЕЙТИНГА)
Кроме того имеем связи:
ИП-ИГРОКИ — от ИП к ИГРОКИ
ИП-ПОЗИЦИИ — от ИП к ПОЗИЦИИ
ИКС_ИГРОКИ — от ИКС к ИГРОКИ
ИКС-КОМАНДЫ — от ИКС к КОМАНДЫ
Полученная сеть показана на рис. 3.5.
Рис. 3.5. Сеть бейсболь-
ной базы данных
ип_играни
И Репозиции
Рис. 3.6. Некоторые логические записи в бейсбольной базе данных
На рис. 3.6 показаны некоторые экземпляры логических записей каждого типа
и экземпляры связей между этими записями. Могут, конечно, существовать и другие
экземпляры связей, в которых участвуют некоторые из приведенных записей.!
83
Реализация сети
Очевидный способ представления логических записей данного типа с
помощью файла заключается в том, что в любой его записи предусматрива-
ется одно поле для каждого поля логической записи. При этом благодаря
использованию адресов записей с целью их уникальной идентификации мож-
но обойтись без полей искусственно созданных порядковых номеров атри-
бутов, например, в типах записей ИП и ИКС из примера 3.5. Как мы уви-
дим в дальнейшем, даже если формат логической записи состоит только из
атрибута порядкового номера, она не обязательно должна полностью исчез-
нуть. Присутствие таких записей, конечно, будет оказывать влияние на ор-
ганизацию базы данных независимо от того, какое представление выбрано
для сети.
Пусть имеется связь от типа записи 7\ к типу записи Т2 вида «многие
к одному». Эту связь можно представлять записями переменной длины с фор-
Запись
типа 1?
Записи
типа Т-/
Указатель для сдязи L
Указатели для сВязи L.
Рис. 3.7. Циклическая цепь
матом Т2 (Л)*, т. е. после каждой записи сипа Т2 перечисляются все свя-
занные с нею записи типа Т\. Такие записи переменной длины могут быть
представлены одним из способов, которые обсуждались в разд. 2.6. Если
существует другая связь от Т3 к Т2, можно перечислять экземпляры типа
записи Т3 с соответствующими записями типа Т2, используя формат записи
переменной длины вида Т2 (7\)* (Т3)*. И в этом случае для реализации
записей переменной длины может применяться методология разд. 2.6.
Если задана еще одна связь от 7\ к некоторому типу записи мы не
можем перечислить записи 7\ после записей Т2, а также после записей 7\.
По крайней мере, едва ли это было бы эффективным или удобным. Необ-
ходим, следовательно, иной способ представления связей, при котором не
требуется, чтобы записи одного типа были смежными с записями другого
типа. Такая организация, называемая мультисписком, предусматривает в
любой записи один указатель для каждой связи, в которой она участвует.
Существует, однако, факультативная возможность исключения указателя
для какой-либо связи и представления ее записями переменной длины, как
описывалось выше.
Предположим, что имеется связь L от 7\ к Т2. Для каждой записи R
типа Т2 создадим циклическую цепь от R ко всем записям Rj, R2, ..., Rh
типа 7\, связанным с R связью L, а затем назад к R. С этой целью в записи
типов Т2 и Т2 включены указатели для связи L. Пример такой цепи пока-
зан на рис. 3.7. Отметим, что мы можем следовать по цепи от R к каждой из
записей Rb R2, ..., Rft, и, если записи типа Т2 идентифицируемы некоторым
образом (например, каждая запись начинается несколькими битами, ука-
84
зывающими ее тип, или тип определяется адресом записи), возможен пере-
ход от любой из записей R2.........Rk к R.
Важно вспомнить, что в организации мультисписка каждая запись со-
держит столько указателей, в скольких связях участвует ее тип записи.
Поскольку указатели являются в записи полями и, следовательно, находят-
ся в фиксированных позициях, можно идти по цепи для конкретной связи,
не опасаясь того, что мы случайно следуем в соответствии с некоторой дру-
гой связью. Вспомним также, что, поскольку здесь допускаются только свя-
зи «многие к одному», любая циклическая цепь имеет в точности одну запись
первого типа и нуль или более записей второго типа. Заметим, что при по-
пытке представлять с помощью мультисписков связи «многие ко многим»
нам пришлось бы столкнуться с несколькими проблемами, поскольку каж-
дая запись может находиться во многих цепях для одной и той же связи.
Рис. 3.8. Мультнсписковая реализация сети
Мы не могли бы заранее знать, сколько указателей нужно включить в запи-
си для каждой связи, и у нас возникли бы затруднения при опеределении свя-
зей, поддерживаемых той или иной цепью. Для решения такой задачи не
существует удобного способа, поэтому в сетевой модели придается особое
значение связям «многие к одному».
Пример 3.6. Рассмотрим простой пример связи «многие ко многим», реали-
зуемой двумя связями сетевой модели вида «многие к одному» и типом фиктивной за-
писи. Два набора объектов ОТДЕЛЫ (универмага) и ИЗДЕЛИЯ находятся в связи
ПРОДАЖИ. Так как большинство отделов продает более одного товара н некоторый
товар может быть продан более, чем одним отделом, ПРОДАЖИ является связью «мно-
гие ко многим». Для представления связи ПРОДАЖИ в сетевой модели требуется про-
межуточный тип записи ОИ (отделы — изделия) и две связи:
1. ТОРГУЮЩИЙ-ОТДЕЛ — от ОИ к ОТДЕЛЫ
2. ПРОДАННОЕ-ИЗДЕЛИЕ — от ОИ к ТОВАРЫ
На рис. 3.8 приведен фрагмент физической базы данных, где связи представлены
мультисписками. Здесь показаны два отдела (одежды и игрушек) и пять товаров:
1. Мужские сорочки, проданные отделом одежды.
2. Юбки, проданные отделом одежды.
3. Куклы, проданные отделом игрушек.
4. Одежда для кукол, проданная отделами игрушек и одежды.
5. Гребешки василисков, не проданные ни одним отделом в связи с отсутствием
спроса.
На этом рисунке мы видим два указателя в каждой записи типа ОИ. Первый
из них используется для связи ТОРГУЮЩИЙ-ОТДЕЛ, а второй — для связи ИРО-
ДАННОЕ-ИЗДЕЛИЕ. В записях ОТДЕЛЫ показан только указатель для < яязи
ТОРГУЮЩИЙ-ОТДЕЛ. Могут, одиако, существовать и другие связи, в которых
участвуют ОТДЕЛЫ. Аналогично в записях ИЗДЕЛИЯ показаны лишь указатели
для связи ПРОДАННОЕ-ИЗДЕЛИЕ. Указатели для связи ТОРГУЮЩИЙ ОТДЕЛ
показаны сплошными линиями, а для связи ПРОДАННОЕ_ИЗДЕЛИЕ — пунктир-
ными.
Операции над сетями
Как н в реляционной модели, основные команды для изменения сете-
вой базы данных — это включение, удаление и модификация. Но в отличие
от реляционной модели, где они применялись только к отношениям, в се-
тевой модели эти команды оперируют и типами логических записей, и свя-
зями. Общим для всех трех операций является то, что каждая из них реа-
лизуется соответствующей операцией над некоторым файлом. Поэтому ог-
раничимся здесь рассмотрением лишь операции включения.
Чтобы включить логическую запись в тип логической записи, нужно
прежде всего создать физическую запись нз логической аналогично тому, как
осуществлялось преобразование кортежа в запись в реляционной модели.
Далее эта запись включается в файл, представляющий тип логической запи-
си, с использованием подходящего метода из гл. 2 в зависимости от органи-
зации файла.
Допустим теперь, что имеется связь L от типа записи 7\ к типу записи
Т2 и с ее помощью нужно представить, что запись типа Тг ассоциируется
с записью /?2 типа Т2. Сначала включаем записи R± и R2 в файлы соответ-
ственно для 7\ и Т2 (когда это необходимо). В том случае, когда связь L
представлена записями переменной длины формата Тг (7\)*, находим запись
для /?2 в файле, представляющем записи переменной длины, и включаем Rv
в список ассоциированных с R2 записей типа Tlt используя для этого ал-
горитм из разд. 2.6. Точный алгоритм зависит от способа представления
записей переменной длины.
Если связь L представлена мультисписковой организацией, нужно
снова найти запись для /?2 в файле типа записи Тг. В файле типа записи
Т\ мы находим также запись для и включаем ее в цепь для записи R2.
При этом используются элементарные операции обработки списков над по-
лями и R2, которые содержат указатели, соответствующие связи L.
Заметим, что для обоих рассмотренных выше представлений связей
предполагалось, что не была предварительно связана с какой-либо за-
писью типа Т2. Если это предположение ошибочно, необходимо сначала найти
Ri в файле для 7\. При использовании мультисписковой стратегии удаление
Ri из любой цепи связи L, в которую входит эта запись, не составляет тру-
да. В случае представления L с помощью записей переменной длины проб-
лема не настолько проста. Может не оказаться удобного способа, позво-
ляющего достигнуть из /?1 записи Rs типа Т2, с которой R± связана в дан-
ный момент. К счастью, для каждого из представлений записей переменной
длины существует простой метод, позволяющий из RT достигнуть R3. На-
пример, если записи типа Т2 имеют указатели на цепь блоков, содержащих
ассоциированные с ними записи типа 7\, мы можем закончить цепь указа-
телем назад на запись типа Т2, к которой относится цепь.
Запросы в сетях
Для ответов на простейшие запросы в базе данных, представленной се-
тевой моделью, используются лишь атрибуты одного типа записи. Напри-
мер, обращаясь к базе данных нз примера 3.5, мы можем ответить на вопрос
86
«Когда день рождения Раса?». Для этого следует в файле для типа записи
ИГРОКИ произвести поиск записи со значением атрибута ИМЯ «Джордж
Рас». Такой поиск может быть выполнен эффективно, поскольку ИМЯ —
ключ рассматриваемого типа записи. Если же заданные в запросе значения
атрибутов не образуют ключ, то необходимы вторичные индексы для этого
файла, по крайней мере, по некоторым из заданных атрибутов. В против-
ном случае поиск должен осуществляться по всему файлу.
Далее в порядке трудности идут запросы, требующие следования по
связи. Так, можно задать значение ключа для записи типа Тг и попросить
найти запись или записи типа Т1г с которыми она ассоциирована связью L
от типа записи 7\ к типу записи Тг. Обращаясь снова к примеру 3.5, мы за-
даем вопрос: «Имел ли Робинсон когда-либо бейтинг, больший 0,340?». На-
ходим запись типа ИГРОКИ для Робинсона, которая обеспечивает доступ
к списку записей ИКС для Робинсона путем следования по связи ИКС-
ИГРОКИ. Просматривая эти записи, выбираем те из них, для которых
ЗНАЧЕНИЕ-БЕЙТИНГА выше 0,340. При этом будет найдена запись со
значением 0,342.
Возможны также и запросы другого рода. Например, при заданном зна-
чении ключа для записи типа Тг необходимо найти единственную запись
типа Т2, ассоциированную с нею связью £ от 7\ к Т2. Если L представляет-
ся с помощью мультисписка, это — легкая задача. Для поиска требуемой
записи следуем по цепи для L, в которую входит /?, до тех пор, пока не при-
дем к записи типа Т2. Если же L представляется записями переменной дли-
ны, то мы должны располагать указателем, позволяющим из списка /? до-
стигнуть начала записи переменной длины, частью которой он является,
что уже обсуждалось в связи с удалением связей. При наличии указателя
никакой проблемы нет. В противном случае для обнаружения записи, с ко-
торой ассоциирована R, нужно просматривать весь файл записей типа Т2.
Наиболее трудными для обработки являются запросы, требующие сле-
дования по двум или более связям. Допустим, например, что у нас возник
вопрос: «Какие игроки центрального поля имели бейтинг более 0,400?».
Здесь можно начать с поиска записи типа ПОЗИЦИИ для «Центрального
поля». Это легко сделать, поскольку НАЗВАНИЕ-ПОЗИЦИИ — ключ
для данного типа записи. Далее проверяем все записи ИП, связанные с
«Центральным полем» связью ИП-ПОЗИЦИИ, после чего следуем по связи
ИП.ИГРОКИ и для каждой записи ИП получаем единственную запись
ИГРОКИ. Наконец, для всех найденных записей ИГРОКИ проверяем запи-
си ИКС, ассоциированные с ними связью ИКС-ИГРОКИ. Если одна или
более записей ИКС для рассматриваемого игрока имеют ЗНАЧЕНИЕ.
БЕЙТИНГА выше 0,400, печатаем его имя.
3.3. ИЕРАРХИЧЕСКАЯ МОДЕЛЬ ДАННЫХ
Иерархия — это сеть, являющаяся лесом (совокупностью деревьев),
в котором все связи направлены от сына к отцу. Обсуждая иерархии, мы
будем пользоваться сетевой терминологией: «тип логической записи»
и т. д. Однако полезно при этом ввести дополнительное понятие — тип вир-
туальной логической записи. Такая запись представляет собой указатель
на логическую запись некоторого типа. Типы виртуальных записей необхо-
димы в ситуациях, когда интуитивно мы хотели бы поместить какой-либо
тип записи в два или более дерева иерархии или даже в несколько мест в
одном дереве. Но в этом случае у нас оказалось бы несколько копий записи
в базе данных. Поступая таким образом, мы нерационально использовали
87
бы память и открыли бы возможности для изменения одной копии без из-
менения другой. Следовательно, будем предполагать, что каждый тип ло-
гической записи появляется в иерархии в одном месте. В других местах,
где требуется данный тип записи, вместо него задаются виртуальные записи.
С помощью типов виртуальных записей можно преобразовать любую
сеть в иерархию. Начнем с какого-либо типа логической записи /?, который
рассматривается как корень первого дерева. Если это возможно, выбираем
а) б] S)
Рис. 3.9. Иерархическое представление бейсбольной базы
данных
R так, чтобы не было оставшихся связей. Сыновьями R становятся любые
типы записей со связями, входящими в R. Их сыновья могут быть найдены
при следовании по связям в обратном направлении (от «головы» к «хвосту»)
и т. д. Если однако, встречается некоторый тип записи, уже включенный
ранее в иерархию, мы создаем тип виртуальной записи, помещаем его в
иерархию вместо встретившегося логического типа и не добавляем каких-
Сынабья типа ИП Сынобья типа ИНС
для Кобба для Кобба
Рис. 3.10. Часть базы данных в форме дерева
либо сыновей виртуального типа. В том случае, когда невозможно добавить
больше никаких сыновей к конструируемому дереву, ищем тип логической
записи, еще не помещенный в иерархию. Если его найти не удается, то про-
цесс считается законченным. При обнаружении такого типа повторяем про-
цесс конструирования дерева, начиная с одного из типов логической запи-
си, ранее не помещенного в иерархию.
Пример 3.7. Преобразуем в иерархию сеть, представленную на рис. 3.5.
Начнем с типа записи ИГРОКИ, который имеет дуги, входящие из ИП и ИКС. По-
88
следние два типа записи не имеют входящих дуг. Поэтому создание первого дерева
завершено. Оно имеет корень ИГРОКИ н сыновей ИП н ИКС. Второе дерево можно
начать конструировать с типа записи КОМАНДЫ. Существует одна входящая
дуга из типа записи ИКС, который уже был помещен в иерархию. Поэтому за-
даем в качестве сына для типа КОМАНДЫ тип виртуальных записей «указатель
на ИКС» и переходим к третьему дереву. Оно состоит из корня ПОЗИЦИИ
с типом виртуальной записи ИП в качестве сына. Полная иерархия показана на рис.
3.9. Заметим, что такая иерархия является плохим способом представления бейсбольной
базы данных, поскольку те виды запросов, которые легко формулируются в базирую-
щихся на иерархии языках манипулирования данными, не включают некоторых
естественных запросов. Позднее мы поясним это замечание и покажем лучшее иерар-
хическое представление.
Пример базы данных, описанный тремя типами логических записей, может рас-
сматриваться как лес. Для любого типа логической записи в иерархии база данных
будет иметь нуль или более узлов, представляющих некоторые записи данного типа.
Иногда удобно изображать каждое дерево в базе данных с фиктивным корнем, сыновья-
ми которого являются экземпляры записей корневого типа. Таким образом, например,
на рнс. 3.10 показана часть дерева базы данных, приведенного на рис. 3.9, а. Числа от
1 до 5 являются порядковыми номерами, которые идентифицируют записи ИП и
ИКС. В реализации такие порядковые номера исчезают.И
Непосредственное представление в иерархии связей
«многие ко многим»
Иерархии, спроектированные непосредственно из сети, иногда оказы-
ваются неудобными для обработки запросов. Рассмотрим иерархию на
рис. 3.9 и предположим, что нужно выяснить, в какой позиции играл Кобб.
Мы вынуждены начинать с корня на рис. 3.10 и искать запись ИГРОКИ
для Кобба. В таком поиске могла бы помочь подходящая организация фай-
ла записей ИГРОКИ. Допустим поэтому, что удалось легко найти требуе-
мую запись. Просматриваем тех сыновей этой записи, которые имеют тип
ИП. Пусть рассматривается запись с порядковым номером 1. Тогда необхо-
димо перейти к базе данных, соответствующей дереву на рис. 3.9, в, и иссле-
довать все записи ПОЗИЦИИ. Для каждой такой записи мы рассматрива-
ем ее сыновей, которые являются виртуальными записями ИП, т. е. указа-
телями на записи ИП в базе данных для дерева на рис. 3.9, а. Если найдена
некоторая виртуальная запись ИП для какой-либо позиции, указывающая
на запись ИП с порядковым номером 1, то отсюда следует, что Кобб играл
в этой позиции.
Возникает вопрос: почему намного легче ответить на данный запрос в
сети на рис. 3.5, чем в иерархии на рис. 3.9? Причина заключается в том, что
связи в сети являются, по существу, двунаправленными, и на рис. 3.5 име-
ется возможность непосредственно перейти от записи ИП к записи ПОЗИ-
ЦИИ. Однако приведенный выше алгоритм преобразования сети в иерархию
разрушает связь типа ИП с типом ПОЗИЦИИ, хотя связь типа ПОЗИЦИИ
с типом ИП существует благодаря указателям в виртуальных записях ИП.
Связям свойственна тенденция к разрушению при переходе от сети к иерар-
хии, несмотря на то, что они могут поддерживаться путем введения допол-
нительных полей указателей в типах логических записей в иерархии.
Другая проблема, связанная с плохо спроектированной иерархией,
заключается в том, что в отличие от базы данных, построенной на основе
сетевой модели данных, где навигация может осуществляться полностью
внутри нее, в иерархии мы должны иногда переходить от одного дерева
к другому. Это можно выполнить лишь путем чтения некоторого значения
из базы данных в рабочее пространство прикладной программы (например,
порядкового номера в примере 3.7) и использования этого значения для до-
ступа к информации в другом дереве.
89
Таким образом, нужно постоянно проявлять осторожность при проек-
тировании иерархии с тем, чтобы значения были доступны там, где они тре-
буются. Может оказаться полезной следующая идея. Предположим, что
имеются наборы объектов Ег и £2 со связью R «многие ко многим» между
ними. Мы можем представить R в иерархии, выбирая либо Ег, либо Е2 (до-
пустим, £]) в качестве корня дерева. Принимаем в качестве сына корня тип
логической записи Т, состоящий из:
1) порядкового номера, позволяющего идентифицировать записи, и
2) атрибутов, образующих ключ для £2.
Как и в сетях, порядковый номер может быть исключен в реализации
благодаря тому, что он фактически заменяется адресом записи. Нежела-
тельно помещать все атрибуты £2 в формат типа записи Т, поскольку тогда
возникла бы задача обеспечения тождественности информации в нескольких
записях £2, представляющих один и тот же объект. Вместо этого мы созда-
ем другой тип логической записи со всеми атрибутами £2. Данный тип запи-
си будет помещен где-либо в иерархии, например в корне его собственного
дерева, если не может быть найдено какое-либо более удобное место.
В некоторых приложениях необходимо лишь найти объекты £2, ассо-
циированные с заданным объектом £г, и для этого рассмотренная выше ор-
ганизация является идеальной. В других случаях, однако, важно удобным
образом находить объекты £1( ассоциированные с £2.Тогда мы можем вклю-
чить в качестве сына типа записи £2 новый тип записи, состоящий из клю-
чевых полей £г.
Альтернативный подход состоит в том, чтобы заменить типы записей,
состоящие из ключей для £t и (или) £2, указателями на записи £\ или £.2
соответственно. Такая организация приводит к закреплению записей, на
которые ссылаются указатели, но предоставляет прямой доступ к этим
записям. Для сравнения отметим, что использование значений ключа для
идентификации записей требует поиска нужной записи. В гл. 8 разбирается
детальный пример, показывающий, как известная иерархическая СУБД об-
легчает реализацию и практическое использование связей «многие ко мно-
гим».
Пример 3. 8. Перепроектируем иерархию для бейсбольной базы данных.
Напомним, что первоначальное определение схемы этой базы данных — диаграмма
объектов-связей, представленная иа рис. 3.3. Связь ИГРЫ можно выразить деревом,
корнем которого является тип логической записи ИГРОКИ:
(ИМЯ, РОДИНА, ДАТА-РОЖД),
У корня есть сын — тип логической записи
(ПОРЯДКОВЫЙ_НОМЕР_1, НАЗВАНИЕ-ПОЗИЦИИ),
представляющий названия позиций, в которых играет каждый игрок. Атрибут ПОРЯД-
КОВЫЙ_НОМЕР_1 — это порядковый номер, используемый для идентификации
записей. Он, вероятно, исчезнет в реализации, поскольку может быть представлен
адресом записи.
Для представления ассоциации между названиями позиции и их номерами сущест-
вует второе дерево, содержащее только корневой тип логической записи:
(НАЗВАНИЕ_ПСЗИЦИИ, НОМЕР_ПОЗИЦИИ)
Мы могли бы использовать атрибуты набора объектов КОМАНДЫ и сформиро-
вать корень третьего дерева, но, поскольку проектируется иерархия, ие следует за-
бывать о том, что существует иерархическая структура для набора команд. Выберем
в качестве корня третьего дерева тип логической записи, состоящий только из атрибута
СПОРТКЛУБ. Спортклуб можно рассматривать как множество команд, существо-
90
вавших по одной в каждом году. Поэтому корень третьего дерева имеет одного сына —
тнп логической записи.
(ПОРЯ Д КОВ ЫЙ_НОМЕР_2, ГОД)
В самой базе данных каждая запись указанного типа представляет некоторую
команду, которая определяется значением ГОД и значением СПОРТКЛУБ в записи,
являющейся отцом данной. Кроме того, ПОРЯДКОВЫЙ- НОМЕР- 2 фиктивный.
Он служит для того, чтобы различать записи этого типа, поскольку могут существо-
вать два спортклуба в данном городе в заданном году.
Указанный тип логической записи имеет сына — тип логической записи, пред-
ставляющий игроков команд и средний бейтинг каждого игрока в данном году, формат
которого
(ПОРЯДКОВЫЙ_НОМЕР_3, ИМЯ, ЗНАЧЕНИЕ-БЕЙТИНГА)
Можно предположить, что подобно другим порядковым номерам ПОРЯДКО-
ВЫЙ_НОМЕР_3 исчезнет в реализации. Присутствие его в схеме концептуальной
базы данных предотвращает возможность идентификации записей одними и теми же
значениями полей ИМЯ и ЗНАЧЕНИЕ-БЕЙТИНГА, если они представляют средний
бейтинг игрока за два различных сезона. Полная иерархия показана на рис. 3.11.
В этой иерархии мы можем ответить на вопрос «В каких позициях играл Кобб?»,
найдя запись Кобба в файле для корневого типа записи в дереве рис. 3.11, а и рассмот-
рев ее сыновей. Каждый из них содержит название позиции, в которой играл Кобб.
Можно даже найти номера этих позиций, если действовать указанным способом, а за-
тем выполнить поиск записи для каждой позиции в дереве рис. 3.11, б.
Рис. 3.11. Улучшенная иерархия для бейсбольной базы данных
Реализация иерархических баз данных
Идеи, на которых основана реализация сетевой базы данных, примени-
мы и к иерархической модели, поскольку иерархии являются специальными
случаями сетей. Представление с помощью файлов с записями переменной
длины особенно подходит для иерархий. Чтобы сконструировать формат
записи переменной длины для дерева, воспользуемся следующими двумя
правилами:
1. Формат для листа дерева есть (а)*, где а представляет собой список
атрибутов в формате логической записи, соответствующей данному листу.
2. Если некоторый узел имеет k сыновей с форматами записей перемен-
ной длины ах, а2, ..., aft и список атрибутов в формате логической записи
для этого узла есть 0, то формат соответствующей ему записи переменной
длины имеет вид
(Pa^ ...aft)*.
91
Учитывая приведенные выше правила, сконструируем файл с запися-
ми переменней длины для каждого дерева в иерархии. Каждый такой файл
должен быть, конечно, реализован, как обсуждалось в разд. 2.6, с помощью
одного или более файлов с записями фиксированной длины.
Пример 3.9. Формат записи переменной длины для дерева, приведенного
на рис. 3.11, в, имеет вид
(СПОРТКЛУБ (ПОРЯДКОВЫЙ_НОМЕР_2 ГОРОД ГОД (ПОРЯДКО-
ВЫЙ-НОМЕР-З ИМЯ ЗНАЧЕНИЕ-БЕЙТИНГА)*)*)*,
а для дерева на рнс. 3.9, а — вид
(ИМЯ РОДИНА ДАТА-РОЖД (ПОРЯДКОВЫЙ-НОМЕР-^(ПОРЯДКО-
ВЫЙ НОМЕР 2 ЗНАЧЕНИЕ_БЕЙТИНГА)*)*
Другой возможный вариант реализации иерархии заключается в том,
чтобы перечислить записи каждого дерева в порядке сверху вниз, как это
предлагалось в разд. 2.6 для полей формата записи переменной длины.
Обход дерева сверху вниз, или перечисление дерева, определяется рекур-
сивно следующим образом:
1) перечислить корень;
2) для каждого сына с корня, начиная слева, выполнить
перечислить сверху вниз поддерево с корнем с.
Пример 3.10. Предположим, что мы имеем дерево, изображенное на рис. 3.12.
Чтобы перечислить его сверху вниз, нужно перечислить сначала корень А, а затем
сверху вниз дерево, состоящее из вершин В, D н Е. С этой целью мы перечисляем В,
а затем дерево, состоящее из одной вершины Е. Таким образом, первыми четырьмя
узлами дерева в порядке сверху вниз являются ABDE. В заключение следует перечис-
лить дерево, корнем которого является С. В результате получаем ABDECF.J^
При перечислении сверху вниз дерева записей в базе данных, нужно
идентифицировать каждую запись в ее начале некоторыми битами, которые
указывают тип логической записи. Это позволяет нам найти и интерпрети-
ровать значения полей в записи. Удобно также в каждом блоке, где нахо-
дятся записи, сделать доступной информацию о том, в каком месте начинается
каждая из них, поскольку мы не знаем априори типы записей или их дли-
ны. Как будет показано в разд. 8.4, полезно, кроме того, снабдить этот спи-
сок указателями различного рода, чтобы обеспечить легкий доступ к сосед-
ним узлам.
Пример 3.11. Рис. 3.12 можно рассматривать как концептуальную схему,
описанную в терминах иерархической модели, где А, В, ... представляют типы логи-
ческих записей. На рис. 3.13 приведена одна из возможных баз данных, описанных
схемой рис. 3.12. Каждую из записей, представленных некоторым узлом на рис. 3.13,
92
можно следующим образом перечислить в порядке сверху вниз, используя для этого
необходимое число блоков:
ai b^d^d^d 1/2е J за2 adae^c Jtfbfectfi •
Отметим, что приведенная строка является сконструированным по рис. 3.12 экземпля-
ром записи переменной длины, имеющей формат
(Л (В (D)* (£)*)* (С (Е)*)*)*-И
ФинтиЪный корень
(не перечисляется)
Рис. 3.13. База данных древовидной структуры
3.4. СРАВНЕНИЕ МОДЕЛЕЙ
Чтобы оценить все три рассмотренные выше модели, мы должны преж-
де всего установить критерии, по которым они могут сравниваться. Глав-
ными из этих критериев являются следующие:
1. Легкость использования. Основную часть издержек, особенно в не-
больших базах данных, содержащих порядка нескольких тысяч или десятков
тысяч записей, может составлять время, затрачиваемое программистом на
разработку прикладных программ и пользователем на формулировку за-
просов. Нам нужна модель данных, которая позволяет тщательно програм-
мировать и легко формулировать запросы.
2. Эффективность реализации. Для больших баз данных стоимость
пространства памяти и машинного времени доминирует в общих издержках
реализации базы данных. Нам нужна модель, в которой СУБД может лег-
ко переводить спецификации концептуальной схемы и отображения «концеп-
туальный—физический» в реализацию, эффективную с точки зрения необ-
ходимого пространства и обработки запросов.
Несомненно, что по критерию легкости использования лучшей являет-
ся реляционная модель. Она оперирует только с одной конструкцией, ко-
торую должен понимать программист или конечный пользователь. Более
того, как будет показано позднее, существуют развитые языки высокого
уровня, позволяющие формулировать запросы на данные, представленные
средствами реляционной модели. Благодаря этому системы, основанные на
реляционной модели, доступны тем, кто не обладает большим опытом про-
граммирования.
Сетевая модель требует понимания не только типов записей и связей,
но и их взаимоотношений. Реализация связей «многие ко многим» и связей
над тремя и более наборами объектов осуществляется непросто, хотя с при-
93
обретением опыта для этого могут быть использованы рассмотренные в
разд. 3.2 методы, основанные на введении типов фиктивных записей. По-
добным образом иерархическая модель требует понимания использования
указателей (типов виртуальных записей) и порождает те же проблемы, что
и сетевая, — относительно представления связей более сложных, чем свя-
зи «многие к одному» между двумя наборами объектов.
При рассмотрении возможностей эффективной реализации высокие
оценки получают сетевая и иерархическая модели. В разд. 3.2 было пока-
зано, как реализации записей переменной длины могут упростить задачу
следования по связям. Упоминалось также и о том, что структуры данных,
такие, как мультисписки, и реализация записей переменной длины, осно-
ванная на указателях, не поддаются легкому обобщению на случай отобра-
жений «многие ко многим». Поскольку отношения часто представляют отоб-
Рис. 3.14. Иерархия и база данных
ражения «многие ко многим», эффективная реализация отношений оказы-
вается более трудной, чем в случае сетей или иерархий. К счастью, для реа-
лизации отношений также можно использовать некоторые специализиро-
ванные структуры данных.В разд. 4.5 мы обсудим, каким образом мульти-
списки и другие идеи применялись для реализации отношений в одной из
существующих систем.
Эффективное использование памяти иногда легче обеспечить для иерар-
хий (или сетей в форме иерархий), чем для отношений. В качестве иллюст-
рации рассмотрим иерархию на рис. 3.14, а и пример базы данных на
рис. 3.14, б. Если бы потребовалось представить ту же самую структуру в
виде отношений, мы выбрали бы, вероятно, одно отношение с атрибутами
А и В, другое — с атрибутами Л и С, а третье — с атрибутами С и D. Соот-
ветстсвующие отношения показаны на рис. 3.15. Можно заметить, что аг, сг
и с2 повторяются по несколько раз, следствием чего является нерациональ-
ное использование пространства по сравнению с рис. 3.14, б.
Указанный выше эффект не был бы столь важным, если бы не то обстоя-
тельство, что данные часто образуют естественную иерархию. Хотя мы и
вправе реализовать отношения с помощью иерархической структуры, по-
добная, которой приведена на рис. 3.14, б, но не всегда будет
А В А С С D
at bt at dt
а1 b2 at Рис. 3.15. Отнс с2 мнения С1 с2 с2 ft. ft. Й- * w
94
ясно, однако, как это сделать. В качестве примера читателю предлагается
рассмотреть, какой вид имела бы иерархия, соответствующая рис. 3.15,
если бы в качестве корня концептуальной схемы был выбран атрибут С, а
не А.
Уровень языка
Уровень языка манипулирования данными может оказывать сущест-
венное влияние на легкость использования СУБД. Проводя аналогию,
вспомним, например, что программировать на Фортране легче, чем на язы-
ке Ассемблера, а на АПЛ—легче, чем на Фортране. Дело в том, что в реля-
ционных СУБД акцент сделан на языки очень высокого уровня, тогда как
СУБД, базирующиеся на других моделях, имеют тенденцию к применению
языков более низкого уровня. В гл. 4 мы рассмотрим некоторые реляцион-
ные языки высокого уровня, а в гл. 7 и 8 — два основных языка низкого
уровня, в которых детали навигации выражены в терминах сетевой и иерар-
хической моделей.
У читателя может возникнуть вопрос: существуют ли какие-либо вес-
кие аргументы в пользу того, что эти примеры являются типичными? Дока-
зать, что такие аргументы существуют, трудно, хотя, как известно, каждый
из языков общего назначения очень высокого уровня—АПЛ, Снобол, Лисп
или Сетл — основан на единственном типе данных (соответственно массив,
строка, списковая структура и множество). Точно так же реляционная мо-
дель обеспечивает лишь единственный тип данных — отношение. В проти-
воположность этому языки низкого уровня, подобные ПЛ/1, предоставляют
в распоряжение программиста различные типы данных.
Заключение
В прошлом коммерческие системы баз данных почти исключительно
основывались на сетевой или иерархической моделях, поскольку в таких
системах придавалось особое значение поддержке больших баз данных. Эти
модели наиболее легко поддаются эффективной реализации. Мы полагаем
однако, что в будущем основное внимание привлечет к себе реляционная мо-
дель. Во-первых становится ясно, что концепции, используемые для про-
ектирования больших баз данных, применимы также к малым и средним
базам данных, и существует намного больше малых баз данных (т. е. содер-
жащих тысячи, а не миллионы записей), чем больших. В случае малых баз
данных легкость использования, присущая реляционной модели, приобре-
тает первостепенную важность.
Во-вторых, могут быть устранены многие из очевидных аспектов неэф-
фективности реляционной модели. В гл. 6 приводятся некоторые методы
оптимизации для реляционных языков манипулирования данными, позво-
ляющие эффективно использовать время. Кроме того, проводятся исследо-
вания по разработке хороших физических реализаций отношений. Мы об-
судим некоторые достижения, связанные с СУБД System R фирмы ИБМ в
разд. 4.5. В разд. 4.7 описывается коммерческая система Query-by-Examp-
1е, подходящая для средних баз данных. Как известно, языки общего на-
значения очень высокого уровня, подобные АПЛ, подвергаются преобразо-
ваниям по мере решения связанных с ними сложных проблем оптимизации.
Мы предполагаем, что точно так же и реляционная модель будет становить-
ся более привлекательной по мере решения связанных с нею проблем опти-
мизации.
95
УПРАЖНЕНИЯ
3.1. На рис. 3.16 представлена диаграмма объектов-связей страховой компании.
Ключами наборов объектов СЛУЖАЩИЕ и ПОЛИСЫ (страховые полисы) являются
СЛУЖ# (номер служащего) и П-# (номер полиса) соответственно. Объекты ПРОДА-
ВЕЦ идентифицируются их связью есть с объектами СЛУЖАЩИЕ. Представьте эту
диаграмму в следующих моделях: а) реляционной, б) сетевой, в) иерархической.
Рис. 3.16. База данных страховой компании
3.2. На рис. 3.17 показана генеалогическая база данных с ключевыми атрибута-
ми ИМЯ и ЛИЦЕНЗИЯ-#' (номер брачной лицензии — разрешения на брак). Пред-
ставьте эту диаграмму в следующих моделях: а) реляционной, б) сетевой и в) иерархи-
ческой.
З.З1. Рецепт для приготовления «гоголя-моголя» включает яйца, молоко, сахар,
соль и ванилин. Омлет приготовляется из яиц, молока и масла. Наконец, песочное
печенье делается из муки, масла, смета-
ны, сахара и ванилина.
а) Допустим, что мы желаем хра-
нить эту информацию в отношении РЕ-
ЦЕПТ с атрибутами БЛЮДО и ИН-
ГРЕДИЕНТ, имеющем схему
РЕЦЕПТ (БЛЮДО, ИНГРЕДИЕНТ)
Покажите текущее значение этого
отношения в виде таблицы (используя
подходящие аббревиатуры для блюд и
ингредиентов).
б) Предположим, что нам требует-
ся представить приведенную выше ин-
формацию как сеть с типами записей
БЛЮДО, ИНГРЕДИЕНТ и ФИКТИВ-
НАЯ, где запись ФИКТИВНАЯ пред-
ставляет пару, состоящую нз одного
ингредиента и одного блюда. Предполо-
жим также, что существуют связи ИС-
ПОЛЬЗУЕТ от типа записи ФИКТИВ-
НАЯ к типу записи БЛЮДО и ЯВЛЯЕТСЯ-ЧАСТЬЮ— от типа записи ФИКТИВ-
НАЯ к типу записи ИНГРЕДИЕНТ. Изобразите экземпляры записей БЛЮДО,
ИНГРЕДИЕНТ и ФИКТИВНАЯ и представьте связи ИСПОЛЬЗУЕТ и ЯВЛЯЕТСЯ-
ЧАСТЬЮ с помощью мультисписковой структуры. 1
1 Упражение изменено при переводе. — Примеч. ред.
96
в) Выполните п. (б), представив связь ИСПОЛЬЗУЕТ записями переменной дли-
ны с форматом БЛЮДО (ФИКТИВНАЯ)*. Представьте ЯВЛЯЕТСЯ_ЧАСТЬЮ
мультиписковой структурой.
г) Допустим, что иерархия на рис. 3.18 используется в качестве концептуальной
схемы для рассматриваемой информации. Покажите актуальную базу данных, вклю-
чив указатели в виртуальные записи.
Рис. 3.18. Иерархия
* 3.4.1 Хотя в системах баз данных, вообще говоря, имеются их собственные
специализированные языки манипулирования данными, мы можем прочувствовать,
как наши три модели облегчают спецификацию запросов к базе данных, если восполь-
зуемся общепринятым языком, подобным ПЛ/12, для создания базы данных и формули-
ровки запросов.
а) Напишите декларации структур записей ПЛ/1 для отношений из упражиеиня
3.3 (а).
б) Напишите программу на языке ПЛ/1, печатающую все блюда, для приготовле-
ния которых требуется молоко, используя структуру из п. (а).
в) Напишите структуры записей ПЛ/1, представляющие типы записей из упраж-
нения 3.3 (б). Включите поля для указателей, необходимые для представления муль-
тисписковой структуры. v
г) Напишите программу на языке ПЛ/1, которая печатает все блюда, использую-
щие молоко. Начните с нахождения записи для этого ингредиента и осуществите поиск
с помощью связи ЯВЛЯЕТСЯ_ЧАСТЬЮ.
д) Напишите структуры записей для иерархии иа рис. 3.18 и найдите способ пред-
ставления сыновей записей БЛЮДО и ИНГРЕДИЕНТ, например, путем создания
связанных списков виртуальных записей ИНГРЕДИЕНТ и БЛЮДО.
е) Напишите программу, печатающую все блюда, для приготовления которых
нужно молоко, используя структуру из п. (д).
* 3.5. В разд. 3.1 мы упоминали, что две таблицы представляют одно и то же от-
ношение, если одна нз них может быть преобразована в другую перестановкой строк
и (или) столбцов, при которой атрибуты, озаглавливающие столбцы, переставляются
вместе со столбцами. Сколько таблиц представляют это отношение, если оно имеет схе-
му с т атрибутами и содержит п кортежей?
Библиографические замечания
Читатель увидит в библиографии к гл. 4, 7 и 8 ссылки на ряд систем, которые ис-
пользуют реляционную, сетевую или иерархическую модель. Ранее, в гл. 1, мы упомина-
ли о других моделях для концептуальной схемы. Это, вообще говоря, модели несколько
более высокого уровня, чем рассмотренные в данной главе. Оии служат главным обра-
зом инструментом проектирования баз данных и отображаются в одну из описанных
здесь моделей данных.
Из этих трех моделей только реляционная имеет в своей основе теоретические пред-
ложения, предопределяющие любые правильные реализации. Концепции модели связы-
вают с серией статей Кодда [41, 42, 43], хотя Кодд [42] высказал признательность не-
которым более ранним работам Чайлдса [36]. Несколько работ посвящено сравиеиню
трех моделей. Из них мы отметим краткое руководство Растииа [145] и выпуск Computer
Surveys [153] под редакцией Сибли.
1 Упражеииие изменено при переводе. — Примеч. ред.
4 Для этой цели пригоден любой язык со структурами записей, такой, как Паскаль
ели «С>.
4 Зак. 1315
97
ГЛАВА 4
ЯЗЫКИ МАНИПУЛИРОВАНИЯ ДАННЫМИ
ДЛЯ РЕЛЯЦИОННОЙ МОДЕЛИ
В настоящей главе обсуждаются три основных подхода к конструиро-
ванию языков для формирования запросов в терминах отношений. Нотация
для формулирования запросов является обычно наиболее важной частью
языка манипулирования данными. Остальные функции реляционного язы-
ка манипулирования данными или «языка запросов» достаточно просты и
связаны с включением, удалением и модификацией кортежей. С другой
стороны, для формулирования запросов, которые в самом общем случае
представляют собой произвольные функции над отношениями, часто
используют развитые языки высокого уровня.
Языки запросов для реляционной модели разбиваются на два класса:
1. Алгебраические языки, позволяющие выражать запросы средства-
ми специализированных операторов, применяемых к отношениям.
2. Языки исчисления предикатов, где запросы описывают требуемое
множество кортежей путем спецификации предиката, которому должны
удовлетворять эти кортежи.
В дальнейшем будет показано, что языки, основанные на исчислении,
в свою очередь, делятся на два класса в зависимости от того, являются ли
примитивные объекты кортежами или элементами домена некоторого атри-
бута. Таким образом, существует три различных вида языков запросов.
В начале главы мы познакомимся с реляционной алгеброй и с двумя
формами реляционного исчисления: реляционным исчислением с перемен-
ными-кортежами и реляционным исчислением с переменными на доменах.
Эти абстрактные языки запросов в описанном виде не реализованы в какой-
либо действующей СУБД, но они служат эталоном для оценки существую-
щих систем. Иными словами, каждый из трех указанных абстрактных язы-
ков запросов эквивалентен по своей выразительности двум другим. Они бы-
ли предложены Коддом [43] для представления минимальных возможностей
любого разумного языка запросов, использующего реляционную модель.
Реальные языки запросов обычнцобеспечивают не только функции абстракт-
ных языков, но н некоторые дополнительные потребности пользователей.
Далее мы обсудим типичные языки запросов каждого из трех видов: алгеб-
раический язык ISBL, язык исчисления с переменными-кортежами QUEL
и язык исчисления с переменными на доменах Query-by-ExampIe. Мы рас-
смотрим также язык SQUARE и его «двоюродного брата» SEQUEL, кото-
вые являются промежуточными между алгеброй и исчислением.
4.1. РЕЛЯЦИОННАЯ АЛГЕБРА
Напомним, что отношение — это множество кортежей длины k для не-
которого фиксированного k, называемого арностью отношения. Иногда пред-
ставляется удобным присвоить имена компонентам кортежей, называемым
98
атрибутами, хотя в других случаях целесообразно считать компоненты не-
именованными и обращаться к ним по номерам. При определении реля-
ционной алгебры предполагается, что столбцы не обязательно должны быть
именованными и порядок в кортежах существен. Эта точка зрения отличает-
ся от изложенной в разд. 3.1, но не противоречит ей, если используются
очевидные преобразования. При обращении с отношениями как с базой дан-
ных предполагается, что все они конечны (в дальнейшем это особо не огова-
ривается). Требование конечности отношений порождает некоторые труд-
ности в определении реляционной алгебры и исчисления. Например, ал-
гебраическая операция дополнения недопустима поскольку—R обозначает
обычно бесконечное отношение — множество всех кортежей, не принадле-
жащих R. Какого-либо способа перечислить отношение —R не существу-
ет, даже если язык запросов допускает такое выражение.
Операндами реляционной алгебры являются постоянные и (или) пе-
ременные отношения, обозначающие отношения фиксированной арности.
Арность, ассоциированная с переменной, будет упоминаться далее только
в тех случаях, когда это существенно. Для определения реляционной ал-
гебры используется пять основных операций. После их представления мы
приведем несколько дополнительных операций, которые не расширяют
множества функций, выразимых в языке, однако обеспечивают краткость
записи.
1. Объединение. Объединение отношений R и X, обозначаемое как
R U X, представляет собой множество кортежей, которые принадлежат R
или X, либо им обоим. Оператор объединения применяется только к отно-
шениям одной и той же арности. Поэтому все кортежи в результате имеют
одинаковое число компонентов.
2. Разность. Разностью отношений R и S, обозначаемой как R — X,
называется множество кортежей, принадлежащих R, но не принадлежащих
X. Здесь снова требуется, чтобы R и S имели одну и ту же арность.
3. Декартово произведение. Пусть R и X — отношения арности и k.,
соответственно. Тогда декартовым произведением R X X отношений R и X
называется множество кортежей длины kY + k2, первые kY компонентов
которых образуют кортежи, принадлежащие R, а последние k2 — кортежи,
принадлежащие X.
4. Проекция. Существо этой операции заключается в том, что берется
отношение R, удаляются некоторые из его компонентов и (или) переупоря-
дочиваются оставшиеся компоненты. Пусть R — отношение арности k. Обо-
значим через лц, ц, ... im (R), где i} — являются различными целыми в диа-
пазоне от 1 до А, проекцию R на компоненты ilt i2, ..., im, т. е. множество
m-ок ага2 ...ат, таких, что существует некоторый принадлежащий R кортеж
i>ib2 ---bh длины k, удовлетворяющий условию: а} — для j = 1,2, ..., т.
Например, для построения (R) нужно из каждого кортежа t, принадле-
жащего R, сформировать кортеж длины 2 из третьего и первого его ком-
понентов в указанном порядке. Если у R имеются атрибуты, с помощью ко-
торых помечены его столбцы, то мы можем подставить имена этих атрибу-
тов1 вместо номеров компонентов и использовать те же имена в отношении,
полученном в результате проекции. Например, для отношения R со схемой
R (А, В, С, D) проекция лс,а (R) представляет собой то же самое, что и
пз,1 (R). В результирующем отношении атрибут С именует его первый
столбец, а атрибут А — второй.
1 Автор непоследователен в терминологии. В разд. 3.1 атрибутами названы имена
столбцов отношения. — Примеч. ред.
4’ 99
б. Селекция. Пусть F — формула, образованная:
а) операндами, являющимися константами или номерами компонентов;
б) арифметическими операторами сравнения
<, =,>, С, ¥=,
в) логическими операторами Д (и), V (или) и "П (нет.)
В этом случае Of (R) есть множество кортежей t, принадлежащих R,
таких, что при подстановке Z-го компонента t вместо любого вхождения но-
мера i в формулу F для всех i она станет истинной. Например, (R) обо-
значает множество кортежей, принадлежащих R, второй компонент которых
больше третьего компонента. В то же время Oi= smith v i = Jones (R) есть
множество кортежей, принадлежащих R, первый компонент которых
имеет значение Smith или Jones. Как и в проекции, формула в селекции мо-
жет ссылаться на столбцы по именам, а не по номерам, если столбцы отно-
шения именованы. Заметим также, что константы в формулах должны
быть заключены в кавычки. Это позволяет отличать их от номеров или имен
столбцов.
а) Отношение R
б) Отношение S
Рис. 4.1. Два отношения
а
с
с
d
Л | С А | В | С
а
d
с
с
d
г) пА. с (R)
Д)
Рис. 4.2. Результаты некоторых операций реляционной
алгебры
100
Пр и м е р 4.1. На рис. 4.1 приведены два отношения R и S, на рис. 4.2, а
и б — отношения R(J S и R — S соответственно. Заметим, что объединение и разность
можно выполнять, даже если столбцы двух отношений имеют различные имен*а, по-
скольку у этих отношений одно и то же число компонентов. При этом не существует,
однако, очевидных имен для столбцов результирующего отношения. На рис. 4.2, в
показано R X S. Поскольку множества атрибутов R и S не пересекаются, имена столб-
цов можно перенести в R X S. Если же для R и S имя столбца является общим, напри-
мер G, мы могли бы различать эти два столбца, называя их R.G и S.G. На рис. 4.2, е
показано пА с (R), а на рис. 4.2, в — ов_ь (R).
Некоторые дополнительные алгебраические операции
Существует ряд полезных операций, которые хотя и могут быть выра-
жены в терминах пяти ранее упоминавшихся, но в литературе имеют спе-
циальные названия. Они используются иногда как примитивные операции.
1. Пересечение. R П S есть краткая запись для R — (R — S).
2. Частное. Пусть R и 3 являются отношениями арности г и s соответ-
ственно, где r>s и 3 #= 0. Тогда R 4- 3 есть множество кортежей t
длины (г — $), таких, что для всех кортежей и длины s, принадлежащих 3,
кортеж tu принадлежит R. Выразим R 4-3, используя пять основных опера-
ций реляционной алгебры. Пусть Т обозначает л1>2.....r_e (R). Тогда
(Т X 3) — R есть множество кортежей длины г, не принадлежащих R.
Каждый из них формируется из г — s первых компонентов кортежа, при-
надлежащего R, за которыми следуют компоненты кортежа, принадлежаще-
го 3.
Пусть далее
У = Л1,а..r-,((T XS)-R).
Здесь V — множество кортежей t длины (г — s), состоящих из первых
г — s компонентов кортежей, принадлежащих R, причем для каждого из них
в 3 существует некоторый кортеж и длины s, такой, что tu не принадлежит
R. Следовательно, Т — V есть R4-3. Теперь можно записать /?4-3 как еди-
ное выражение в реляционной алгебре, заменив Т н V выражениями, кото-
рые они обозначают:
Я 4- 3 = Л1, r-s (/?) —Я1, 2 r-s ((«1, 2.r-s (R) X S) — R).
Пример 4.2. Пусть R и S — отношения, представленные на рис. 4.3, а
и 4.3, б. Соответствующее отношение R 4- S показано на рис. 4.3, в. Кортеж ab принад-
лежит R 4- S, поскольку abed и abef принадлежат R. По аналогичной причине кортеж
ed принадлежит R 4- S. Кортеж Ьс является единственным в первых двух столбцах
R не принадлежащим R 4- S, так как beed ие принадлежит R.
Рис. 4.3. Пример
d
f
Ь
d
а
е
с
е
б) Отноше-
ние S
в) Отноше-
ние R-rS
вычисления частного
и 3 по столбцам I и /, записываемое
3. Соединение. 0-соединение R i '. ‘
R £><]3, .где 0— арифметический оператор сравнения (=,<ит. д.), есть
101
краткая запись для oie{r+n (R х S), если R имеет арность г. Таким об-
разом, 0-соединение R и S представляет собой множество таких кортежей в
декартовом произведении R и S, что i-й компонент R находится в отношении
О с j-m компонентом S. Если 9 является оператором--, то эта операция час-
то называется эквисоединением.
Пример 4.3. Пусть R и S—отношения, представленные на рис. 4 4, а
и 4.4, б. Тогда /?£><]S приведено на рис. 4.4, в. Как и во всех алгебраических опера-
B<D
цнях, здесь можно использовать имена столбцов, если они имеются. Таким образом,
в этом случае £><] означает то же самое, что и £><].
B<D 2<1
4. Естественное соединение. Естественное соединение (обозначается
R[><]S) применимо лишь тогда, когда столбцы R и S именуются атрибута-
ми. Чтобы вычислить R£><]S, поступим следующим образом:
а) вычислим R X S;
б) для каждого атрибута А, который именует некоторый столбец в R
и какой-либо столбец в S, выберем те кортежи из R X S, у которых совпа-
дают значения в столбцах R.A и S.A. Напомним, что R.A есть имя столбца
R X S, соответствующего столбцу А из R. Аналогично определяется S.A;
в) для каждого указанного выше атрибута А удалим S.A. Формально,
если все Av А2, ..., Ak являются именами атрибутов, используемых и в R,
и в S, то R SecTbnG,r,.........im {or.a^s.a, л - л H-Ah^s.Ak(R X 5)), где
z2> •••, zm — упорядоченный список всех компонентов R X S, за исклю-
чением компонентов S.Av S.Ah.
А й С D Е А В С D Е
1 2 3 3 1 1 2 3 3 1
4 5 6 6 2 1 2 3 6 2
7 8 9 4 5 6 6 2
а) Отношение R б) Отноше-
ние S
в) Отношение Z?p><S
B<D
Рис. 4.4. Пример < — соединения
Пример 4.4. На рис. 4.5, а и б заданы отношения R и S. Соединение R > <] .$
обозначает в R с D (<b?.B=s.BAK.c=s.C (R х s))- Для конструирования
рассмотрим каждый принадлежащий R кортеж, с тем чтобы установить, какие кортежи
из 5 совпадают с ним в обоих столбцах В и С. Например, dbc в R совпадает с bed и Ьсе
в S. Поэтому abed н abce принадлежат R><]S. Подобным образомdbcдает кортежиdbed
и ЛЬсецля R> <] S. Кортеж bbfue совпадает ни с одним кортежем нз S в столбцах В и С,
в силу чего мы не имеем никаких кортежей в R><] S, которые бы начинались с bbf.
Наконец, cad соответствует adb, в результате чего получаем кортеж cadb.
а) Отношение R
в) Отношение R><S
Рис. 4.5. Пример естественного соединения
102
Важность естественного соединения нам станет ясной из следующей
главы, где рассматривается теория декомпозиции отношений.
4.2. РЕЛЯЦИОННОЕ ИСЧИСЛЕНИЕ
Прежде всего приведем определение реляционного исчисления с пере-
менными-кортежами. С этой целью представим сначала исчисление, которое
позволяет определять бесконечные отношения. Далее обсудим модификации,
обеспечивающие необходимые гарантии для того, чтобы каждая формула я
реляционном исчислении обозначала конечное отношение. Отметим, кста-
ти, что термин «реляционное исчисление» не подразумевает какой-либо свя-
зи с областью математического анализа, обычно называемой «дифферен-
циальным и интегральным исчислением».
Формулы в реляционном исчислении имеют вид {//ф (/)}, где t— пере-
менная-кортеж, т. е. переменная, обозначающая кортеж некоторой фик-
сированной длины1, а ф — формула, построенная из атомов и совокупности
операторов, которые определяются ниже.
Атомы формул ф могут быть трех типов:
1. R (s), где R — имя отношения, as — переменная-кортеж. Этот атом
означает, что s есть кортеж в отношении R.
2. s Ь’]0и I/J, где s и и являются переменными-кортежами, а 0— ариф-
метическим оператором сравнения «, = и т. д.). Этот атом означает, что
i-й компонент s находится в отношении 0 с /-м компонентом и. Например,
s [И < и [2] означает, что первый компонент s меньше, чем второй компонент
и.
3. s Ь’]0а и ads [Л, где 0 и s [Л имеют тот же смысл, что и в п. 2, а а -
константа. Первый из этих атомов означает, что i-й компоненте находится
в отношении 0 с константой а. Второй атом имеет аналогичный смысл. На-
пример, s [1] — 3 указывает, что значение первого компонента s равно 3.
При определении операторов реляционного исчисления полезно одно-
временно ввести понятия «свободных» и «связанных» переменных-кортежей.
Эти понятия имеют в точности тот же смысл, что и в исчислении предикатов.
(В дальнейшем для уяснения материала читателю не потребуются знания
в области исчисления предикатов.) Неформально вхождение переменной в
формулу является «связанным», если этой переменной предшествует кван-
тор «для всех» или «существует». В противном случае мы называем перемен-
ную «свободной».
Понятие свободной переменной аналогично понятию глобальной пере-
менной в языке программирования, т. е. переменной, определенной вне те-
кущей процедуры. Связанная переменная подобна локальной переменной --
переменной, которая определяется в данной процедуре. Фактически кван-
торы реляционного исчисления играют роль деклараций в языке програм-
мирования.
Формулы, а также свободные и связанные вхождения переменных-корте-
жей в эти формулы определяются рекурсивно следующим образом:
1. Каждый атом есть формула. Все вхождения переменных-кортежей,
упомянутые в атоме, являются свободными в этой формуле.
2. Еслиф! иф2 — формулы, тофх Д ф2,Ф1 V “Фа и ''К— также форму-
лы, утверждающие соответственно, что «фг и ф2 обе являются истинными»,
«Ф1 или ф2, либо обе истинны» и «фг не истинна». Экземпляры переменных-
кортежей являются свободными или связанными в фх Д ф2, ф1 V и 4’1
1 Символ #0 означает, что t имеет арность i.
103
точно так же, как они являются свободными или связанными в фх и ф2, в
зависимости от того, где они появляются. Заметим, что некоторое вхождение
переменной s может быть связанным в фх, в то время как другое — свобод-
ным, например, в ф2.
3. Если ф — формула, то (gs) (ф) — также формула. Символ g пред-
ставляет собой квантор. Его следует читать «существует». Другой исполь-
зуемый квантор V («для всех») описывается в п. 4. Вхождения переменной
s, свободные в формуле ф, являются связанными квантором (gs) в (gs) (ф)1 *.
Остальные вхождения переменных-кортежей в формуле ф, включая возмож-
ные вхождения s, связанные в ф, являются свободными или связанными в
(И s) (Ф) — такими, каким они были в ф. Формула (g s) (ф) утверждает, что
существует значение s, при подстановке которого вместо всех свободных
вхождений s в формулу ф эта формула становится истинной. Например,
(Я s) (Я (s)) означает, что отношение R не пусто, т. е. существует некоторый
кортеж s, принадлежащий /?.
4. Если ф — формула,, то и (V s) (ф) — тоже формула. Свободные вхож-
дения s в ф становятся связанными квантором (V s) в (V $) (ф). Другие
вхождения переменных в ф интерпретируются так же, как в п. 3. Формула
(ys) N5) утверждает, что, какое бы значение подходящей арности мы не под-
ставили вместо свободных вхождений s в ф, формула ф станет истинной.
5. Формулы могут при необходимости заключаться в скобки. Предпо-
лагается следующий порядок старшинства: арифметические операторы срав-
нения, кванторы g и V и, наконец, ~1, Д и у в перечисленном порядке.
6. Ничто иное не является формулой.
Выражение реляционного исчисления с переменными-кортежами есть
выражение вида {//ф (/)}, где t— единственная свободная переменная-кор-
теж в ф.
Пример 4.5. Объединение R и S выражается следующим образом в исчисле-
нии:
{t/R (f) V S(f)}.
Это означает: «множество кортежей/, таких, что t принадлежит R или I принадле-
жит S». Отметим, что объединение имеет смысл, только если R и S обладают одной и
той же арностью. Аналогично формула R (/) V S (/) имеет смысл при том же условии,
поскольку переменная-кортеж t предполагается фиксированной длины.
Разность R — S может быть представлена следующим выражением:
{t/R (t) Л-S (/)}.
Если R и S—отношения арности соответственно г и s, то R X Sb исчислении мож-
но записать в виде
{/(Г-Н) | (3U(D) (3U(S)) (7? (Ы) Д s (и) Л / [ 1 ] = «[ 1 ] Л... Д / [г] =
= «И Д /[г + 1] = v[1] Д...Д /[r + s] = u[s])}.
Как уже отмечалось, указывает, что t имеет арность i. Приведенное выражение
означает, что R X S есть множество кортежей t (рассматриваемых как кортежи длины
г + s), таких, что существует и, принадлежащее R, и v, принадлежащее S, причем г
первых компонентов t образуют и, а следующие з компонентов — v.
Проекция n(t {...t (R) выражается следующим образом:
{/<*> | (Н«) (R (и) д / [1] =и [ix] д.. .д/ [k]=u [/ft])}.
Селекция uF (R) может быть выражена в виде
{t/R (/) Л F’},
1 Если мы считаем свободную переменную s нз ф «глобальной» для ф, то (gs)
служит «декларацией» S.
104
где F' есть формула F, в которой каждый операнд i, обозначающий i-й компонент,
заменяется на t [ij.
И, наконец, если R есть отношение арности 2, то
{/(*) | (а«) (R (0 л я («) Л (/ [ 1] ф U [1] V t (2) =£ и [2]))}
представляет собой выражение исчисления, которое обозначает R, когда R имеет Два Или
более кортежа, и пустое отношение, когда R пусто или имеет лишь один кортеж.
Ограничение реляционного исчисления
для использования только конечных отношений
Реляционное исчисление с переменными-кортежами в том виде, в каком
мы его определили, позволяет представлять некоторые бесконечные отно-
шения. Например, {/| — R (/)} обозначает все возможные не принадлежащие
R кортежи, длина которых согласуется с I. Для того чтобы выражение
имело смысл, эта длина должна быть равна арности R. Поскольку мы не в
состоянии отпечатать «все возможные кортежи» (над каким доменом?), сле-
дует исключить такие бессмысленные выражения. Это достигается обычно
благодаря тому, что рассмотрение ограничивается так называемыми «безо-
пасными» выражениями {/|ф (/)}. Для подобных выражений можно проде-
монстрировать, что каждый компонент любого t, удовлетворяющего ф, дол-
жен быть элементом DOM (ф). Последнее определяется как множество сим-
волов, которые либо явно появляются в ф, либо служат компонентами како-
го-либо кортежа в некотором отношении R, упоминаемом в ф. Выбранное
таким образом DOM (ф) не обязательно является наименьшим множеством
символов, которое мы могли бы использовать, но оно будет достаточным.
Заметим, что DOM (ф) определяется не в зависимости от вида ф, а как
функция фактических отношений, которые должны подставляться вместо
переменных отношений в ф. Однако, так как все отношения предполагаются
конечными, множество DOM (ф) всегда конечно. Если, например, ф (/)
есть 111] = a \J R (/), где R — бинарное отношение, то DOM (ф) — унар-
ное1 отношение, заданное формулой реляционной алгебры:
{a} U (R) U na (R).
Выражение {/|ф (/)} реляционного исчисления с переменными-корте-
жами назовем безопасным, если выполняются следующие условия:
1. Всякий раз, когда t удовлетворяет ф, каждый компонент t есть эле-
мент DOM (ф).
2. Для любого подвыражения ф вида (д и) (со (и)) каждый компонент
и принадлежит DOM (со), если и удовлетворяет со.
3. Если для любого подвыражения ф вида (уи) (со (и)) каждый компо-
нент и не принадлежит DOM (со), то и удовлетворяет со.
Условия 2 и 3 позволяют устанавливать истинность квантифицирован-
ной формулы (д и) (со (и)) или (V и) (со (и)), рассматривая только и, состав-
ленные из принадлежащих DOM (со) символов. Например, любая фор-
мула (ди) (R (и)\/...) удовлетворяет условию 2, а любая формула
(Vи) (-~R (и)\/ ...) — условию 3.
Хотя условие 3 может показаться неинтуитивным, мы должны заметить,
что формула (V и) (со (и)) логически эквивалентна формуле —, (д и) (—со (и)).
Последняя не является безопасной, если и только если существует некото-
рое и0, для которого истинно —со (и0), и и0 не принадлежит домену формулы
1 Для всех практических целей унарное отношение— это множество символов,
В оно будет так здесь интерпретироваться.
105
!w. Так как домены со и ~1со одни и те же, условие 3 устанавливает, что-
формула (V и) (со (и)) безопасна, когда безопасна формула “1 (а и) (“ ico (и)).
В дальнейшем будет показано, что безопасные выражения реляционно-
го исчисления с переменными-кортежами эквивалентны реляционной ал-
гебре. Определение безопасных выражений исчисления с переменными-кор-
тежами представляет собой интересное и нетривиальное упражнение. К
счастью, при доказательстве эквивалентности реляционной алгебры и ре-
ляционного исчисления нам не требуется точно знать, какие выражения ис-
числения безопасны. Мы можем, однако, привести некоторые примеры кон-
струкций в исчислении с переменными-кортежами, которые с гарантией яв-
ляются безопасными.
Пример 4.6. Пусть ip (/) — формула, такая, что любая ее подформула вида
(gw) (со (и)) или (уи) (со (и)) безопасна. Тогда безопасно каждое выражение вида
(б А Ф (61, поскольку любой кортеж t, удовлетворяющий 7? (/) Д ф (/), принад-
лежит R, в силу чего каждый нз его компонентов принадлежит DOM (R (/) Д ф (/)),
Например, такой вид имеет формула разности множеств {t/R (t) Д _ 5 (/)} при
ф (/) = _ S (/) и формула селекции, где ф (t) = F'.
В качестве обобщения заметим, что безопасна также любая формула вида
{б (Ri(l) V Rt (t) V ... V Rk (6) A V’ (0}- Здесь t [г] должно быть символом, появляю-
щимся в i-м компоненте какого-либо кортежа некоторого отношения Rj. Такой вид
имеет, в частности, формула объединения в примере 4.5, но в ней опущена ф, т. е. мы
можем считать ф тождественно истинной формулой, подобной t [1] = t [1].
Другое безопасное выражение
(бт> । (a «J (а и2)... (a uh) (Rx (uj л /?2 (u2) л... л % (ик)
A t [1J = Utl [Д] л t [2] = Ul21/2] л .. -л t [mJ = Uim lfm]
А ф(Д Uj......wh))}.
Па компонент t [/] налагается ограничение— он должен быть символом, появ-
ляющимся в /7-м компоненте кортежа из R^. Формулы декартова произведения и
проекции в примере 4.5 имеют указанный выше вид.
Редукция реляционной алгебры
к реляционному исчислению с переменными-кортежами
Докажем, что множество функций отношений, выразимых в реляци-
онной алгебре, является в точности тем же самым, что и множество функ-
ций, выразимых безопасными формулами в реляционном исчислении с пе-
ременными-кортежами. В одном направлении эта эквивалентность будет
доказана здесь, а в другом— после того, как мы введем реляционное ис-
числение с переменными на доменах, которое является третьей эквивалент-
ной нотацией.
Теорема 4.1. Если Е — выражение реляционной алгебры, то су-
ществует эквивалентное ему безопасное выражение в реляционном исчис-
лении с переменными-кортежами.
Доказательство. Проведем доказательство индукцией по чис-
лу вхождений операторов в Е.
Базис. Нуль операторов. Тогда Е — либо постоянное отношение
{Д, (2, ..., /п}, либо переменная R, обозначающая отношение. В последнем
случае Е эквивалентно {(|7? (()}, представляющему собой безопасное выра-
жение, как указывалось в примере 4.6. В первом случае Е эквивалентно
{W = /x v t = t2 V - V t = tn},
где t = ti — краткая запись для t [1] — tt Ш Д ... Д t [А] = б [&]. Здесь
k — предполагаемая арность t. Легко видеть, что t [i] — одно из конечных
106
множеств символов, явно представленное как t-й компонент некоторой
константы-кортежа t,.
Индукция. Предположим, что Е имеет по крайней мере один опе-
ратор и что теорема истинна для выражений с числом вхождений операторов
меньшим, чем в Е.
Случай 1. Е = Е± U Еъ. Тогда Ег и Е3 каждое имеют меньшее чис-
ло вхождений операторов, чем Е, и по гипотезе индукции мы можем найти
безопасные выражения реляционного исчисления {У |Фх (/)} и {/|ф2 (/)}, эк-
вивалентные Ех и Е3 соответственно. В таком случае Е эквивалентно
{/|фх (О V 'Фа (0)- Если t удовлетворяет фх (/) V ф2 (0, каждый компонент
t принадлежит DOM (фх) или DOM (ф2). Так как DOM (фх (/) V Ф2 (0) =
= DOM (4>t) U DOM (ф2), то Е эквивалентно некоторому безопасному вы-
ражению. Таким образом, полная формула ф (t) = фх (t) V Фа (0 истинна
только когда t принадлежит DOM (ф) и любая подформула (а и) (со (и)) или
(V и) (со (и)) вф должна входить в фг илиф2. Поэтому в соответствии с гипо-
тезой индукции эти подформулы не нарушают безопасности.
Случай 2. Е=Ег — Е3. Тогда, как и в случае 1, для Ег и £"2 суще-
ствуют безопасные выражения. Ясно, что Е эквивалентно {£|Ф1(0 А —Фз (01-
Так как ПОМ(фх (/)/\ — (ф2 (/))=DOM (фх) (J DOM (ф2), приведенное выше
выражение безопасно.
Случай 3. Е = Е^х Е3. Пусть Ег и Е2 эквивалентны некоторым
безопасным выражениям, как и в случае 1, и пусть Ei и Е3 обозначают от-
ношения арности k и т, соответственно. Тогда Е эквивалентно
{/(Л+m) | (3 „) (3 у) (ц) Д (у)
Л И1] = и[1] Л-Л/[*]=«[*]
л t [Л+П = v[l] Л...A /[*+m] = 0[m])}.
Легко проверить, что приведенное выражение является безопасным, по-
скольку t It] ограничивается значениями, которые может принимать и [с],
если i А’, и значениями, которые может принимать v [i — Л], если k <. i
k + т.
Случай 4. Е — niltit.......ik (Ei). Пусть Ег эквивалентно безопасному
выражению {7|фг (/)}. Тогда Е эквивалентно
{/<*>1 (а«) (Фх(«) a t Hl =« [‘J Л ••• Л t 1*1 = «[‘л1))-
Безопасность этого выражения легко показать, как и в случае 3.
Случай 5. Е — аР (Е^1. Пусть Ег эквивалентно безопасному выра-
жению {/|фх (/)}. Тогда Е эквивалентно {/|фг (/) А Е'}, где F' есть F, в ко-
тором каждый операнд, обозначающий компонент i, заменяется на t (И. Это
выражение безопасно, так как каждый компонент t ограничивается теми
символами, которыми его ограничивает фх (/).
Пример 4.7. Если R и S — бинарные отношения, их композиция в обычном
теоретико-множественном смысле представляется выражением nt,4 (а,_3 (/? X .$)).
Используя алгоритм нз теоремы 4.1, мы можем сконструировать для R X S выражение
реляционного исчисления:
{‘I (Я «) (Я 0 (F И Д S (v) Л HU = и [1] Л Н2] = и [2] Д t 01 = v 11]
Л / [4] = V [2])}.
Для o2==3 (R X S) добавим к этой формуле терм Д /[21 = t [3]. Тогда
ях,4 (я2-з (R X 5)) представляется следующим выражением:
[®1 (Я 0 (Я “) (Яу) (R (“) Л S (v) Д t [1] = и [1] Д t [2] = и [2] Д t [3] - v [I] Д
i [4] - v [2] Д /[2] = t [3] Д щ[Ц = i [1] Д аН2] = t [4]}.
1 В оригинале ошибочно приведено выражение Е — ар (R). —• Примеч. ред.
ЮГ
Отметим, что это выражение не является максимально кратким. Мы можем исключить
t, если заменим каждый из его компонентов соответствующими компонентами и или и.
В результате получим
{да| (а и) (a v) (R (и) Д S (v) Д и [2] = v [1] Д w [1} = v [1] Д w [2] = v 12])}.
Следует признать, что данное выражение представляет собой обычное теоретико-
множественное определение композиции, переведенное в язык реляционного исчисле-
ния с переменными-кортежами.
Реляционное исчисление с переменными на доменах
Реляционное исчисление с переменными на доменах строится из тех же
самых операторов, что и реляционное исчисление с переменными-кортежа-
ми. Различие их состоит в следующем:
1. В исчислении с переменными на доменах не существует никаких пе-
ременных-кортежей. Вместо них существуют переменные на доменах, кото-
рые представляют компоненты кортежей.
2. Атом имеет вид:
a) R (XjX2 ...xk), где R — Парное отношение и каждое xt есть констан-
та или переменная на домене, либо
б) хву, где хну — константы или переменные на доменах, а 0 — ариф-
метический оператор сравнения.
R указывает, что значения тех xt, которые являются перемен-
ными, должны быть выбраны так, чтобы XjX2 ...xk было кортежем отноше-
ния R. Смысл атома хву заключется в том, что х и у представляют собой зна-
чения, при которых истинно хву.
3. Формулы в реляционном исчислении с переменными на доменах ис-
пользуют связки Д, V и ~I, как и в исчислении с переменными-кортежами.
Для записи выражений исчисления с переменными на доменах применяют-
ся также кванторы (дх) и (V х), но х является переменной на домене, а не
переменной-кортежем.
Понятия свободных и связанных переменных на доменах и область дей-
ствия связанной переменной определяются в исчислении с переменными на
доменах точно так же, как и в исчислении с переменными-кортежами, поэ-
тому мы ие будем повторять здесь эти определения. Выражение исчисления
с переменными на доменах имеют вид {хгх2 ...хЛ|ф (хх, х2, ..., xft)}, гдеф—
формула, обладающая тем свойством, что только ее свободные переменные
на доменах являются различными переменными хь х2, ..., xh.
Аналогично исчислению с переменными-кортежами введем следующее
определение. Выражение исчисления с переменными на доменах
{хгх2 ...хЛ|ф (хь х2, ..., xft)} называется безопасным, когда
1) из истинности ф (хь х2, ..., xft) следует, что х; принадлежит DOM (ф);
2) если (ди) (со («)) — подформула ф, то из истинности со (и) следует,
что и принадлежит DOM (со);
3) если (V и) (со (и)) — подформула ф, то из истинности —. со (и) сле-
дует, что и принадлежит DOM (со).
Пример 4.8. Рассмотрим снова последнюю часть примера 4.5, где было за-
дано бинарное отношение R и требовалось написать выражение, которое было бы рав-
но R, если бы в нем имелось не менее двух элементов, и пустому множеству—в против-
ном случае. В реляционном исчислении с переменными на доменах одним из таких вы-
ражений является следующее:
*1 (а У) (3 г) (R (шх) /\ R (yz) /\ у \/ х =#»)}.
Пусть ф (и>, х, у, г) обозначает формулу
R (wx) Л Я (уг) Л У V *¥= г)
108
н J? есть отношение {12, 13). Если положить = 1 и х = 2, то формула
(Э У) (Я «) (Ф (1. 2- У. г))
окажется истинной в связи с тем, что при выборе у = 1 н г = 3 будет истинной форму-
ла ф. Точно так же эта формула является истинной при w = 1 и х — 3, поскольку мы
можем выбрать у = 1 и г = 2. Следовательно, оба кортежа 12 и 13 принадлежат множе-
ству, обозначенному нашим выражением исчисления с переменными на доменах. Если
выбрать, однако, любые другие значения w и х, то подформула R (wx) из ф, а значит, и
формула (д у) (g z) (ф (w, х, у, г)) ложны. Таким образом, приведенное выше выра-
жение исчисления с переменными на доменах обозначает множество, равное R, когда
R = {12, 13).
Допустим, что R — одноэлементное множество, например {12}, тогда никакие зна-
чения w и х не удовлетворяют формуле (д у) (д г) (ф (w, х, у, г)). Действительно,
R (wx) — первая подформула ф — удовлетворяется только прн w — 1 и х = 2, вторая
подформула R (уг) — только при у = 1, г = 2, но прн этом не удовлетворяется тре-
тья подформула у V г)-
Редукция исчисления с переменными-кортежами
к исчислению с переменными на доменах
Выражение исчисления с переменными на доменах, эквивалентное за-
данному выражению исчисления с переменными-кортежами {/|ф (/)}, кон-
струируется весьма просто. Если t имеет арность k, введем k новых перемен-
ных на доменах tu t2, ..., и заменим заданное выражение следующим:
VA • -А1Ф' (^i. •••» МЬ Здесь ф' представляет собойф, в которой любой
атом R (f) заменен атомом R ((^2 ...tk)< а каждое свободное вхождение
t [i] — переменной ti. Отметим, что в формулеф могут быть связанные вхож-
дения t, если существует некоторый квантор (д t) или (V /), в котором t слу-
жит для ссылок на «иные» переменные-кортежи, и такие переменные не за-
меняются1.
Далее, для каждого квантора (д м) или (V и) вводим т новых перемен-
ных на доменах иь и2, ..., ит, где т — арность и. В области действия этой
квантификации и заменяем и И на иг и R (и) на R («t и2 ... ит). Заменя-
ем также (д и) на (g mJ ...(g um) и (V м) на (V мг)... (V um). В результате
получаем выражение исчисления с переменными на доменах, очевидно,
эквивалентное первоначальному выражению исчисления с переменными-
кортежами.
По-видимому, ясно, что tt может принимать в точности те же значения,
которые в первоначальном выражении принимает t [{]. Таким образом, ес-
ли выражение {/[ф (/)} безопасно, то безопасно и результирующее выраже-
ние исчисления с переменными на доменах. Поэтому сформулируем без до-
казательства следующую теорему.
Теорема 4.2. Для каждого безопасного выражения реляционного
исчисления с переменными-кортежами существует эквивалентное безопас-
ное выражение реляционного исчисления с переменными на доменах.
Пример 4.9. Описанный выше алгоритм был использован для продуцирова-
ния из последнего выражения исчисления с переменными-кортежами примера 4.5 выра-
жения исчисления с переменными на доменах, рассматриваемого в примере 4.8.
Приведем другой пример. Возьмем выражение композиции нз примера 4.7:
{®1(3 “) (3 v) (R (и) Л S (ц)
Л и И = v [1] Л ® (И = и И) Л w [2] = v [2])}.
1 Это аналогично ситуации, когда в обычных языках программирования, обладаю-
щих блочной структурой, локальная и глобальная переменные имеют один и тот же
идентификатор.
109
Заменим w на w^, и на и v на 1ди2. В результате получим
{tt>it»2|(a «J (а и2) (a vx) (a t>2) (R (и^) д s (vxv2)
Л «2 = «1 Л = «1 Л ®2 = Цг)}‘
Редукция исчисления с переменными на доменах
к реляционной алгебре
Наш план состоит в том, чтобы взять произвольную безопасную форму-
лу ф (хп х2, ..., xft) исчисления с переменными на доменах, где хп х2,
хА — свободные переменные, и сконструировать индукцией по числу опера-
торов в ф алгебраическое выражение, значение которого
{XjX2 ...хЛ|ф (х„ х2, ...,xft)}.
Если даже заданное выражение является безопасным, некоторые под-
формулы его формулы могут не обладать этим свойством. Поэтому докажем
индукцией по размеру (числу операторов) подформулы со формулы ф со сво-
бодными переменными ylt ут, что существует выражение реляцион-
ной алгебры для
(DOM (Ф))т П {х/1*/2 ...ут\(Л (У1, У г, •••, Ут}},
где Dm обозначаетD X D X ... X D (т раз). При доказательстве будут по-
лезны следующие леммы.
Лемма 4.1. Для любой формулы ф исчисления с переменными на
доменах (или исчисления с переменными-кортежами) существует выраже-
ние в реляционной алгебре, обозначающее унарное отношение (множество)
DOM (ф).
Доказательство. Если R — отношение арности k, то пусть
Е (R) = ях (R) U л2 (R) и ... U (/?).
Тогда искомое выражение представляет собой объединение Е (R) по всем
входящим в формулу ф переменным-отношениям и постоянного отношения
{«,, а2, ..., ап}, где все а, являются символами констант, входящих в ф.
Лемма 4.2. Для произвольной формулы ф исчисления с переменными
па доменах (или исчисления с переменными-кортежами) существует эквива-
лентная ей формула ф' этого исчисления, не содержащая вхождений Д или
V- Если ф — безопасная формула, то безопасной является и формула ф'.
Доказательство. Заменим каждую подформулу фх Д ф2 из
ф на _(—,фх \/ —ф2). Это сохраняющее эквивалентность преобразование
называется законом де Моргана и гласит, что подформулы фх и ф2 обе истин-
ны, если и только если ие является истиной то, что фх или ф2 ложна. За-
меним далее каждую подформулу (у«) (фх («)) на — (а «) (— фх («))• Это
преобразование также сохраняет эквивалентность и, по существу, означает,
чтоф! истинна для всех «, если и только если не существует и, для которого
фх ложна.
Пусть в результате получена формула ф'. Эта формула, несомнеиио, эк-
вивалентна ф-. Если ф безопасна, то, как известно, фх (и) истинна для каж-
дой подформулы (V и) (фх («)), когда и имеет некоторое значение, не при-
надлежащее множеству DOM (фх). Следовательно, —фх («) ложна, когда и
не принадлежит DOM (ф^, или, что эквивалентно, принадлежит DOM (—,фх).
Таким образом, формула (д и) (—фх («)) также удовлетворяет условию безо-
пасности.
ПО
Т еор ем а 4.3. Для каждого безопасного выражения реляционного
исчисления с переменными на доменах существует эквивалентное ему вы-
ражение реляционной алгебры.
Доказательство. Пусть {хх ...хЛ|ф (хх, ..., xft)} — безопасная
формула исчисления с переменными на доменах. По лемме 4.2 мы можем пред-
положить, что ф содержит только операторы \/, ~"'и 3. Мы можем принять
также по лемме 4.1, что Е — выражение реляционной алгебры для множест-
ва DOM (ф), и, как обычно, Ek обозначает Е х Е X ... X Е (k раз). Дока-
жем индукцией по числу операторов в подформуле со из ф, что если w со-
держит свободные переменные на доменах ylt у2, ..., ут, то для
DOM (ф)т Л {ух ... ут\<& (уг, ..., ут)} существует эквивалентное выраже-
ние в реляционной алгебре. Тогда в частном случае, когда <о есть само ф,
получаем алгебраическое выражение для DOM (ф)* л {хх ...хк|ф (хх, .... хЛ)}.
Поскольку ф — безопасная формула, пересечение с DOM (ф)* не изменит
обозначаемого ею отношению и, таким образом, теорема будет доказана.
Вернемся теперь к индуктивному доказательству.
Базис. Нуль операторов в <о. Тогда <о есть атом. Мы можем принять,
что он имеет один из видов: хх0х2 , xx0xx, хх0а или R (xitxit ... xiz), где 0 —
арифметический оператор сравнения, а а — константа. Если атом имеет вид
хх0х2, то требуемое алгебраическое выражение — стюг (Е х Е). Аналогич-
но поступаем с атомами вида хх0хх и хх0а.
Наконец, если атом имеет вид R (xtlx{, ...х^), конструируем выраже-
ние л ....jh (о>(/?)), где F — формула, содержащая терм и = v всякий
раз, когда xiu и xiv представляют собой одни и те же переменные и и < и.
Все термы связываются операторами Д1. Список /х, j2, ..., jh должен быть
здесь таким, чтохг/ = хх, ..., х^ =Хь- Например, если фесть R (х2ххх2х3),
то наше выражение имеет вид л211>4 (стх=3 (7?)).
Индукция. Предположим, что со содержит по крайней мере один
оператор и что гипотеза индукции справедлива для всех подформул форму-
лы ф, имеющих меньше операторов, чем со.
Случай 1. Имеем со (ylt ..., ут) = ®х (иг, ..., ип) V <о2 (их, ..., ор),
где все иг являются различными yt, а все иг — различными у$ (хотя некото-
рые ии v могут быть одинаковыми у2). Пусть Ех — алгебраическое выраже-
ние для
DOM (ф)” л {«1 ...ып|<ох (uj, .... ип)},
а Ег — для
DOM (ф)₽ Л {vx • • -vp|<о2 (их, ..., Up)}.
Определим EJ следующим образом:
...im(£1XEm-n),
где ii — это q, такое, что uq = уь если такое uq существует, и it—уникаль-
ное целое число между п + 1 и т в противном случае. Подобным же обра-
зом определим
^>^х....../т(£2х Ет-\
где /[ есть q, при котором vq= уь если такое vq существует, и —уникаль-
ное целое между р + 1 и т в противном случае. Тогда требуемое выраже-
ние — Е{ U Е'ч-
1 Отметим, что если существует три или более вхождения одной переменной,
некоторые из этих термов являются избыточными и могут быть исключены.
111
Например, если со (ylt у2, у3, уд имеет вид
(г/л, у9, уд V ®2 (у2, уд,
то
= 4, 2.з(Е1ХЕ)
и
£; = лз,1,4,2(£2х£х£).
Корректность формулы EJ и Eq следует из того, что Е{ обозначает
DOM (ф)т Л {У1 ... («1, •••, «п)}, а £2 — DOM (ф)т Л {г/i ...г/т|®2
(ип ..., ир)}. (Напомним, что каждое и и каждое v представляют собой один
из у.) Из этого следует, что £[ и Eq обозначает
DOM (ф )т Л {У1 -..«/ml® (У1, •••> Ут)}-
Случай 2. <о (г/л, ..., г/то) = ~сол (г/л....ут). Пусть ^ — алгеб-
раическое выражение для DOM (ф)т л {yi ...г/то|сол (У1, • ••» Ут)}- Тогда
Ет—Ег — выражение для
DOM (ф)т — {У! (Ук ...» Ут)},
которое, в свою очередь, эквивалентно
DOM (ф)т Л {У1 ...ут\ — (У1, ..., Ут)}-
Случай 3. со (г/л, .... ут) = (эут+д (®л (г/л, .... г/м+л)). Пусть Е± —
алгебраическое выражение для
DOM (ф)"^1 Л {У1 ... г/т+11®1 (yi, .... Ут+д}-
Так какф — безопасная формула, ©л (уг, ..., ут+д не. может быть ис-
тинной, если ут+1 не принадлежит множеству DOM (сол)» являющемуся под-
множеством DOM (ф). Следовательно, л12........т (Ег) обозначает отношение
DOM (ф)"* Л {yi ...ут1 (ЭУтп+1) (®1 (У1, Ут+1))},
что завершает индукцию и доказывает теорему.
Пример 4.10. Пусть R и S — бинарные отношения. Выражение исчисления
с переменными на доменах
{wx | R (wx) л (V У) (—• S (wy) A — S (xy))}
обозначает множество кортежей в R, ни один из компонентов которых ие является пер-
вым компонентом какого-либо кортежа S. Это выражение является безопасным, по-
скольку
1) формула не удовлетворяется для w и х, если wx не является кортежем R, и
2) всякий раз, когда у не является символом, входящим в какой-либо кортеж S,
очевидно, истинна формула
— S (wy) А — S (ху).
Пусть Е обозначает (R) U л2 (R) U Лл (S) U л2 (S). Сначала исключим Дну,
используя построение из леммы 4.2. После «взаимного уничтожения» пар отрицаний
—। получим выражение
{wx | - (— R (wx) у (з у) (S (wy) у S (ху)))}.
Применим теперь построения из теоремы 4.3 сначала к атомам, а затем к более
крупным подформулам. Выражение R обозначает Е2 Л (wx)}, в то время как вы-
ражение S есть Ё2 Л {wlS (w у)}, так же как и Е2 Л {xy|S (ху)}1.
1 «Формулы» R и S являются существенно более простыми, чем заданные в бази-
се теоремы 4.3. Мы можем использовать здесь сами отношения, так как никакой атом
не содержит переменных на доменах, входящих в два компонента.
112
В соответствии со случаем 1 из теоремы 4.3 получим выражение для
£3 П {o>xy|S (wy) V S (ху)}, имеющее вид
— "1,з,а (S X Е) I) n3iii2 (S X Е).
Далее случай 3 той же теоремы позволяет для
Ег П {Щ*|(э У) (S (wy) V S (ху))}
также найти эквивалентное выражение л112 (£j). Если теперь очевидным способом по-
строить каскадные проекции, то получим
£2 — л118 (S X Е) (J л8д (S X Е).
Это выражение обозначает множество пар, один из компонентов которых являет-
ся первым компонентом кортежа из S, а другой входит в некоторый кортеж R или S.
В соответствии со случаем 2 выражение для £2 П {щ*| 1 R (o'*)} представляет-
ся в виде £2 — £. Кроме того, в соответствии со случаем! (£2 — £) (J Ег есть формула
для {юх| "о R (wx) (g у) (S (wy) V S (ху))}. Заметим, что проекции здесь могут быть
опущены, поскольку л112 и для £2 — £, и для £2 оставляет все кортежи неизменными.
Наконец, полное выражение исчисления с переменными на доменах эквивалентно алге-
браическому выражению вида £2 — ((£2 — R) U Е2). Так как R и £2 оба являются под-
множествами £2, это выражение эквивалентно R — Еъ, т. е.
R ~ («1.3 (S X £) U "ад (« X £)).
4.3. ОБЩИЕ ЗАМЕЧАНИЯ ОТНОСИТЕЛЬНО ЯЗЫКОВ ЗАПРОСОВ
Мы рассмотрели три абстрактные нотации, которые могут служить ос-
новой языка манипулирования данными, позволяющего получать информа-
цию из отношений: реляционную алгебру, реляционное исчисление с пере-
менными-кортежами и реляционное исчисление с переменными на доменах.
Как показывают теоремы 4.1, 4.2 и 4.3, эти три нотации эквивалентны по
своей выразительной силе.
Использовать реляционное исчисление с переменными-кортежами (с фор-
мализацией, несколько отличающейся от предложенной в разд. 4.2) как эта-
лон для оценки языков манипулирования данными, основанных на реляцион-
ной модели, впервые предложил Кодд [43]. Иными словами, язык, который
не обладает, по меньшей мере, выразительностью безопасных формул реля-
ционного исчисления или, что равносильно, реляционной алгебры, считает-
ся неадекватным. Дело обстоит так, что едва ли не во все современные язы-
ки запросов встраивается одна из трех рассмотренных в предыдущем разде-
ле нотаций, а в некоторые языки — их комбинация. Язык, в котором мож-
но (по крайней мере) моделировать исчисление с переменными-кортежами,
либо, что равносильно, реляционную алгебру или исчисление с переменны-
ми иа доменах, называется полным. В этой главе будут рассмотрены неко-
торые примеры языков и показана их полнота.
Дополнительные возможности языков
манипулирования данными
В сущности, языки манипулирования данными обладают в общем слу-
чае возможностями, выходящими за рамки реляционного исчисления. Во
всех языках манипулирования данными предусматриваются, конечно, коман-
ды включения, удаления и модификации, которые не являются частью реля-
ционной алгебры или реляционного исчисления. Кроме того, часто предо-
ставляются следующие дополнительные возможности:
1. Арифметические вычисления. Атомы в выражениях реляционного
исчисления и формулах селекции в алгебраических выражениях часто могут
включать арифметические вычисления, а также сравнения, например, ви-
1Ц
да A<Z В + 3. Заметим, что + и другие арифметические операторы не ис-
пользуются ни в реляционной алгебре, ни в реляционном исчислении.
2. Команды присваивания и печати. В общем случае языки допускают
печать отношения, сконструированного с помощью алгебраического выра-
жения либо выражения исчисления, или присваивание вычисленного от-
ношения как значения некоторому имени отношения.
3. Агрегатные функции. К столбцам отношения часто применяются \ •»-
кие операции, как среднее, сумма, минимум или максимум, в результате
которых вычисляется единственная величина.
По этим причинам языки, которые мы будем рассматривать, в действи-
тельности являются «более чем полными». Они позволяют вычислять функ-
ции, не имеющие аналогов в реляционной алгебре или реляционном исчис-
лении. Многие (но не все) рассматриваемые далее языки стали бы эквива-
лентными реляционному исчислению, если бы из них были исключены агре-
гатные и арифметические операторы. Доказательство этого утверждения
является интересным упражнением. При этом нужно показать, как преоб-
разовать в реляционное исчисление или в реляционную алгебру любое вы-
ражение языка, не содержащее арифметики или агрегации. Следует, од-
нако, предупредить читателя о том, что мы не приводим здесь полного мно-
жества возможностей обсуждаемых языков. Поэтому перед тем, как пред-
принять такое доказательство, следует обратиться к руководству по язы-
ку. К тому же некоторые языки, подобные Query-by-Example (разд. 4.7),
являются «более чем полными» даже после исключения арифметики и агре-
гации. В частности, Query-by-Example допускает вычисление транзитив-
ного замыкания отношения, хотя в данной книге этот вопрос не рассматри-
вается.
Сравнение алгебраических языков
и языков исчисления
Часто говорят, что языки, основанные на реляционном исчислении, пред-
ставляют собой языки более высокого уровня по сравнению с алгебраичес-
кими, поскольку алгебра специфицирует порядок операций, в то время как
исчисление оставляет определение наиболее эффективного порядка вычис-
лений компилятору или интерпретатору. Например, если имеются отноше-
ния R (Л, В) и S (В, С), мы можем написать алгебраическое выражение
лс(ал=ао(/?><5)), (4.1)
где[><]обозначает естественное соединение, а а0 — константу. Этот запрос
гласит: «Напечатать значения С, ассоциированные со значением А, равным
а0, в отношении со столбцами А, В и С, полученным в результате соедине-
ния». Эквивалентное выражение в исчислении с переменными на доменах
имеет вид
W (a b) (R (aob) A s (Ьс))}. (4.2)
Сравнивая (4.1) и (4.2), можно видеть, что выражение в исчислении фак-
тически только указывает, что мы хотим, но не описывает, как это полу-
чить. Так, (4.2), специфицирует лишь свойства желаемого значения с. Вы-
ражение (4.1), напротив, специфицирует конкретный порядок операций.
Нетрудно убедиться в том, что (4.1) эквивалентно выражению
лс(лв(стл=0о(/?))><15). (4.3)
Для вычисления (4.3) нужно сначала найти в R кортежи с Л-значения-
ми а0 и ассоциированные с ними В-значения. В результате будет вычислено
114
пв (<УА=аа (R))- Затем находим кортежи S с такими В-значениями и печа-
таем ассоциированные с ними С-значения.
По сравнению с этим выражение (4.1) требует вычисления естественно-
го соединения R и S, что, в свою очередь, может вызвать необходимость
сортировки обоих отношений по их В-значениям и просмотра сортирован-
ных отношений. В зависимости от организации файлов, используемых для
представления R и S, вычисление (4.1) может потребовать значительно боль-
ше времени, чем (4.3), хотя и будет получен один и тот же ответ.
В принципе, мы всегда можем вычислять (4.2), следуя (4.3), а не (4.1),
что считают обычно преимуществом исчисления перед алгеброй, поскольку
в алгебраическом языке с большей вероятностью может быть написано (4-1),
чем (4.3). Однако компилятор языка запросов при оптимизационном про-
смотре может непосредственно преобразовать (4.1) в (4.3). Кроме того, вы-
ражения реляционного исчисления необходимо оптимизировать, если мы
хотим извлечь максимальную выгоду из его непроцедурности1.
Проблемы оптимизации запросов рассматриваются в гл. 6. Таким об-
разом, нам представляется весьма условным считать исчисление более вы-
соким уровнем по сравнению с алгеброй хотя бы потому, что на первом ша-
ге оптимизации алгебраическое выражение может быть преобразовано по
теореме 4.1 в эквивалентное выражение исчисления. Следует признать, од-
нако, что языки, основанные на исчислении, в настоящее время более рас-
пространены, чем алгебраические. Мы предпочитаем объяснять преоблада-
ние языков исчисления их непроцедурностью, желательной с точки зрения
программиста, а не эффективностью или легкостью компиляции для таких
языков.
Выражения вида «селекция-проекция-соединение»
Хотя мы предполагаем, что язык запросов является полным, существу-
ет некоторое подмножество выражений реляционной алгебры, используемых
очень часто, и нам важно рассмотреть, насколько легко в языке иметь дело
с этими выражениями. Класс выражений, который имеется в виду, образу-
ется из операторов селекции, проекции и естественного соединения. Интуи-
тивно многие запросы могут рассматриваться следующим образом: взять
некоторый объект (описанный предложением селекции), ассоциировать
его с каким-либо объектом другого типа, возможно, через многие связи (ес-
тественное соединение выражает ассоциирование), а затем напечатать нуж-
ные атрибуты последнего объекта (печатаемые атрибуты определяет про-
екция). Мы называем такие выражения выражениями вида «селекция-про-
екция-соединение». Читателю рекомендуется проследить; как в каждом из
описанных языков запросов можно лаконичным образом обращаться с за-
просами рассматриваемого вида.
4.4. ISBL: «ЧИСТЫЙ» ЯЗЫК РЕЛЯЦИОННОЙ АЛГЕБРЫ
ISBL (Information System Base Language) — это язык запросов, раз-
работанный в исследовательском центре фирмы ИБМ в Питерли (Англия)
для использования в экспериментальной системе PRTV (Peterlee Relatio-
nal Test Vehicle). Он весьма близок к реляционной алгебре, рассмотренной в
разд. 4.1. Поэтому полнота ISBL может быть легко доказана. Синтаксичес-
1 Непроцедурным называется язык, средствами которого можно выразить, что
нам нужно, не обязательно говоря о том, как это получить.
115
кое соответствие этого языка и реляционной алгебры показано в таблице
на рис. 4.6. Как в ISBL, так и в реляционной алгебре, AJ и S могут быть лю-
быми реляционными выражениями, a F — булевской формулой. Компо-
нентам отношения присваиваются имена, и мы обращаемся к компонентам
в F по этим именам.
Реляционная алгебра ISBL
R — S R(]S °f(R) "л, AnW R><lS R+S R-S R. S RiF R%\....,An R* S
Рис. 4.6. Соответствие между ISBL и реляцион-
ной алгеброй
Чтобы напечатать значение некоторого выражения, помещаем перед
ним LIST. Для присваивания значения выражения отношению, имя кото-
рого F, записываем R — Е. Следует отметить интересную особенность при-
сваивания, которая заключается в том, что можно отложить связывание
отношения с именами, входящими в выражение, до тех пор, пока имя этого
отношения не будет использовано слева от знака присваивания. Чтобы от-
ложить вычисление некоторого отношения, поместим перед его именем в вы-
ражении оператор ЛИ. Этот оператор вызывает вычисление «по наименова-
нию»1.
Пример 4.11. Предположим, что требуется иногда использовать компози-
цию бинарных отношений R (А, В) ъ S (С, D). Если записать
RCS = R*S : В = С%А, D,
то будет вычислена композиция текущих значений отношений R и S и присвоена имени
отношення RCS. Отметим, что R и S имеют атрибуты с различными именами. Поэтому
оператор * (естественное соединение) является здесь декартовым произведением.
Допустим, однако, что мы хотели бы обозначить через RCS не композицию теку-
щих значений R (А, В) и S (С, D), а формулу композиционирования R и S. Тогда сле-
довало бы записать
RCS = N!R*N!S : В = С%А, D.
Этот оператор ISBL не вызывает вычисления отношений. Он определяет, скорее,
RCS как обозначение формулы R*S : В = С%А, D. Если мы когда-либо используем
RCS в операторе, который требует вычисления этого отношения, например в операторе
LIST RCS
или
Т = RCS + U,
то текущие значение R и S для этого момента времени подставляются в формулу RCS,
и вычисляется значение RCS.
Оператор отложенного вычисления ЛИ служит двум важным целям. Во-
первых, большие реляционйые выражения трудно записать корректно с
1 Здесь имеет место аналогия с передачей значений формальным параметрам
процедуры с помощью вызова по наименованию н различных языках программирова-
ния, например в Алголе-60. — Примеч. ред.
116
первого раза. Отложенное вычисление позволяет программисту упростить
конструирование выражений благодаря назначению временных имен важным
их частям. Однако более существенно то, что отложенное вычисление предо-
ставляет элементарную возможность для определения представлений. Бла-
годаря определению имен отношений как выражений с отложенным вычис-
лением программист может использовать эти имена так, как будто определя-
емые отношения действительно существуют. Таким образом, множество оп-
ределяемых отношений образует представление базы данных.
Переименование атрибутов
Определения чисто теоретико-множественных операторов — объеди-
нения, пересечения и разности — модифицируются здесь по отношению к их
стандартным определениям в реляционной алгебре с тем, чтобы учесть тот
факт, что компоненты имеют имена атрибутов. Операторы объединения и
пересечения применимы только если отношения-операнды имеют одни и те
же множества имен атрибутов. Оператор разности 7? — S является обычной
теоретико-множественной разностью, если 7? и S имеют одно и то же мно-
жество имен атрибутов. Однако в том случае, когда некоторые из атрибу-
тов 7? и S различны, 7? — S обозначает множество принадлежащих 7? кор-
тежей t, таких, что t не совпадает ни с одним кортежем в S по тем атрибутам,
которые являются общими для R и S. Таким образом, например, в ISBL вы-
ражение 7? — S, где 7? есть R (Л, В), a S — отношение S (Л, С), обознача-
ет выражение реляционной алгебры:
R — лА (S) X лв (R).
Для создания возможности использования нужным образом этих опера-
торов предусматривается специальный вид проекции, обеспечивающий пе-
реименование атрибутов. В списке атрибутов, следующих за оператором
проекции (%), элемент А -> В означает, что компонент, соответствующий
атрибуту А, включается в проекцию, но переименовывается в В. Например,
чтобы получить объединение R (А, В) с S (Л, С), запишем
(R %Л, В->С) + S.
Результирующее отношение имеет атрибуты А и С.
Мы можем также применить переименование для получения декартова
произведения отношений, множества атрибутов которых пересекаются. За-
метим, что естественное соединение R (Л, B)*S (С, D) является в действи-
тельности декартовым произведением, a R (Л, B)*S (В, С) — естествен-
ным соединением, в котором В-компоненты R и S равны. Если требуется
получить декартово произведение R (А, В) и S (В, С), мы можем записать
(R % А, В -> D)*S.
Так как левый операнд оператора * имеет атрибуты А и D, a S — атри-
буты В и С, результат является декартовым произведением.
Благодаря переименованию атрибутов существует возможность моде-
лирования любой из пяти основных операций реляционной алгебры в ISBL.
Таким образом, очевидно, что ISBL является полным языком.
Некоторые примеры запросов
Пример 4.12. Рассмотрим теперь пример базы данных, которая будет ис-
пользоваться при обсуждении различных языков запросов. Пищепродуктовый коопе-
ратив в Счастливой Долине поддерживает базу данных, в которой записаны бплан-
117
сы его членов, их заказы, а также возможные поставщики и цены. Эту базу данных мож-
но описать тремя схемами отношений:
ЧЛЕНЫ (ФАМИЛИЯ, АДРЕС, БАЛАНС)
ЗАКАЗЫ (ФАМИЛИЯ, ТОВАР, КОЛИЧЕСТВО)
ПОСТАВЩИКИ (НАЗВ_ПОСТ, АДРЕС-ПОСТ, ТОВАР, ЦЕНА)
Будем считать, что иа рис. 4.7 представлены «текущие значения» соответствующих
отношений, используемые в примерах этой главы. Далее приводятся некоторые типич-
ные запросы и их выражения в ISBL.
ФАМИЛИЯ АДРЕС БАЛАНС
Брукс Яблочное шоссе, 7 + 10,50
Филд Вишневый переулок, 43
Робин Вересковая улица, 12 —123,45
Харт Жаворонковое шоссе, 65 —43,00
а) ЧЛЕНЫ
ФАМИЛИЯ ТОВАР КОЛИЧЕ-
СТВО
Брукс Карамель 5
Брукс Мука 10
Робин Карамель 3
Харт Сметана 5
Робнн Фасоль 2
Робин Салат 8
б) ЗАКАЗЫ
ИАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
Солнечная продукция Речная улица, 16 Карамель 1,29
Солнечная продукция Речная улица, 16 Салат 0,89
Солнечная продукция Речная улица, 16 Фасоль 1,09
Натуральные продукты Индустриальное шоссе, 180 Сметана 0,70
Натуральные продукты Индустриальное шоссе, 180 Творог 0,80
Натуральные продукты Индустриальное шоссе, 180 Карамель 1,25
Натуральные продукты Индустриальное шоссе, 180 Мука 0,65
Корп. вкусных продуктов Речная улица, 17 Салат 0,79
Корп. вкусных продуктов Речная улица, 17 Сметана 0,79
Корп. (жусиых продуктов Речная улица, 17 Фасоль 1 ,!9
в) ПОСТАВЩИКИ
Рис. 4.7. Текущее состояние отношений в базе данных
Примечание. Все адреса относятся к городу Счастливая Долина.
КОЛИЧЕСТВО дается в фунтах, а ЦЕНА — за фунт.
1. Простейшие запросы часто включают селекцию и проекцию над единственным
отношением, т. е. специфицируется некоторое условие, которому должны удовлетво-
рять кортежи, н печатаются некоторые или все компоненты этих кортежей. Конкретный
118
пример запроса такого рода: «Напечатать фамилии членов кооператива с отрицатель-
ными балансами». Запись такого запроса в ISBL имеет вид
LIST ЧЛЕНЫ: БАЛАНС < 0% ФАМИЛИЯ
Фраза БАЛАНС < 0 приводит к выборке третьего н четвертого кортежей, по-
скольку их компоненты в третьем столбце (БАЛАНС) отрицательны. Оператор проек-
ции оставляет только первый столбец— ФАМИЛИЯ. Поэтому печатается таблица:
Робин
Харт
2. При запросе более сложного вида необходимо получить естественное соедине-
ние, соединение общего вида или декартово произведение нескольких отношений, осу-
ществить селекцию кортежей из построенного отношения и напечатать некоторые их
компоненты. Пример такого запроса: «Напечатать названия, товары и цены для всех
поставщиков, которые поставляют по крайней мере один товар, заказанный Бруксом».
Мы могли бы непосредственно записать выражение для этого запроса, но кон-
цептуально проще сначала определить естественное соединение отношений ЗАКАЗЫ и
ПОСТАВЩИКИ:
ЗП = N! ЗАКАЗЫ* NI ПОСТАВЩИКИ
Заметим, что вычисление отношения ЗП откладывается. Теперь с помощью имею-
щегося в нашем распоряжении естественного соединения
ЗП (ФАМИЛИЯ, ТОВАР, КОЛИЧЕСТВО, НАЗВ _ ПОСТ,
АДРЕС-ПОСТ, ЦЕНА)
осуществляем селекцию множества кортежей, в которых ФАМИЛИЯ = «Брукс»,
и проецируем их на требуемые атрибуты НАЗВ-ПОСТ, ТОВАР и ЦЕНА. Восполь-
зуемся для этого следующей формулой:
LIST ЗП: ФАМИЛИЯ = «Брукс» % НАЗВ.ПОСТ ТОВАР ЦЕНА
Результат этого выражения приведен в таблице на рис. 4.8.
НАЗВ-ПОСТ ТОВАР ЦЕНА
Солнечная продукция Карамель 1,29
Натуральные продукты Карамель 1,25
Натуральные продукты Мука 0,65
Рис. 4.8. Результат второго запроса
3. Запрос еще более сложного вида использует некоторый эквивалент квантора
«для всех». Рассмотрим конкретный[запрос: «Напечатать поставщиков, которые постав-
ляют каждый товар, заказанный Бруксом».
Такне запросы являются более легкими для языков исчисления, чем для алге-
браических языков. Читатель может заметить, что в доказательстве теоремы 4.3 кван-
торы у были исключены перед преобразованием в алгебраическую форму путем пред-
ставления их с помощью кванторов а с отрицаниями. Применим здесь ту же стратегию.
Сначала построим множество поставщиков, которые не поставляют никакого товара,
заказанного Бруксом. Введем следующие определения:
S = N! ПОСТАВЩИКИ % НАЗВ-ПОСТ /* множество поставщиков */
I = N! ПОСТАВЩИКИ % ТОВАР /* множество поставляемых товаров */
В = N! ЗАКАЗЫ: ФАМИЛИЯ= «Брукс» % ТОВАР/* товары, заказанные Бруксом */
NS = N!S*N!I — (N! ПОСТАВЩИКИ % НАЗВ.ПОСТ, ТОВАР) /* пары постав-
щиков и товаров, не поставляемых этим поставщиком */
NSB = N! NS. (N!S*N!B) /* множество пар поставщик— товар, таких, что постав-
щик не поставляет такой товар и этот товар заказал Брукс */
119
Тогда требуемое выражение: S — (NSB% НАЗВ-ПОСТ). В соответствии с этим
выражением вычисляется список, состоящий нз одного элемента: Натуральные продук*
ты.
Расширения ISBL
Язык ISBL является довольно ограниченным по сравнению с языками
запросов, которые будут обсуждаться в следующих разделах. В нем нет,
например, никаких агрегатных операторов (среднее, минимум и т. п.), а
также средств для включения, удаления или модификации кортежей. Окру*
жающая PRTV система позволяет, однако, написать любые программы на
языке ПЛ/1 и объединить их в обработке отношений.
Простейшим случаем использования ПЛ-программ в ISBL являются
Кортежные процессоры, которые служат обобщенными операторами селек-
ции. Например, можно написать программу LOWADDR (S), которая иссле-
дует литерную строку S, рассматриваемую как адрес, и определяет, меньше
ли номер дома 50. Если ответ положительный, то программа возвращает
значение «истина». Тогда мы можем применить LOWADDR к некоторому
атрибуту в выражении языка ISBL таким образом, чтобы компонент, соот-
ветствующий данному атрибуту в каждом кортеже, передавался програм-
ме, и этот кортеж «селектировался» бы, если LOWADDR возвратит зна-
чение «истина». Синтаксис ISBL предусматривает возможность использо-
вания оператора соединения для такой обобщенной селекции. Следователь-
но,
LIST (ЧЛЕНЫ* LOWADDR (АДРЕС))% ФАМИЛИЯ
печатает фамилии членов кооператива, номера домов которых не пре-
вышают 49.
Могут быть также определены программы в ПЛ/1, которые опери-
руют не кортежами, а полными отношениями. Чтобы облегчить обра-
ботку, система PRTV допускает передачу отношений таким программам
либо как реляционных файлов для чтения, либо как реляционных фай-
лов для записи. Они являются обычными файлами в смысле ПЛ/1, от-
крываемыми для чтения или записи, соответственно. Записанная на
этом языке программа может читать (или писать) следующую запись,
которая представляет кортеж поддерживаемого в этом файле отноше-
ния, в (или из) объект данных ПЛ/1, являющийся структурой. Чита-
тель должен представить себе, как написать программы на языке ПЛ/1
для вычисления агрегатных операторов, подобных сумме или среднему,
для удаления или модификации кортежей любым специфицированным
способом либо для чтения кортежей из входного файла (не обязательно
реляционного файла для чтения; он может быть, например, термина-
лом) и добавления их к отношению.
4.5. SQUARE И SEQUEL: ЭВОЛЮЦИОННЫЕ ШАГИ
ОТ АЛГЕБРАИЧЕСКИХ ЯЗЫКОВ
К ЯЗЫКАМ ИСЧИСЛЕНИЯ
Создание языка SQUARE было первым шагом в разработке языка за-
просов для СУБД System-R, реализуемой исследовательской лабораторией
ИБМ в Сан-Хосе. Его дальнейшее развитие привело к появлению языка,
названного SEQUEL, который подобен SQUARE с точки зрения идеологии,
120
но имеет синтаксис, напоминающий реляционное исчисление с переменны-
ми-кортежами. Мы обсудим эволюцию SQUARE в SEQUEL после рассмот-
рения основных идей языка SQUARE.
SQUARE сам по себе обладает рядом возможностей, которых нет в чис-
то реляционной алгебре, например способностью именовать кортежи в от-
ношениях или сравнивать множества с помощью условий вида с. Операто-
ры объединения и разности в SQUARE выражаются так же, как в реляци-
онной алгебре. Таким же образом интерпретируется пересечение. Декарто-
во произведение R и S выражается как
г € R, s G S.
Проекция отношения R на атрибуты Alt Л2, ..., Ап записывается следую-
щим образом:
Л,, ...AnR’
Селекция представляется не так, как в реляционной алгебре, а скорее
в стиле исчисления с переменными-кортежами. Выражение op (R) в
SQUARE имеет вид
г € R:F',
где F' есть F, в котором г а замещает атрибут А или номер компонента это-
го атрибута в F.
Мы можем утверждать, что SQUARE является полным языком, по-
скольку в нем существуют возможности присваивания вычисленного отно-
шения имени другого отношения. Для этого может быть использован опе-
ратор присваивания ч-. Присваивание
Rav а2...лп *- (выражение),
где<выражение> обозначает n-компонентное отношение, вызывает вычис-
ление выражения и присваивание результата имени отношения R. Атрибу-
ты этого отношения получают далее имена А1г Аг, .... Ап, Таким образом,
если в языке нет каких-либо более удобных возможностей, можно вычислять
любое реляционное выражение, применяя последовательно по одному опе-
ратору и присваивая результат имени временного отношения. Заметим, что
в отличие от ISBL присваивание в SQUARE всегда предполагает непосред-
ственное вычисление. Отложенные вычисления не допускаются.
Отображения
Одной из центральных возможностей SQUARE является отображение —-
специальный вид селекции с последующей проекцией. Общий вид отобра-
жения
Аа...Ап Rbv в2...вт(01Ь1, е2Ьг,.... Gmbm),
где R — имя отношения, Аг и Bj — атрибуты R, 0г — оператор сравнения
(=, #=,<, > или ^), за которым следует константа Если 0г- опуще-
но, подразумевается оператор Это отображение означает
ПА1- А2..Ап <aWl Л-Л Вт embm (R)).
Можно конструировать композиции отображений, используя опера-
тор о . Композиция позволяет, как нетрудно видеть, выполнять эквисоеди-
нение отношений. Поэтому отображение в большой степени воплощает в
себе суть реляционной алгебры —- «селекцию-проекцию-соединение».
121
Пример 4.13. Первый запрос из примера 4.12 может быть выражен в
SQUARE как
ФАМИЛИЯ ЧЛЕНЫ БАЛАНС ( < °)’
а второй — как
назв_пост.товар,цена ПОСТАВЩИ КИТОВАРоТОВАр ЗАКАЗЫФАМИлия(«Брукс»)
Сначала используется отображение справа, и оно продуцирует множество товаров,
заказанных Бруксом. Отметим, что перед фамилией «Брукс» подразумевается опера-
тор равенства, поскольку не представлен никакой иной оператор. Далее второе отобра-
жение определяет кортежи в отношении ПОСТАВЩИКИ с одним из таких товаров в
третьем компоненте и продуцирует первый, третий и четвертый компоненты этих кор-
тежей.
Свободные переменные
Так же как реляционное исчисление с переменными-кортежами,
SQUARE допускает переменные-кортежи, называемые свободными перемен-
ными. Мы уже встречали свободные переменные в формулах для декартова
произведения и селекции. В SQUARE свободные переменные могут быть ин-
дексированы списком имен атрибутов для того, чтобы указать, какие ком-
поненты представляемого этой переменной кортежа должны быть взяты. Сле-
дующее выражение в SQUARE можно считать аналогом выражения реля-
ционного исчисления с переменными-кортежами:
...Ох^Я^Ф- (4.4)
Здесь tt — свободная переменная, обозначающая некоторый кортеж в R;;
at — список атрибутов Rt, которые мы хотим печатать. Если at опущено,
то подразумевается список всех атрибутов R{. Формула ф содержит опе-
ранды— константы или переменные из числа tit возможно, индексиро-
ванные произвольными списками атрибутов.
Формула (4.4) имеет следующий смысл:
{иКз ti) - (3 *к) (Ri (h) Л -Л Кл (4) Л ® Л Ш
где а> означает, что и [/] = /,• [т], если i и т выбраны так, что сумма длин
списков alt а2, ..., плюс т равна j и длина а, не превышает т. Иными
словами, формируем список компонентов, представленный (fja,, затем спи-
сок компонентов, представленный (?2)а,, и т. д. При этом j-й компонент и
равен /-му компоненту этого списка. Вид <о и (^) гарантируют безопас-
ность этого выражения, поскольку в ф не допускаются кванторы.
К числу операторов, которые могут быть использованы в ф, относятся
ранее определенные отображения, алгебраические операции и, Г) и —, бу-
левские операторы, арифметические операторы и сравнения, а также срав-
нения множеств (=,#=» ^ и т- Д-)-
Пример 4.14. Первый запрос из примера 4.12 может быть записан со свобод-
ными переменными как
* фамилия € ЧЛЕНЫ: t баланс < °-
122
Второй запрос не выражается достаточно удобным способом с использованием
свободных переменных. Однако третий запрос о поставщиках, которые поставляю!
каждый товар, заказанный Бруксом, может быть выражен кратко следующим образом:
^нлзв^пост € ПОСТАВЩИКИ: (товар ЗАКАЗЫ фдмилия («Брукс»)
—ТОВАР ПОСТАВЩИКИ нАЗв_пост (^назв_.ПОСТ ))
Здесь товар ЗАКАЗЫ фамилия(<Брукс>) — отображение, которое формирует мно-
жество товаров, заказанных Бруксом. ОтображениетоварПОСТАВЩИКИназв пост
(^НАЗВ пост) дает множество товаров, поставляемых поставщиком, название ко-
торого задано компонентом НАЗВ_ПОСТ кортежа s. Следовательно, формула справа
от двоеточия истинна в точности тогда, когда поставщик, указанный в кортеже s, по-
ставляет все товары, заказанные Бруксом. Поскольку областью определения «служит
множество всех кортежей в отношении ПОСТАВЩИКИ, выражение вызывает печать
всех поставщиков, которые поставляют все товары, заказанные Бруксом.
В качестве последнего примера заметим, что приведенное ранее выражение для
/? X S
г с я, s е s
является специальным случаем выражения со свободными переменными, где форму-
ла ф опущена и, следовательно, рассматривается как тождественно истинная. Таким
образом, печатается конкатенация каждого кортежа, принадлежащего /?, с каждым
кортежем, принадлежащим S.
Операторы включения, удаления
и модификации кортежей
Для того чтобы включить кортеж в отношение R, следует записать
| Ra,...ап («1, .... ап), где ..., Ап — список некоторых или всех атри-
бутов схемы отношения R и at — значение атрибута А, в новом кортеже.
Компоненты нового кортежа, соответствующие атрибутам R, не перечислен-
ным среди А1г Ап, имеют неопределенное значение.
Пример 4.15. Кортеж («Веселый», «Проезд Голубого Неба, 29», 0) может
быть добавлен к отношению ЧЛЕНЫ из примера 4.12 оператором SQUARE:
| ЧЛЕНЫ («Веселый», «Проезд Голубого Неба, 29», 0)
ФАМИЛИЯ, АДРЕС, БАЛАНС
Имеется также возможность записать
| Rax...ап «выражение»,
где значение<выражения> представляет собой n-арное отношение S. Этот
оператор дает точно такой же результат, как и последовательность опера-
торов
...ап (Я1,ап),.
где (аи ..., ап) пробегает все кортежи в S.
Оператор удаления имеет синтаксис, аналогичный синтаксису опера-
тора включения, но вместо | используется f.
Оператор .......«д, ..., ап) удаляет из R все кортежи, в которых
компоненты Лг равны аг для каждого i — 1, ..., ri. Команда
f ......ап «выражение»,
где <выражение> вычисляет некоторое n-арное отношение S, удаляет из
R все кортежи, которые совпадают с некоторым кортежем S в компонен-
тах ..., Ап.
123
Пример 4.16. Если «Корпорация вкусных продуктов» прекращает продажу
салата, мы можем обновить базу данных из примера 4.12:
f ПОСТАВЩИКИ ндзв пост товар («Корп. вкусных продуктов», «Салат»)
При этом из отношения ПОСТАВЩИКИ будет удален кортеж:
(«Корп. вкусных продуктов», «Речная улица, 17», «Салат», 0,79)
Если нужно аннулировать заказы членов кооператива с отрицательными баланса-
ми, можно использовать для их обозначения выражение фамИЛИяЧЛЕНЫбддднс
(<0). Множество — это унарное отношение. Поэтому мы можем считать его аргу-
ментом удаления. Тогда
t ЗАКАЗЫ фамилия (фамилия ЧЛЕНЫваланс ( < °))
Для модификации применяется следующий синтаксис:
~.... Ап; .... Вт (^li •••, ап’ ^1» ••> Ьт)‘
Здесь Alt ..., Ап и Blt Вт представляют собой (не обязательно не
пересекающиеся) списки атрибутов отношения /?. Атрибутам Bit но не At,
могут предшествовать арифметические операторы +, —, х или /. Величи-
ны at, bj являются константами. Оператор модификации вызывает поиск
кортежей в /?, компоненты At которых равны at для всех i = 1, .... п. Для
каждого такого кортежа он заменяет компонент Bt величиной bt для
1 i пг. Если, однако, Bt предшествует арифметический оператор а
старое значение с компонента Bt замещается на caftj. Например, +Bt вызы-
вает замену с на c+bt.
Пример 4.17. Чтобы установить в 0 баланс Харта, напишем
-» ЧЛЕНЫ фамилия; баланс («Харт», 0)
Если Робин уплатил 200 дол., мы можем увеличить его баланс иа эту сумму сле-
дующим образом:
-» ЧЛЕНЫ фамилия; + баланс («Робин», 200)
Если корпорация «Натуральные продукты» снижает цену на сметану наполовину, мы
можем написать
-* ПОСТАВЩИКИ Ндзв пост, товар;/ценА («Натуральные продукты», «Сметана»,2)
Агрегатные функции
К совокупности значений в некотором множестве (к унарному отноше-
нию) могут быть применена! такие функции, как COUNT (число значений),
AVG (среднее значение), SUM (сумма), MIN (наименьшее значение), МАХ
(наибольшее значение). Еслй требуется, например, определить чистый ба-
ланс всех членов кооператива, мы можем написать
^(баланс ЧЛЕНЫ')
Другой пример: если нужно найти поставщика или поставщиков, уста-
новивших наименьшую цену на карамель, мы пишем
^идзв ПОСТ ПОСТАВЩИКИ: ^товар «Кзрамель»
Лецена “ MIN (цена ПОСТАВЩИКИ у^вдр («Карамель»))
Читатель может заметить знак «прим» в первой из этих формул. Его
присутствие должно напомнить SQUARE, что нужно различать два иден-
тичных элемента, когда он производит вычисления на множестве. Если бы
мы написали
зиМ(БдЛднс ЧЛЕНЫ),
то балансы членов кооператива, случайно оказавшиеся одинаковыми, были
бы учтены в сумме только один раз. Знак «прим» указывает, что результат
отображения балансЧЛЕНЫ должен быть мультимножеством, в котором
допускаются повторения, а не обычным множеством, где повторения исклю-
чены.
Язык запросов SEQUEL
Одна из проблем языка SQUARE заключается в том, что в его синтак-
сисе присутствуют нижние индексы. Несмотря на то что мы можем разрабо-
тать синтаксис, который предусматривает запись в строку (и мы должны это
сделать для использования ЭВМ), такой синтаксис нельзя считать привлека-
тельным. В отличие от SQUARE в SEQUEL применяются ключевые слова
для указания роли имен отношений и атрибутов.
At...Ап .....Вт (01 &1» —> 0m М
выражается в SEQUEL следующим образом:
SELECT А,, .... Ап
FROM Л
WHERE BiOibiA-ABmOmbm
Напомним, что если Bt опущено в отображении SQUARE, то предпола-
гается оператор сравнения =. Таким образом, первый запрос из примера
4.12 может быть записан в виде
SELECT ФАМИЛИЯ
FROM ЧЛЕНЫ
WHERE БАЛАНС<О
В том случае, если выбран такой стиль представления отображений,
могут быть до некоторой степени ослаблены ограничения, которым подчи-
няется WHERE. В языке SEQUEL за WHERE может следовать любое вы-
ражение, включающее атрибуты отношения, указанного после FROM, ариф-
метические сравнения и операции, булевские связки (AND, OR и NOT), опе-
рации. надмножествами (UNION—объединение, INTERSECT—пересечение
и MINUS—разность), символ принадлежности множеству (X IN S, где S —
множество, или эквивалентная запись S CONTAINS X), а также отрицания
125
принадлежности множеству (X NOT IN S или S DOES NOT CONTAIN X).
Те же самые операторы могут обозначать включение множеств, если X яв-
ляется множеством, а не элементом или кортежем. Выражение, следующее
за WHERE, может содержать также операнды, которые представляют собой
отношения, сформированные другим предложением SELECT-FROM-
WHERE.
Пример 4.18. Чтобы напечатать названия и адреса поставщиков, которые
поставляют творог или сметану, запишем
SELECT UNIQUE НАЗВ-ПОСТ АДРЕС-ПОСТ
FROM ПОСТАВЩИКИ
WHERE ТОВАР = 'творог' OR ТОВАР = 'сметана'
Здесь после SELECT требуется слово UNIQUE (уникальный), поскольку в от-
личие от SQUARE, когда в SEQUEL используется отображение, оно не устраняет дуб-
ликаты, если необходимость в этом не указана ключевым словом UNIQUE. Без
указания UNIQUE по этому запросу дважды печаталось бы «Натуральные продукты»,
поскольку эта корпорация поставляет и творог, и сметану.
Композиция отображений достигается благодаря использованию вложенных пред-
ложений SELECT-FROM-WHERE и оператора IN принадлежности множеству. Таким
образом, второй запрос из примера 4.12 в SEQUEL имел бы вид
SELECT UNIQUE НАЗВ-ПОСТ, ТОВАР, ЦЕНА
FROM ПОСТАВЩИКИ
WHERE ТОВАР IN
SELECT ТОВАР
FROM ЗАКАЗЫ
WHERE ФАМИЛИЯ = 'Брукс'
Язык SEQUEL обладает двумя средствами, которые подобны выраже-
ниям со свободными переменными SQUARE. Во-первых, мы можем дать не-
которое имя Т типичному кортежу отношения R. Для этого нужно написать
SELECT...FROM R Т WHERE...
Тогда внутри предложения WHERE можно ссылаться на значение компо-
нента А кортежа Т с помощью Т. А.
Пример 4.19. Чтобы напечатать фамилии всех членов кооператива, которые
заказали не менее десяти фунтов продуктов, мы можем записать
SELECT ФАМИЛИЯ
FROM ЧЛЕНЫ Т
WHERE 10 < =
SELECT SUM (КОЛИЧЕСТВО)
FROM ЗАКАЗЫ
WHERE ФАМИЛИЯ = Т.ФАМИЛИЯ
Здесь SUM —• агрегатная функция, как и в языке SQUARE. В предложении
WHERE ФАМИЛИЯ = Т. ФАМИЛИЯ атрибут ФАМИЛИЯ ссылас.ся на компонент
ФАМИЛИЯ отношения ЗАКАЗЫ, в то время как Т. ФАМИЛИЯ ссылается на компо-
нент ФАМИЛИЯ кортежа Т отношения ЧЛЕНЫ. Будет напечатан следующий резуль-
тат:
Брукс
Роби и
Третий запрос из примера 4.12 может быть записан в виде, представленном на
рис. 4.9.
126
SELECT НАЗВ.ПОСТ
FROM ПОСТАВЩИКИ T
WHERE
(SELECT ТОВАР
FROM ПОСТАВЩИКИ
WHERE НАЗВ_ПОСТ = T. НАЗВ_ПОСТ)
CONTAINS
(SELECT ТОВАР
FROM ЗАКАЗЫ
WHERE ФАМИЛИЯ = 'Брукс')
Рис. 4.9. Запрос в языке SEQUEL
Другое средство языка SEQUEL, которое может быть использовано по-
добно свободным переменным в SQUARE, — способность оперировать бо-
лее чем одним отношением в предложении FROM. На значения атрибутов
любого из отношений, указанных в предложении FROM, можно ссылаться
как в предложении SELECT, так и в предложении WHERE. Если А является
атрибутом более одного отношения и в этой связи возникает потенциальная
двусмысленность, следует использовать /?.Л, указывая тем самым, что име-
ется в виду атрибут А из отношения R.
При наличии в запросе предложения FROM R1( ..., Rn будут рассмат-
риваться все списки tlt .... tn кортежей, где tt берется из 7?;. Если данный
список удовлетворяет условиям, указанным в предложении WHERE, в ре-
зультат оператора включается список компонентов, специфицированных в
предложении SELECT.
Пример 4.20. Соединение отношений можно произвести, перечисляя их
в предложении FROM и помещая необходимые соотношения между атрибутами в пред-
ложении WHERE. Таким образом, второй запрос из примера 4.12 может быть записан
следующим образом:
SELECT НАЗВ_ПОСТ, ПОСТАВЩИКИ.ТОВАР, ЦЕНА
FROM ПОСТАВЩИКИ, ЗАКАЗЫ
WHERE ФАМИЛИЯ = 'Брукс' AND
ПОСТАВЩИКИ.ТОВАР = ЗАКАЗЫ.ТОВАР
Заметим, что, так как ТОВАР входит в оба отношения ПОСТАВЩИКИ и ЗАКАЗЫ,
он должен быть квалифицирован отношением, из которого он берется. Другие атрибу-
ты входят лишь в одно из двух отношений, и их не нужно квалифицировать.
В качестве другого примера мы можем взять декартово произведение отношений
R и S с помощью оператора
SELECT*
FROM R, S
Символ ’обозначает все компоненты всех отношений, следующих за FROM.
Операции включения, удаления и модификации в SEQUEL являются
синтаксически улучшенной версией соответствующих операций SQUARE
так же, как конструкция SELECT-FROM-WHERE является синтаксичес-
ки улучшенной версией отображения из языка SQUARE. Эти операции
здесь не рассматриваются.
Полнота SEQUEL
В примере 4.20 мы видели, как вычислить декартово произведение.
Объединение и разность множеств могут быть выполнены с помощью опе-
раций UNION и MINUS, Например, объединение R и S есть
127
(SELECT*
FROM R)
UNION
(SELECT*
FROM S)
Очевидно, что конструкция SELECT-FROM-WHERE включает как
операцию селекции, так и операцию проекции реляционной алгебры. При-
сваивание в SEQUEL указывается путем записи перед запросом предложе-
ния
ASSIGN ТО R:
если мы желаем присвоить результат отношению R. Таким образом, в
SEQUEL имеются средства для вычисления любого выражения реляцион-
ной алгебры, позволяющие последовательно применять по одному операто-
ру и вычислять посредством этого каждое подвыражение. Следовательно,
SEQUEL обладает свойством полноты.
SEQUEL и System R
Как уже упоминалось, SEQUEL является основным языком запросов
экспериментальной СУБД System R. При этом SEQUEL может приме-
няться как «самостоятельный» язык запросов, средствами которого пользова-
тель просто выражает запросы и обновления базы данных, и эти операции
выполняются непосредственно System R. Возможно, однако, также встро-
ить SEQUEL-запросы в программы, записанные в языке программирования
ПЛ/1. Операторы SEQUEL снабжаются префиксом *, и препроцессор транс-
лирует их в операторы CALL, входящие в окружающую программу. Эти
операторы вызывают процедуры, предоставляемые System R. Например,
процедура с именем SEQUEL использует в качестве аргумента литерную
строку, представляющую текст самого запроса, и вызов этой процедуры при-
водит к тому, что эта строка интерпретируется и выполняется.
В том случае, когда ПЛ/1 служит включающим языком, SEQUEL-за-
просы могут содержать переменные окружающей программы. Мы можем,
например, написать программу, которая читает название товара / и затем
печатает всех поставщиков / с помощью встроенного в нее SEQUEL-запро-
са:
SELECT НАЗВ.ПОСТ
FROM ПОСТАВЩИКИ
WHERE ТОВАР = /
Используя некоторый механизм, который мы не будем здесь детально
обсуждать, можно осуществить выборку результата запроса последователь-
но по одному кортежу в определенную переменную окружающей програм-
мы.
Реализация отношений в System R
Обсуждение SEQUEL мы завершим рассмотрением способа хранения
отношений в System R. Этот материал не относится исключительно к
SEQUEL, поскольку все данные в системе хранятся одним и тем же спосо-
бом, независимо от используемого языка запросов, a System R проектиро-
валась для поддержки множества языков запросов, включая языки, не ос-
нованные на реляционной модели данных.
128
System R распределяет кортежи отношения между страницами разме-
ром по 4096 байт, которые играют роль блоков, описанных в гл. 2. На стра-
нице могут содержаться кортежи нескольких отношений, и иногда это вы-
годно делать. В распоряжении администратора базы данных имеются три
инструмента, позволяющие ему добиваться эффективного исполнения тех
запросов, которые, по его предположению, встречаются чаще других.
1. Кортежи из двух различных отношений могут быть сгруппированы
вместе на некоторых страницах. Цель такого их размещения — сделать эф-
фективной обработку предполагаемых связей между отношениями (вида
«многие к одному», как в сетевой модели). Эффективность достигается за
счет ограничения числа страниц, перемещаемых в основную память при об-
работке запроса. Например, существует предполагаемая связь между кор-
тежами отношений ЧЛЕНЫ и ЗАКАЗЫ в примере 4.12. Кортеж каждого
Рнс. 4.10. Использование косвенности
в страницах
Идентификатор
кортежа 2
Яыоает
1 --------
члена кооператива может рассматриваться как связанный с теми кортежами
отношения ЗАКАЗЫ, которые представляют заказы данного члена коопе-
ратива. Предполагаемая связь может быть представлена совокупностью
записей переменной длины формата ЧЛЕНЫ (ЗАКАЗЫ)*. Всегда, когда
имеется место, мы можем реализовать эту связь путем хранения кортежа от-
ношения ЗАКАЗЫ с заданным значением атрибута ФАМИЛИЯ на той же
странице, где будет храниться кортеж из отношения ЧЛЕНЫ с тем же зна-
чением ФАМИЛИЯ-
2. Мы можем создать индекс для отношения по любой совокупности его
атрибутов. Он может быть организован как плотный индекс, описанный в
разд. 2.5, со структурой В-дерева. Внутренние узлы этогоВ-дерева представ-
ляют собой страницы, заполненные парами, состоящими из указателей на
другие страницы и ассоциированных с ними значений атрибутов, по которым
определяется индекс. Узлы, являющиеся листьями, состоят из значений та-
ких атрибутов и связанных с ними списков идентификаторов кортежей.
Существует один идентификатор кортежа в списке для каждого кортежа,
имеющего заданные значения атрибутов из индекса. Идентификаторы кор-
тежей являются, по существу, указателями на кортежи, но они обеспечива-
ют некоторую степень косвенности. Фактически идентификаторы кортежей
указывают на некоторое место в нижней части страницы, где может нахо-
диться сам указатель на кортеж. Подобная организация допускает уплот-
нение кортежей на странице, когда производятся их включения и удаления1.
Действительно, такая степень косвенности позволяет интерпретировать кор-
тежи как незакрепленные записи, даже если на них ссылаются указатели
из В-дерева. На рис. 4.10 показан пример страницы.
3. Для соединения некоторого кортежа t в отношении R с кортежами
в отношении S, имеющими такие же значения для определенного списка
1 В SystemR кортежи могут иметь переменную длину. Поэтому не всегда возмож-
но оставлять кортежи там, где они находятся, без потери пространства памяти.
5 Зак. 1315 129
атрибутов, какие имеет для соответствующего списка атрибутов кортеж t,
могут использоваться связи. Отношение может участвовать в любом числе
связей. Такая организация подобна структуре мультисписков, описанной
в разд. 3.2. При этом для каждого принадлежащего R кортежа t предусмат-
ривается цепочка указателей, которая начинается в этом кортеже, соединяет
ассоциированные с ним кортежи из S и возвращается к t. Напомним, что все
указатели являются идентификаторами кортежей и указывают на кортежи
косвенным образом, как на рис. 4.10.
ЧЛЕНЫ
ФАМИЛИЯ АДРЕС____________БАЛАНС СВЯЗЬ
Вруне Яблочное шоссе, Т 20,50
Филд Вишневый пеоеилок, АЗ 0
Робин вересковая улица. 13, . -123, А5
Харт жаворонковое шоссе. 65 - АЗ, 00 •
ФАМИЛИЙ ТОВАР КОЛИЧЕСТВО СВЯЗЬ
Брунс Карамель 5
Брукс Муна 10
Робин Карамель 3
Харт Сметана 5
Робин Фасоль 2
Робин Салат В
ЗАКАЗЫ
Рис. 4.11. Пример связи
Пример 4.21. Предположим, что требуется использовать связь, которая
ассоциирует членов кооператива с их заказами. Представим себе, что отношения
ЧЛЕНЫ и ЗАКАЗЫ, приведенные на рис. 4.7, размещены каждое на одной странице.
Связь от ЧЛЕНЫ к ЗАКАЗЫ, основанная на равенстве полей ФАМИЛИЯ, схематиче-
ски показана на рис. 4.11. Однако читатель должен помнить, что все указатели в дейст-
вительности являются идентификаторами кортежей и указывают на место в нижней ча-
сти страницы, где находится сам указатель на этот кортеж.
4.6. QUEL: ЯЗЫК РЕЛЯЦИОННОГО ИСЧИСЛЕНИЯ
С ПЕРЕМЕННЫМИ-КОРТЕЖАМИ
QUEL — это язык запросов INGRES реляционной СУБД, разработан-
ной в Калифорнийском университете в Беркли. Он обладает весьма разви-
тым синтаксисом, представляющим широкий спектр операторов исчисле-
ния с переменными-кортежами.
Оператор исчисления
{«(r) I (до - (дМ (Ri (ti) A ... A R* (th)
A « m=h. l/d A... A u И = hr IM А Ф} (4.5)
130
устанавливает, что tt принадлежит Rt и и образуется из г отдельных компо-
нентов ti, а также формулирует некоторое дополнительное условие ф. Если
ф — произвольная формула исчисления с переменными-кортежами без кван-
торов, то оператор (4.5) может быть записан в языке QUEL следующим об-
разом:
range of /j is
range of th is
retrieve (//j^.Aj. itj.. Ar)
where ф'
Здесь Am является /т-м атрибутом отношения Rtm, m = 1,2, ..., k, a
Ф' — результатом перевода условия ф в форму выражения QUEL. Чтобы
выполнить такой перевод, необходимо:
1. Заменить ссылки в ф на компонент и [т] ссылкой на ti [jmI. Заме-
тим, что и [т] и tim l/m] равны в соответствии с формулой (4.5).
2. Заменить каждую ссылку на tm [п] величиной tm.В, где В представ-
ляет собой n-й атрибут отношения Rm для любых п и т.
3. Заменить на<=, на > и на! =.
4. Заменить Д, у, на «and (и)», «ог (или)», «not (нет)» соответствен-
но.
Интуитивный смысл оператора
range of t is /?
заключается в том, что любые последующие операции должны быть выпол-
нены по одному разу для каждого принадлежащего/? кортежа при t, равном
поочередно каждому из этих кортежей. Эта декларация имеет силу до тех
пор, пока t не будет переопределено другим оператором range.
Оператор выборки retrieve печатает таблицу с именами столбцов
Ait, ..., Aik. Если мы желаем назначить столбцу т иное имя, скажем, ЗА-
ГОЛОВОК, то следует написать ЗАГОЛОВОК = ti -At вместо// А;
J тп гт т т-
Пример 4.22. Первый запрос из примера 4.12 записывается следующим
образом:
range of t is ЧЛЕНЫ
retrieve (t. ФАМИЛИЯ)
where t. БАЛАНС < 0
Второй запрос из этого примера может быть записан в виде
range of t is ЗАКАЗЫ
range of s is ПОСТАВЩИКИ
retrieve (s. НАЗВ_ПОСТ, s.ТОВАР, s.IJEHA)
where t.ФАМИЛИЯ = «Брукс» and
t.TOBAP = s. ТОВАР
Поскольку ф в выражении (4.5) не содержит кванторов, легко пока-
зать, что это выражение всегда является безопасным. Оно не имеет однако
достаточно общего вида и не позволяет, в частности, выразить объединение
или разность отношений. К счастью, в QUEL предусмотрен оператор уда-
ления delete, который наряду с другими функциями позволяет вычислять
разность множеств. Можно написать:
range of t is R
delete t
where 4>(t)
5*
131
Здесь ф (0 — выражение в языке QUEL, подобное тем, которые могут
следовать за «where» в операторе retrieve. Действие данного оператора
delete заключается в том, чтобы удалить из 7? все кортежи t, удовлетворяю-
щие ф.
Аналогично этому QUEL имеет оператор присоединения (append), ко-
торый позволяет вычислять объединение отношений и решать ряд других
задач. Запишем, напрймер:
range of 4 is Rx
range of tk is Rk
append to S (At = <olt ..., An = <on)
where ip tk)
Здесь, как и выше, ф — выражение в языке QUEL, а <о{ — выражения,
в которые входят компоненты из t( и (или) константы, соединенные арифме-
тическими операторами. При каждом присваивании переменным-кортежам
tt значений, таких, что ф (t1( ..., tk) — истинно, к отношению S добавляет-
ся кортеж, компонентом которого для атрибута Ар является значение <ор,
р = 1,2, ..., п. Например, если мы хотим добавить заказ на 10 фунтов тво-
рога для каждого члена кооператива с неотрицательным балансом, то сле-
дует написать:
range of t is ЧЛЕНЫ
append to ЗАКАЗЫ (ФАМИЛИЯ = t-ФАМИЛИЯ,
ТОВАР = «творог», КОЛИЧЕСТВО = 10)
where ЕБАЛАНС>0
Отметим, что предложение where не является обязательным в операторе
append, и этот оператор в действительности используется обычно без каких-
либо переменных-кортежей для целей присоединения к отношению единст-
венного кортежа.
Мы еще не готовы, однако, моделировать любое выражение реляцион-
ной алгебры в QUEL. Необходимо для этого также иметь возможность при-
сваивать значения новым отношениям. Если S — имя нового отношения,
то можно написать:
range of 4 is Ry
range of tk is Rk
retrieve into S (Лх = <0i,..., An = <on)
where ..., th)
Этот оператор будет находить все списки кортежей tlf ..., th, такие, что
it принадлежит Rt и ф (^...tk) — истинно, и создавать для нового отно-
шения S кортеж, i-м компонентом которого является (of. Здесь — фор-
мула того же вида, как в операторе append.
Имена атрибутов Alt ..., Ап становятся именами компонентов S. Если
ail имеет вид ^-.ФАМИЛИЯ, можно опустить «At — ». Тогда ФАМИЛИЯ
становится именем i-ro атрибута S.
Пример 4.23. QUEL подобно языку SEQUEL не предусматривает автома-
тического удаления дубликатов при вычислении отиошеиия. Предположим, что мы
хотим напечатать название НАЗВ_ПОСТ и адреса АДРЕС_ПОСТ всех поставщиков.
Мы могли бы тогда написать
range of t is ПОСТАВЩИКИ
retrieve (t.HA3B_nOCT, /.АДРЕС-ПОСТ)
132
Но тогда каждый поставщик печатался бы столько раз, сколько товаров он по-
ставляет. В QUEL, однако, предусмотрена команда сортировки sort для устранения
дубликатов в то время, когда она будет сортировать отношение сначала по первому
компоненту, затем — по второму для кортежей с одинаковым первым компонентом
и т. д. Для того чтобы каждый поставщик печатался только одни раз и чтобы все они
печатались в алфавитном порядке, нужно написать
range of t is ПОСТАВЩИКИ
retrieve into НЕНУЖНОЕ (ФАМИЛИЯ = 1.НАЗВ_ПОСТ, АДРЕС=Е
АДРЕС-ПОСТ)
sort НЕНУЖНОЕ
print НЕНУЖНОЕ
Столбцы отношения НЕНУЖНОЕ будут иметь заголовки ФАМИЛИЯ и АД-
РЕС.
Полнота QUEL
Теперь мы знаем, как создавать временные отношения. Поэтому для
вычисления любого выражения реляционной алгебры достаточно показать
применение пяти основных операторов. Будем предполагать далее, что име-
ются отношения 7? (Ль ..., Лп) и S (Вь ..., Вп) и что Т — имя нового от-
ношения. Чтобы вычислить Т = 7? и *$ в предположении, что m — п, сле-
дует написать:
range of г is R
append to T (Cx = r.At.... Cn = r.An)
range of s is S
append to T (Сг = s.B±.... Cn = s.Bn)
Вычисление T = R — S можно осуществить так:
range of r is 7?
append to T (Ct = r. .... Cn — r. An)
range of s is S
range of t is T
delete t
where s. Br = t. Cx and... and s. Bn — t. Cn
Если нужно вычислить T — R X S, используется последовательность
операторов:
range of г is R
range of s is S
append to T (Ci = r.Alt..., Cn — r.An,
Cn+i = s. 7?i...... Crt+m = s.Bm)
Для вычисления селекции oF (R) можно записать:
range of r is R
append to T (Cx = r. Alt..., Cn = r. An)
where F'
3jue.ci> F' представляет собой переведенную в нотацию QUEL формулу
F (компонент i отношения R становится r.At, Д становится «and» и т. д.).
Наконец, чтобы выразить проекцию ф/,......ik (R), запишем
range of г is R
append to T (Cx = r. Atl...... Ch = r. Aih)
133
Пример 4.24. Третий запрос из примера 4.12 можно представить в QUEL,
следуя формуле реляционной алгебры, выведенной в этом примере. Напишем сначале
программу для вычисления множества пар поставщик—товар:
range of s is ПОСТАВЩИКИ
range of i is ПОСТАВЩИКИ
retrieve into ФИКТИВНЫЙ (S = s.HA3B_nOCT, I = i.ТОВАР)
Теперь должны следовать операторы, которые удаляют из отношения ФИКТИВ-
НЫЙ такие пары поставщик—товар (S, /), что S поставляет /. В результате получим
такие пары (S, /), что S не поставляет /.
range of s is ПОСТАВЩИКИ
range of t is ФИКТИВНЫЙ
delete t
where t. S = s. НАЗВ_ПОСТ and t. I = s.TOBAP
Далее создаем отношение нз пар (S, /), таких, что S является каким-либо постав-
щиком, а I не поставляется S, ио товар I заказан Бруксом. Для этого пишем:
range of г is ЗАКАЗЫ
range of t is ФИКТИВНЫЙ
retrieve into НЕНУЖНОЕ (S = t.S, I = t.I)
where г. ФАМИЛИЯ = «Брукс» and г. ТОВАР = t.I
Перечисляем затем только тех поставщиков, которые не входят в качестве перво-
го компонента кортежа в НЕНУЖНОЕ. Для получения множества поставщиков за-
пишем:
range of s is ПОСТАВЩИКИ
retrieve into МНОЖЕСТВО _ ПОСТ (S = s.HA3B_nOCT)
Чтобы, наконец, напечатать желаемое множество, нужно написать:
range of u is МНОЖЕСТВО_ПОСТ
range of j is НЕНУЖНОЕ
delete и
where U.S = j.S
sort МНОЖЕСТВО_ПОСТ
print МНОЖЕСТВО_ПОСТ
Хотя построенная программа в языке QUEL выглядит довольно громоздкой, ее
можно значительно упростить, если предположить, что операторы range объявляют не-
которое отношение областью изменения переменной «навсегда» или до тех пор, пока не
будет задан другой оператор range для указанной переменной. При этом можно опу-
стить некоторые операторы range и записать программу в языке QUEL так, как она
представлена на рис. 4.12.
range of s is
range of i is
retrieve into
range of t is
delete t
ПОСТАВЩИКИ
ПОСТАВЩИКИ
ФИКТИВНЫЙ (S = s.НАЗВ_ПОСТ, I = i.ТОВАР)
ФИКТИВНЫЙ
where t.s = S. НАЗВ-ПОСТ and t.I = s.TOBAP
range of г is ЗАКАЗЫ
retrieve into НЕНУЖНОЕ (S = t.S, I = t.I)
where г. ФАМИЛИЯ = «Брукс» and г.ТОВАР = t.I
retrieve into МНОЖЕСТВО-ПОСТ (S = s. НАЗВ-ПОСТ)
range of u is МНОЖЕСТВО-ПОСТ
range of j is НЕНУЖНОЕ
delete u
where U.S = j.S
sort МНОЖЕСТВО-ПОСТ
print МНОЖЕСТВО-ПОСТ
Рис. 4.12. Программа на языке QUEL для третьего запроса
134
Агрегатные операторы
В языке QUEL, как и в SQUARE или SEQUEL, используются агрегат-
ные функции: сумма sum, среднее avg, счетчик count, минимум min и мак-
симум max. Аргументом таких функций может быть любое выражение, со-
держащее компоненты одного отношения, константы и арифметические опе-
раторы. Все компоненты должны указываться как t.A для переменной-кор-
тежа t и различных атрибутов А. Например, если нам нужно получить
суммарный баланс всех членов кооператива в Счастливой Долине, мы
должны написать:
range of t is ЧЛЕНЫ
retrieve (sum (t. БАЛАНС))
Мы можем также разбить кортежи отношения на группы в соответствии
со значением одного или более выражений, вычисляемых над отдельным
кортежем, и вычислить агрегаты для каждого множества кортежей, имею-
щих общие значения указанных выражений1. Для получения такого раз-
биения следует записать:
ag_op (Е by Fj_, F2, ..., Fh), (4.6)
где E и Ft — выражения, операндами которых являются константы и ком-
поненты t.A для одной переменной-кортежа t. Операнды в выражении могут
соединяться арифметическими операторами. Если t определено на R, значе-
ние (4.6) для заданного значения t вычисляется путем нахождения всех тех
кортежей/?, которые принимаютто же самое значение, что и ^для/д, ..., Fh.
Далее агрегатный оператор ag_op применяется к значению Е для каждого
из таких кортежей.
Пример 4.25. Чтобы напечатать поставляемые товары с их средними цена-
ми, запишем:
range of s is ПОСТАВЩИКИ
retrieve into ФИКТИВНЫЙ (ТОВАР = s.TOBAP,
СРЕДНЯЯ-ЦЕНА = avg (s-ЦЕНА by s.TOBAP))
sort ФИКТИВНЫЙ
print ФИКТИВНЫЙ
Сортируем отношение ФИКТИВНЫЙ, чтобы устранить дубликаты, поскольку оно со-
держит для товара столько кортежей, сколько их для этого товара имеет отношение
ПОСТАВЩИКИ. Результат исполнения приведенной программы для отношения ПО-
СТАВЩИКИ из рис. 4.7 показан на рис. 4.13.
ТОВАР СРЕДНЯЯ- ЦЕНА
Творог Карамель Салат Фасоль Мука Сметана 0,80 1,27 0,84 1,14 0,65 0,74
Рис. 4.13. Средние цены товаров
1 Такой возможностью обладают также SEQUEL и Query-by-Example (который
будет обсуждаться в следующем разделе). Мы рассмотрим, однако, эту концепцию
только в контексте языка QUEL.
135
Организация хранения данных в INGRES
В INGRES имеется команда «создать» (create), которая создает новое имя
отношения. Эта команда позволяет пользователю специфицировать атрибу-
ты отношения и их типы данных. Последние ограничиваются целыми числа-
ми из одного, двух или четырех байт, действительными числами из четырех
или восьми байт и литерными строками фиксированной длины до 255 байт.
Таким образом, известно число байт, занимаемых каждым кортежем отно-
шения, и отношение может храниться как файл, состоящий из записей, по
одной для каждого кортежа. Записи хранятся в блоках длиной 512 байт.
При этом не допускается, чтобы какая-либо запись хранилась в двух блоках.
Если для кортежей не установлено конкретное упорядочение, файл
называется кучей. Мы можем обеспечить хешированный доступ к файлу для
отношения R, как было рассмотрено в разд. 2.2, если запишем:
modify R to hash on Alt ..., Ak,
где Alt ..., Ak — список атрибутов R, которые служат ключом. Реализация
файла для отношения R в INGRES осуществляется с помощью техники, рас-
смотренной в разд. 2.2. Записи при этом могут быть закрепленными благода-
ря вторичным индексам, которые мы обсудим позже. В качестве альтерна-
тивы использованию структуры с хешированным доступом может быть соз-
дан первичный индекс файла для R. С этой целью следует написать:
modify R to isam on Alt ..., Ah-
Здесь снова предполагается, что Alt ..., Ak есть ключ для R. Акроним
isam обозначает индексно-последовательный метод доступа (indexed sequen-
tial access method). Построенная таким образом структура была рассмотре-
на в разд. 2.3.
Вторичный индекс для R можно создать с помощью оператора
index on /? is S (Лх, ..., Л^).
Отношение S в результате этого становится вторичным индексом для
R по атрибутам Лх, ..., Ak и имеет структуру, подобную описанной в
разд. 2.7. Отношение S состоит из k + I компонентов, первыми k из которых
являются Ль ..., Ak, а последним — указатель на записи из R. Этот послед-
ний компонент не имеет имени атрибута, и поэтому пользователь не может
осуществлять доступ к его значениям или изменять их (хорошее проектное
решение, если оно вас интересует). Файл для вторичного индекса S автома-
тически делается файлом с индексно-последовательным методом доступа по
Ль ..., Ah, хотя такая организация может быть изменена командой modify
так же, как и для любого другого отношения, если этого пожелает пользова-
тель.
4.7. QUERY-BY-EXAMPLE: ЯЗЫК ИСЧИСЛЕНИЯ
С ПЕРЕМЕННЫМИ НА ДОМЕНАХ
Язык Query-by-Example(QBE) разработан в Исследовательском цент-
ре ИБМ в Йорктаун-Хейтсе. В этом языке предусмотрен ряд возможностей,
которых нет в реляционной алгебре, в реляционном исчислении, а также в
реализованных языках запросов, которые мы обсуждали ранее. Его специ-
фика заключается в том, что он предназначен для работы с терминала. При
этом можно применять специальный экранный редактор для составления
136
запросов. Клавиши терминала позволяют затребовать показ на экране од-
ной или более форм таблиц, как изображено на рис. 4.14. Далее с помощью
экранного редактора можно именовать отношения и атрибуты, представлен-
ные в такой форме.
Запросы, позволяющие формировать кортежи, принадлежащие одно-
му из отношений, формы которых появились на экране, формулируются с
использованием переменных на доменах и констант, как в реляционном ис-
числении с переменными на доменах. Некоторые из переменных, указывае-
мые путем задания префикса Р. для их имен, будут напечатаны1. (Все опе-
раторы в QBE заканчиваются точкой; сама точка не является оператором.)
При нахождении кортежа или комбинации кортежей, соответствующих спе-
цифицированному в запросе условию, печатаются компоненты для тех ат-
рибутов, которым предшествует Р.
Для имени отно-
шения
Для атрибутов
(могут использоваться, если
необходимо, дополнительные
столбцы)
д
Для команд иад
кортежами
Для кортежей, упоминаемых в запросах
Рис. 4.14. Форма таблицы QBE
Прежде чем перейти к детальному обсуждению выражения и смысла
запросов в QBE, рассмотрим пример, демонстрирующий, как выглядит ти-
пичный запрос. Допустим, мы хотим ответить на второй запрос из примера
4.12. и нам доступны в базе данных отношения ЗАКАЗЫ и ПОСТАВЩИКИ.
Потребуем показать на экране две формы таблиц.
В зарезервированной для имени отношения графе одной формы печа-
таем ЗАКАЗЫ Р. Атрибуты отношения ЗАКАЗЫ появятся в первой стро-
ке этой формы, как показано на рис. 4.15. Подобным же образом печатаем
ПОСТАВЩИКИ Р. в левом верхнем углу другой формы для того, чтобы по-
лучить атрибуты отношения ПОСТАВЩИКИ.
Существо второго запроса в примере 4.12 состоит в том, что требуется
найти в отношении ЗАКАЗЫ кортеж, компонентом ФАМИЛИЯ которого
является «Брукс», а компонентом ТОВАР — некоторый товар, например
«бананы». Тогда мы ищем в отношении ПОСТАВЩИКИ кортеж с тем же
самым товаром в компоненте ТОВАР и печатаем для каждого такого найден-
ного кортежа компоненты НАЗВ_ПОСТ, АДРЕС-ПОСТ и ТОВАР.
Рассматриваемый запрос, выраженный в QBE, представлен на рис. 4.15.
Важные для нас свойства кортежа, который нужно найти в отношении
ЗАКАЗЫ, записаны во второй строке формы этого отношения. Товару
1 В языке QBE для обозначения операторов, выполняемых над элементами задан-
ных таблиц, используются первые буквы соответствующих английских глаголов: Р. —
print (печатать), I. — insert (включить), D. — delete (удалить), U. — update (обно-
вить). — Примеч. ред.
137
«бананы» предшествует знак подчеркивания, показывающий, что это только
пример. Значение «Брукс» в компоненте ФАМИЛИЯ записывается без ка-
вычек или подчеркивания. В QBE таким образом представляются литера-
лы1.
В форме ПОСТАВЩИКИ можно видеть важное свойство кортежа, ко-
торый мы хотим найти в данном отношении, заключающееся в том, что то-
вар является таким же, как и в кортеже, найденном в отношении ЗАКАЗЫ.
Факт тождественности двух компонентов выражается в том, что переменная
на домене _ бананы является одной и той же в обоих кортежах. Мы видим
также из кортежа, записанного в форме ПОСТАВЩИКИ, что должны быть
напечатаны компоненты НАЗВ_ПОСТ, АДРЕС_ПОСТ и ТОВАР. Опера-
тор Р. в этих столбцах указывает печатаемые компоненты.
ЗАКАЗЫ ФАМИЛИЯ ТОВАР КОЛИЧЕСТВО
Брукс —бананы
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
Р. Р. Р.-бананы
Рис. 4.15. Пример запроса в QBE: «Для каждого товара, заказанного Бруксом, нэпе,
чатать поставщиков, их адреса и товары»
Большое семейство запросов QBE соответствует выражениям исчисле-
ния с переменными на доменах вида
{a1n2...an|(jb1)(jb2)...(jbm)(T?1(c11, ..., clkl) Л ••• A RP(cpl, cpkp))},
где каждое сц есть некоторое сц, bt или константа и каждое сц, bt появля-
ется по крайней мере один раз. Чтобы выразить любой такой запрос, мы по-
казываем формы таблиц для всех отношений, упоминаемых среди ...,
Rp, и создаем имя переменной для каждого из at и 6г. Вообще, имена пере-
менных, являющиеся примерами объектов, фактически принадлежащих со-
ответствующим доменам, служат хорошей мнемоникой, но годится и любая
другая строка литер, которой предшествует знак подчеркивания. Теперь
запишем кортежи для каждого терма 7?г (сг1, ..., с>.) в форму отношения
Rt. Если сц — константа, поместим ее в /-й компонент. Если сц одно из аг
или bt, поместим туда переменную, соответствующую этому символу. Если,
однако, одно из at или bt появляется только один раз среди всех термов, то
мы можем при желании оставить соответствующий компонент пустым.
1 Заметим, что соглашение о предшествовании именам переменных на доменах
знаков подчеркивания и о записи литералов без кавычек является диаметрально проти-
воположным обычному стилю языков запросов и языков программирования, где лите-
ралы, являющиеся строками литер, заключаются в кавычки, а переменные записы-
ваются без кавычек. Кроме того, в Query-by-Example имена выбираются в предполо-
жении, что они являются примерами требуемых объектов. Однако, как и в случае
других языков, имя «бананы» не имеет семантического смысла и могло бы быть замене-
но во всех его вхождениях иа «ненужное», а или хуг.
138
Часто имеет место случай, когда все а2 оказываются компонентами од-
ного терма К, (с21, .... С;*,). Если это так, то в кортеж данного терма поме-
щаем в качестве префикса для каждого at оператор Р.. Однако, если такого
терма не существует, можно создать другую форму таблицы. Ее компоненты
при необходимости можно поименовать и ввести в форму этой таблицы кор-
теж
Р._А1 Р._А2 ... Р._Ап,
где _Ai есть имя переменной для аг.
Пример 4.26. Предположим, что требуется напечатать для всех заказчи-
ков карамели их фамилии и заказанное количество товара. Этот запрос может быть вы-
ражен в исчислении с переменными на доменах следующим образом:
{ахаа| ЗАКАЗЫ (щ «Карамель» аг)},
а в QBE как
ЗАКАЗЫ ФАМИЛИЯ ТОВАР КОЛИЧЕСТВО
Р—Оу кис Карамель Р.
Здесь переменная _Оукис замещает ах. Эта переменная вполне может быть опуще-
на, поскольку _Оукис появляется только одни раз. Переменную для аг мы не создаем,
поскольку она также появляется только одни раз.
Рассмотрим другую задачу: напечатать фамилию, товар, количество и баланс лица,
сделавшего каждый заказ. В исчислении с переменными на доменах этот запрос имеет
вид
(ЧЛЕНЫ (а^а^) Д ЗАКАЗЫ (а]а2а3У)}
Поскольку никакой терм ие содержит всех at, мы затребуем новую форму табли-
цы, а также формы для отношений ЧЛЕНЫ и ЗАКАЗЫ. Этот запрос показан на
рис. 4.16.
ЧЛЕНЫ ФАМИЛИЯ АДРЕС БАЛАНС
-Оукис -999
ЗАКАЗЫ ФАМИЛИЯ ТОВАР КОЛИЧЕСТВО
-Оукис -бутерброд -МНОГО
Р.-Оукис Р._бутерброд Р.-МНОГО Р.-999
Рис. 4.16. Запрос: «Напечатать фамилии, товары, заказанные колн
чества и балансы»
139
Непоименованное отношение на рис. 4.16 можно написать также следующим об-
разом:
р. -Оукис -бутерброд — МНОГО „999
поскольку команда Р. в первом столбце (столбце, соответствующем имени отношения)
применяется ко всем компонентам кортежа.
Реализация запросов QBE
Общее правило реализации запроса в QBE1 заключается в том, что си-
стема создает переменную-кортеж для каждой строки, входящей в формы
таблиц существующих отношений. Во втором запросе из примера 4.26 со-
здается переменная-кортеж t для строки (_Оукис, , _999) отношения
ЧЛЕНЫ и переменная-кортеж для строки (_Оукис, „бутерброд, „много)
из отношения ЗАКАЗЫ. Отметим, что не создается никакой переменной
для строки непоименованного отношения на рис. 4.16, поскольку это отно-
шение не существует в базе данных. Если имеется k таких переменных-
кортежей, то формируется k вложенных циклов. Каждый цикл заставляет
одну из переменных пробегать по всем кортежам в его отношении. После
очередного присваивания значений переменным-кортежам (каждое «значе-
ние» есть кортеж в соответствующем отношении) проверяется, могут ли быть
заданы соответствующие значения переменным на доменах. В приведенном
выше примере необходимо лишь удостовериться в том, что компоненты ФА-
МИЛИЯ из s и t совпадают, и тогда можно задать соответствующее значение
переменной на домене „Оукис.
Всякий раз, когда нам удается получить значения переменных на
доменах, предпринимается требуемое запросом действие. Если, например,
одна или более строк запроса содержат какие-либо команды печати, то пе-
чатаются значения переменных на доменах, которые имеют префикс Р..
На рис. 4.16 только кортеж в непоименованном отношении имеет операторы
Р., и поэтому после получения упомянутых в этом кортеже значений перемен-
ных они печатаются. Если команды печати содержатся более чем в одной
строке, независимо от того, содержатся эти строки в одном отношении или
нет, значения этих строк печатаются в отдельных таблицах. При успешном
установлении соответствия могут выполняться другие действия, к числу
которых относится включение кортежей в отношение или их удаление из
него. Эти действия будут рассмотрены ниже.
Графы таблицы, представляющие множества
Графа в форме таблицы может быть заполнена таким образом, чтобы она
соответствовала более чем одному, но менее чем всем элементам некоторого
домена. Типичным случаем является заполнение графы 9с, где 9 — ариф-
метическое сравнение, ас— константа. Например, >=3 соответствует лю-
бому значению, не меньшему трех. Можно также записать 9с, где v — пере-
менная на домене. Например, < „итог соответствует любому значению,
1 Это ие означает, что QBE должен быть реализован таким способом. Скорее,
описываемая процедура служит определением запросов в QBE.
140
меньшему чем значение ^итог. Значение _итог определяется, вероятно,
заполнением некоторой другой графы запроса. Это значение изменяется,
так как в только что описанной процедуре реализации мы позволяем перемен-
ным-кортежам пробегать все кортежи.
Пример 4.27. Для того чтобы напечатать все заказы, в которых требуется
не менее 5 фунтов карамели, мы можем написать запрос, представленный на
рис. 4.17, а; по запросу, приведенному на рис. 4.17, б, напечатаются все заказы с боль-
шим количеством карамели, чем заказал Робин.
Запрос на рис. 4.17, б реализуется путем создания переменных-кортежей t из
для строк формы таблицы1. Поскольку мы допускаем, что t и з могут принимать в ка-
честве значений различные кортежи отношения ЗАКАЗЫ, следует проверять их соот-
ветствие. Кортеж t должен содержать в качестве компонента ФАМИЛИЯ «Робин» и
компонента ТОВАР— «Карамель». Если это так, то он определяет значение —х. Вся-
кий раз, когда вмеет место соответствие, это значение оказывается равным 3 (см. рве.
4.7). Далее рассматривается кортеж з. Если он содержит ТОВАР «Карамель» и его
КОЛИЧЕСТВО превышает значение _х, этот кортеж должен печататься.
ЗАКАЗЫ ФАМИЛИЯ ТОВАР КОЛИЧЕСТВО
Р. Карамель а) >=5
ЗАКАЗЫ ФАМИЛИЯ ТОВАР КОЛИЧЕСТВО
Р. Робин Карамель Карамель V 1 1 * и
б)
Рис. 4.17. Два запроса
Другой способ обозначения множества — заполнение графы, которое
является частично постоянным и частично переменным. Соединение этих ча-
стей представляет собой конкатенацию. Поэтому, если домен для данной
графы является литерными строками, мы можем попытаться проверить на
совпадение любые постоянные литерные строки в заполнении графы с под-
строками строки, которая образует соответствующий компонент некоторого
кортежа. При обнаружении такого совпадения можно присвоить перемен-
ным в заполнении графы фрагменты остальной части строки.
П р в м е р 4.28. Пусть мы хотим напечатать имена всех поставщиков, прожи-
вающих на Речной улице. Тогда следует записать:
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР КОЛИЧЕСТВО
Р. -999 Речная улица
1 Термин строка используется здесь для того, чтобы ссылаться на любую строку,
за исключением заголовка, который содержит имена отношения и атрибутов.
141
Каждый раз, когда в адресе указывается «Речная улица»1, переменная _999
принимает значение, равное номеру дома, и мы получаем совпадение. Таким образом,
если задано отношение, представленное ва рис. 4.7, в, то будет напечатано:
Солнечная продукция
Корп. вкусных продуктов
Заметим, что QBE в отлнчие от QUEL или SEQUEL автоматически ликвидирует
дубликаты.
Строки с отрицанием
В первый столбец любой строки (столбец с именем отношения R) может
быть помещен символ —.. Такой запрос требует, чтобы любой кортеж, соот-
ветствующий этой строке, не являлся кортежем R. Далее мы попытаемся
дать более точную интерпретацию, но прежде рассмотрим следующий пример.
Пример 4.29. Предположим, что требуется напечатать заказ (или заказы)
с наибольшим количеством заказанного товара. Для этого можно использовать агре-
гатную функцию МАХ, которая будет описана ниже. Однако в данном примере это сде-
лано с помощью отрицания. Перефразируем запрос следующим образом: «Напечатать-
заказ, если не существует иного заказа с большим количеством товара». В QBE это-
выражается так, как показано на рве. 4.18.
ЗАКАЗЫ ФАМИЛИЯ ТОВАР КОЛИЧЕСТВО
Р. 1 —X
>_х
Рнс. 4.18. Запрос: «Напечатать заказы, такие, что ника-
кой иной заказ не имеет большего количества заказан-
ного товара»
Реализация запросов с отрицанием требует модификации описанного
ранее алгоритма. Пусть в соответствии с рис. 4.18 созданы кортежи t и s
для двух строк (t — для первой строки) и эти кортежи пробегают все воз-
можные значения. Тогда t не должен печататься, как только будет найден
некоторый кортеж s, компонент КОЛИЧЕСТВО которого не превышает
КОЛИЧЕСТВО в t. Это привело бы в конечном счете к тому, что печатал-
ся бы каждый кортеж отношения ЗАКАЗЫ, в котором КОЛИЧЕСТВО не
является минимальным. В данном случае необходимо организовать циклы
по переменным так, чтобы самые внутренние циклы были связаны с перемен-
ными, соответствующими строкам с отрицанием. Далее, для каждого мно-
жества значений переменных-кортежей, связанных со строками без отрица-
ний, соответствующее присваивание значений переменным на доменах в за-
просе должно осуществляться только в том случае, если оказывается неудов-
летворительным результат проверки всех значений переменных-кортежей
для строк с отрицанием.
1 В США при записи адреса принято сначала указывать номер дома, а затем
название улицы. Прн переводе же всюду, кроме данного примера, использовалась
привычная для читателя форма записи адреса. Это обстоятельство необходимо учесть
прн разборе нашего примера, просматривая отношение на рнс. 4.7, в. — Примеч. ред.
142
Агрегатные операторы
Язык QBE имеет пять обычных агрегатных операторов, обозначаемых
SUM. (сумма), AVG. (среднее), МАХ. (максимум), MIN. (минимум) и CNT.
(счетчик). Имеются также два других оператора — ALL. (все) и UN. (уни-
кальный), которые часто используются вместе с операторами агрегации.
Применив оператор ALL. к переменной на домене, мы получим мульти-
множество значений, которые будет принимать переменная, если перебирать
все кортежи в релевантном отношении. Напомним, что мультимножество
представляет собой множество, в котором допускаются повторения, посколь-
ку оператор ALL., по существу, сохраняет дубликаты, в отличие от боль-
шинства других операций QBE, ликвидирующих их. Таким образом, для
вычисления среднего баланса членов кооператива в Счастливой Долине нуж-
но написать:
ЧЛЕНЫ ФАМИЛИЯ АДРЕС БАЛАНС
P.AVG.ALL.-999
Оператор UN. преобразует мультимножество в множество путем удале-
ния дубликатов. Предположим, например, что нам нужно знать, сколько
поставщиков имеется в базе Данных кооператива из примера 4.12. Если бы
мы (некорректно) написали:
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
P.CNT.ALL.-x
и применили это к отношению, представленному на рис. 4.7, в, мы получили
бы ответ 10, поскольку переменная _х принимает значения на мульти-
множестве из десяти значений, по одному для каждого кортежа в отношении.
Корректная формулировка запроса:
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
P.CNT.UN.ALL.-X
При таком способе перед пересчетом множества поставщиков, продуци-
рованного выражением ALL. _ х, оператор UN. удаляет дубликаты.
Включение и удаление кортежей
Если строка в запросе содержит в первой колонке оператор I. (или D.),
то во время реализации запроса переменная-кортеж для этой строки не со-
здается. В этом случае осуществляется включение (I.) (или удаление (D.))
соответствующих кортежей в (или из) отношение, в форме таблицы которо-
го находится данная команда. Переменные в строке (или строках), которые
143
должны быть включены, удалены или обновлены, принимают свои значения
из соответствующих компонентов переменных-кортежей.
Пример 4.30. Если корпорация «Солнечная продукция» начинает прода-
жу сметаны по 59 центов за фунт, то мы можем записать:
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
I. Солнечная продукция Речная улица, 16 Сметана .59
Заметим, что этот запрос реализуется в соответствии со специальным случаем
правила реализации QBE.
Поскольку не имеется переменных-кортежей, по которым строится цикл, выпол-
няется просто операция включения. Строка, которая должна быть включена, не содер-
жит переменных. Поэтому компоненты включенного кортежа полностью определены.
Если мы забыли адрес «Солнечной продукции», его можно получить нз базы дан-
ных во время выполнения включения следующим образом:
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
I. Солнечная продукция Солнечная продукция -адрес -адрес Сметана .59
Переменная-кортеж для второй строки имеет в качестве области определения
множество всех кортежей в отношении ПОСТАВЩИКИ. Значение «Речная улица, 16»
присваивается переменной _адрес всякий раз, когда переменная-кортеж для второй
строки принимает значение, содержащее название поставщика «Солнечная продукция»
в первом компоненте.
Обновления
Чтобы понять операцию обновления, необходимо знать, что система QBE
позволяет определять для отношения ключевые и неключевые атрибуты с
помощью механизма, который мы здесь кратко рассмотрим. Множество клю-
чевых атрибутов должно уникально определять кортеж, т. е. у двух корте-
жей в отношении не могут совпадать все ключевые атрибуты. Если в первом
столбце строки указан оператор обновления (U.), то значения ключевых по-
лей должны совпадать с соответствующими значениями ее обновляемого
кортежа. Для любого кортежа, который совпадает с данной строкой по клю-
чевым атрибутам, будут обновляться его неключевые атрибуты, причем их
значения совпадут со значениями в строке с U..
Пример 4.31. В отношении ПОСТАВЩИКИ атрибуты НАЗВ_ПОСТ и
ТОВАР являются ключевыми, а остальные — неключевымн. Если «Солнечная продук-
ция» повышает цену карамели до 1,33 дол. за фунт, мы пишем:
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
и. Солнечная продукция Карамель 1,33
Если на 0,10 дол. за фунт вырастет цена на все товары, поставляемые «Солнеч-
ной продукцией», запишем:
144
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
и. Солнечная продукция Солнечная продукция -бутерброд -бутерброд _х+.1О
Обратим внимание на использование арифметического выражения в строке, ко-
торая должна быть обновлена. Использование арифметики допускается там, где это
имеет смысл, например в строках, которые должны быть обновлены нлн включены, а
также в «блоках условий». Последнее понятие будет разъяснено ниже.
Блоки условий
Существуют ситуации, когда в строки запросов нужно включить условие
на запрос, включение, удаление или обновление, которое не выражается в
терминах, таких, как< 3. Тогда мы можем потребовать, чтобы был показан
блок условия, и вводим в него любое соотношение, которое должно удовлет-
воряться. Содержимое этого блока, по существу, является таким же усло-
вием, как в языке, подобном ПЛ/1, но не использующем оператор «не» —
Для обозначения логического «и» может быть использовано AND или &, а
для обозначения «или» — OR или |. При реализации запроса считается, что
соответствие имеет место, если текущие значения переменных-кортежей
допускают совместное присваивание значений переменным на доменах в за-
просе и эти значения удовлетворяют условиям.
Пример 4.32. Пусть нужно напечатать названия всех тех поставщиков
карамели, которые назначили цену, большую, чем цена, назначенная Корпорацией
вкусных продуктов на фасоль, и превышающую более чем вдвое цену, назначенную
компанией «Натуральные продукты» на творог. На рнс. 4.19 показан такой запрос,
выраженный с помощью блока условия.
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
Р. Корп. вкусных продуктов Натуральные продукты Карамель Фасоль Творог _р1 _р2 _рЗ
УСЛОВИЯ
_р1>_ р2
_р1< = _рЗ*2
Рнс. 4.19. Пример блока условия
Справочник таблиц
Система QBE поддерживает список, называемый справочником таблиц,
который содержит все имена отношений в базе данных, их атрибуты и опре-
деленную информацию об атрибутах. Используя ту же нотацию, что и для
обычных запросов, можно осуществлять запросы, включения в этот список
или удаления из него. Например, если напечатать Р. _ relname или просто
Р. в левой верхней графе формы таблицы, то система будет печатать текущий
145
список имен отношений1. Если же напечатать в той же графе Р. _relname Р.,
то будут печататься имена отношений и имена их атрибутов. Второе Р. ука-
зывает на имена атрибутов. Чтобы вставить новое отношение REL в справоч-
ник таблиц, нужно напечатать I.REL I. в левой верхней графе, а затем —
атрибуты REL в верхней части таблицы. Снова второе I. указывает на атри-
буты, в то время как первое I. относится к имени отношения.
Может быть объявлено, что атрибуты обладают определенными свойст-
вами. К числу этих свойств относятся:
1. KEY (ключ), указывающее, является ли атрибут частью ключа (на-
помним, что для обновлений необходимо, чтобы система различала ключевые
и неключевые поля). Значения этого свойства — Y (ключ) и N (не
ключ).
2. TYPE (тип) — тип данных атрибута, например CHAR (литерная
строка переменной длины), CHAR (и) (литерная строка длины и), FLOAT
(действительное число) или FIXED (целое).
3. DOMAIN (домен) — имя домена значений для данного атрибута.
Если переменная на домене появляется в запросе в двух различных столб-
цах, этим столбцам должен соответствовать один и тот же домен. Система
отвергает запросы, в которых нарушено указанное правило, — полезная
проверка осмысленности запросов.
4. INVERSION (инверсия), указывающее, должен ли создаваться и
поддерживаться индекс по атрибуту. В первом случае значение атрибута —
Y (ues — да), во втором — N (not — нет).
Пример 4.33. Чтобы создать отношение ПОСТАВЩИКИ, мы можем зане-
сти в форму таблицы некоторые из ее свойств, как показано на рнс. 4.20. Домен
СУММЫ может быть использован так же, например, как домен для БАЛАНС в отно-
шении ЧЛЕНЫ.
I. ПОСТАВЩИКИ I. НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
KEY I. Y N Y N
TYPE I. CHAR CHAR CHAR FLOAT
DOMAIN I. НАЗВАНИЯ АДРЕСА ТОВАРЫ СУММЫ
INVERSION I. N N N N
Рис. 4.20. Создание отношения ПОСТАВЩИКИ
Полнота QBE
Как и для других языков, наиболее простой метод доказательства полно-
ты QBE заключается, по-видимому, в том, чтобы показать, как применить
каждую из пяти операций реляционной алгебры и сохранить результат в
новом отношении. Для вычисления, например, Т = R и S можно выпол-
нить команду QBE, представленную на рис. 4.21, предполагая, что первона-
чально Т пусто. Операция вычисления разности множеств выполняется с
применением команды включения I., а затем — команды удаления D..
Декартово произведение и проекция выполняются включением. Мы остав-
ляем эти команды для упражнений.
Самая сложная проблема возникает в том случае, когда мы пытаемся вы-
числять селекцию Т = aF (R) для произвольного условия F.
1 Здесь relname= RELation NAME = имя отношения. — Примеч, ред.
146
R
S
_al _a2 ... _an
_bl _b2 ... -bn
T
I. _al _a2 ... _an
I. —bl _b2 ... —bn
Рис. 4.21. Команда QBE для получения объединений
Условия в блоках условий не используют логического оператора «нет».
Удалить операторы i из условия селекции F можно, однако, следующим
образом. Для выполнения преобразования на первом шаге следует восполь-
зоваться законами де Моргана:
"(^V F2)= ~'F1/\^F2
и перенести все отрицания внутрь Д и V так, чтобы применялось только
к атомам. На втором шаге любой атом может быть заменен своим отрица-
нием путем изменения входящего в него оператора сравнения. Например,
-] (Л #= В) — это то же самое, что и А = В, а (А< В) — то же самое,
что А В. Итак, мы имеем только операторы Ди \/, примененные к атомам,
и результат является допустимой формулой QBE.
Пример 4.34. Формула ^((Л < В) \/ (С = Df\E=jLF)) преобразуется сна-
чала за счет перенесения “3 внутрь V НЛ:
-'М<5)Д -(С=РД£^Е)
^(А<В)Д(^(С = П)
Применяя отрицание к атомам, получаем
Л>ВД (С^£> \/£ = Л,
или в нотации QBE
А>В&(С-я = В|Е = Е).
Теперь, чтобы вычислить orF(7?) в QBE, мы должны только выполнить
запрос, представленный на рис. 4.22, где F' есть F, в котором операторы
«не» удалены рассмотренным выше способом.
Т
УСЛОВИЯ
F’
I. _а1 _а2 ... _ап
Рнс. 4.22. Селекция в QBE
147
Представления
В QBE имеется возможность отложенного вычисления, аналогичная
используемой в ISBL. Если требуется создать представление V, заносим V
в форму таблицы точно так же, как имя отношения, записывая перед ним
ключевое слово VIEW. Далее формулируем в терминах QBE метод вычисле-
ния V. Однако V фактически в это время не создается. Это делается всякий
раз, когда оно используется в каком-либо последующем запросе. При этом
для определения его значения служат текущие значения отношений, упоми-
наемых в формуле для V.
Пример 4.35. Пусть требуется создать представление СЧЕТА, которое да-
ет заказанные товары, заказавшее их лицо, а также плату за ннх. Для вычисления пла-
ты берется наименьшая цена данного товара по всем его поставщикам. Эта наименьшая
цена за фунт умножается на число заказанных фунтов. Такое представление определяет-
ся на рис. 4.23. Мы можем далее использовать его как отношение, например в приведен-
ном на рис. 4.24 запросе. Значение отношения СЧЕТА вычисляется из отношений
ЗАКАЗЫ и ПОСТАВЩИКИ прн выполнении запроса.
I. VIEW СЧЕТА I. ФАМИЛИЯ ТОВАР ПЛАТА
I. _Оукис —бутерброд _q*MIN.ALL._p
ЗАКАЗЫ ФАМИЛИЯ ТОВАР КОЛИЧЕСТВО
-Оукнс —бутерброд -q
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
-бутерброд -Р
Рис. 4.23. Определение представления СЧЕТА
СЧЕТА ФАМИЛИЯ ТОВАР ПЛАТА
Р. Брукс —бутерброд _999
Рис. 4.24. Запрос, использующий СЧЕТА: «Напечатать дифференцированный по това-
рам счет для Брукса»
УПРАЖНЕНИЯ
4.1. Пусть R н S — отношения, показанные на рис. 4.25. Вычислите: a) R U S,
б) R — S, в) RXS (естественное соединение), г) лА (R), д) Од_с (Я X $)• Иг-
норируйте имена атрибутов в результате объединения и разности.
148
4.2. Предполагая, что R н S имеют соответственно арность 3 и 2, преобразуйте
выражение rti;B (o2=4v3=4 (Я X S)) в :
а) выражение реляционного нсчнсления с переменными-кортежами;
б) выражение реляционного нсчнсления с переменными на доменах.
4.3. Преобразуйте формулу исчисления с переменными-кортежами
{/(2> J R(t) Д (S (и) Д -я и [1] = t [2])}
в:
а) предложение на английском языке;
б) формулу реляционного исчисления с переменными-кортежами;
в) формулу реляционной алгебры.
4.4. Преобразуйте формулу исчисления с переменными на доменах
{а6|Д (ab) A R (Ъа)}
в:
а) предложение на английском языке;
б) выражение реляционного исчисления с переменными-кортежами;
в) формулу реляционной алгебры.
Рис. 4.25. Отношения из упражнения 4.1
4.5. Являются ли выражения в упражнениях 4.3 и 4.4 безопасными?
4.6. Пусть имеется база данных, состоящая из трех следующих отношений:
ЧАСТО ПОСЕЩАЕТ (ПЬЯНИЦА, БАР)
ИМЕЕТ (БАР, ПИВО)
ЛЮБИТ (ПЬЯНИЦА, ПИВО)
Первое отношение указывает бары, которые часто посещает каждый пьяница,
второе говорит о том, какие сорта пива подаются в каждом баре, а последнее—какие
сорта пива любит каждый пьяница. Выразите в: 1) реляционной алгебре, 2) исчисле-
нии с переменными на доменах, 3) исчнсленни с переменными-кортежами, 4) языке
ISBL, 5) языке SQUARE, 6) языке SEQUEL, 7) языке QUEL, 8) в Query-by-Exa-
mple следующие запросы:
а) напечатать названия баров, в которых подают пиво, любимое пьяницей Чарль-
зом Чагемагом1;
б) напечатать имена пьяниц, которые часто посещают по крайней мере один бар,
где подают любимое ими пиво;
* в) напечатать имена пьяниц, которые часто посещают только бары, где подают
какое-либо любимое ими пиво;
* г) напечатать имена пьяниц, которые не посещают часто никакого бара, где
подают любимое ими пиво.
4.7. Используя 1) SQUARE, 2) QUEL, 3) Query-by-Example, напишите про-
граммы для:
а) удаления из отношения ИМЕЕТ всех кортежей с пивом «Потгольд»;
б) включения кортежа, представляющего тот факт, что пьяница Чагемаг любит
пиво «Потгольд»;
в) включения кортежа, представляющего тот факт, что Чагемаг любит все сорта
пива, которые подают в барах «Бент Элбоу» и «Гриль».
4.8. Предположим, что база данных из упражнения 4.6 содержит отношение
ПРОДАЕТ (БАР, ПИВО, КОЛИЧЕСТВО). Напишите в QUEL запросы, которые пе-
чатают: а) суммарное и б) среднее по каждому сорту количество проданного пива (за
исключением баров, которые не продают пиво).
1 Вероятно, автор использует созвучие со словом «chugalug» — «выпить одним
духом». — Примеч. ред.
149
4.9. Пусть в базе данных из упражнения 4.6 требуется создать представление
ГДЕ (ПЬЯНИЦА, ПИВО, БАР), содержащее кортежи (d, b, г), такие, что пьяннца d
любит пиво Ь, в баре г подают пиво Ь и d часто посещает г. Напишите в a) ISBL и б)
Query-by-Example определения представления ГДЕ.
** 4.10. Транзитивным замыканием R+ бинарного отношения R называется мно-
жество пар (а, Ь), таких, что для некоторой последовательности clt са.сп:
1) — а\
2) сп = 6;
3) для i = 1, 2, ..., п — 1 имеем (ci, q+i) принадлежит R.
Докажите, что не существует выражения реляционной алгебры, эквивалентно-
го операции транзитивного замыкания над конечными отношениями.
** 4.11. Покажите, что пять операторов реляционной алгебры (объединение,
разность, селекция, проекция и декартово произведение) являются независимыми в
том смысле, что ни одни из них не может быть выражен в виде формулы, которая содер-
жит только четыре других оператора. Указание: для каждого оператора следует обнару-
жить такое свойство, которым не обладает любое выражение, записанное в терминах
других четырех операторов. Например, чтобы показать независимость объединения,
допустим, что имеется выражение Е (R, S), включающее только операторы разности,
селекции, проекции и произведения, но эквивалентное R (J S для любых R и S. Пусть
Re состоит из единственного кортежа (a, b), a So — из единственного кортежа (с, d),
где а, Ь, с и d не входят в Е как константы. Покажите индукцией по числу операторов,
используемых в любом подвыражении F из Е, что отношение, являющееся значением
F (Rg, Sg), не может иметь компонента, в котором один кортеж содержит а, а дру-
гой — с. Поскольку RB (J So имеет такой компонент, то из этого следует, что
F (Rg, So ) Rg (J S„.
Библиографические замечания
Реляционная алгебра была введена в работе Кодда [42]. Коддом также доказана
[43] ее эквивалентность реляционному исчислению с переменными-кортежами. В по-
следней статье, кроме того, впервые сформулирован принцип, заключающийся в том,
что язык запросов должен быть, по меньшей мере, полным для реляционного исчисле-
ния. Идею использования исчисления предикатов для формулировки запросов связы-
вают с именем Кунса [102]. Джекобс [94] обобщил соотношение между алгеброй и исчис-
лением на другие модели данных, такие, как сетевая и иерархическая. Галлер и Мин-
кер [70] показали различные приложения исчисления предикатов к реляционным базам
данных.
ISBL и система PRTV обсуждаются в работе Тодда [169]. Язык SQUARE описан
Бойсом и др. [28], a SEQUEL — в работе Чемберлина и др. [32]. Ранняя версия этого
языка рассмотрена Астраханом и Чемберлином [10], СУБД System R обсуждается
Астраханом и др. [11]. Информацию о QUEL и INGRES можно найти у Стоунбрекера,
Вонга, Крепса и Хелда [164], Вонга и Юзефи [176], а также Зука и др. [188]. Описа-
ние коммерческой вер ' Query-by-Example содержится в документе IBM [92], а ее
экспериментальная вер'.ь описана Злуфом [186].
В обзоре Пиротта [134] упоминается большое число существующих реляционных
языков манипулирования данными, классифицируемых иа алгебраические языки, язы-
ки исчисления с переменными-кортежами, а также исчисления с переменными на доме-
нах, как это сделано и в данной книге. Грннблат и Ваксман [79] сравнивают легкость
изучения QBE, SEQUEL и реляционной алгебры. Явным преимуществом обладает
QBE. Кроме того, представляет интерес статья Ахо, Кернигана и Вайнбергера [3], опи-
сывающая «инструментарий» реляционных баз данных, который предназначен для ис-
пользования в обстановке операционной системы UNIX.
Упражнение 4.10 о транзитивном замыкании заимствовано из работы Ахо и Уль-
мана [5]. В этой работе, а также у Чандра и Харела [33] исследуется возможность ре-
ляционных языков запросов, которые выполняют только манипулирование дан-
ными (в отличие от арифметических действий над данными), но являются, однако,
более богатыми, чем реляционное исчисление. Бенсилои [13] и Пэреданс [131] пытаются
доказать, что в реляционном исчислении можно выразить все операции, в которых
не содержится арифметика. Однако они допускают, что функции, подобные R+, могут
вычисляться различными выражениями для каждого R, и это не противоречит упраж-
нению 4.10. Злуф [185] показывает, как транзитивное замыкание может быть вычисле-
но в QBE (с использованием возможностей языка, которые мы не рассматривали), де-
монстрируя тем самым, что QBE является более мощным, чем реляционное исчисле-
ние.
150
Вывод о независимости операторов, подобный сделанному в упражнении 4.11,
был доказан Беком 116].
Исследования, связанные с реляционными базами данных, ведутся во многих на-
правлениях. Помимо теории проектирования, обсуждаемой в гл. 5, и оптимизации за-
просов, рассматриваемой в гл. 6, мы должны упомянуть и работы о естественном язы-
ке как языке запросов. Типичными в этой области являются работа Дель’Орко, Спа-
давекио и Книга 152], система Rendezvous Кодда и др. [47], а также статья Кодда [45].
Хотя проблема трайсляции естественных языков, например английского, в запросы,
которые может понимать машина, всегда является сложной, реляционная модель все
же обеспечивает полезную основу для такой трансляции. Возможно, в частности, иден-
тифицировать определенные существительные и глаголы отношениями, атрибутами
и значениями из доменов. Тот факт, что схема отношения имеет фиксированное множе-
ство атрибутов, известных заранее, часто дает полезный ключ к пониманию.
Другое важное направление — введение «семантики» в реляционную модель. Ав-
торы ряда работ— Шмид и Свенсон [150], Фуртадо [69], Кодд [46] и Сайор [151] —
пытались различать роли атрибутов. Не вдаваясь в детали, мы отмечали в разд. 3.1,
что некоторые атрибуты в схеме отношения могут представлять объекты, в то время как
другие — связи между объектами. Эти различия уточнены в указанных статьях. До-
полнительный интерес представляют концепции, называемые «агрегацией и обобщени-
ем», введенные Смитом и Смит [156]. Эта статья, по существу, расширяет реляционную
модель, допуская, что домен атрибута может быть множеством имен отношений. Такое
расширение способствует обобщению (например, набор объектов «учащиеся» обобщает
наборы объектов «аспиранты», «студентки» и т. д.), позволяя нам ассоциировать с каж-
дым элементом набора объектов некоторое отношение, которое дает информацию, от-
носящуюся к данному объекту (например, «консультант» — это атрибут, соответствую-
щий только аспирантам).
Третья область, в которой остаются нерешенные проблемы, — расширение реля-
ционной модели, позволяющее оперировать «неопределенными значениями», т. е. эле-
ментами кортежа, которые представляют неизвестные, неуместные или противоречивые
значения. Попытки иметь дело с неопределенными значениями предпринимали Кодд
[44], Лакруа н Пнротт [104], Заниоло [184], Лнпски [107] и Вассилоу [174]. Однако
возникают проблемы, когда мы пытаемся определить алгебраические операции. На-
пример, должны лн два неопределенных значения рассматриваться как одинаковые,
если берется эквисоединение? Ни один ответ ие является в полной мере удовлетвори-
тельным.
ГЛАВА 5
ТЕОРИЯ ПРОЕКТИРОВАНИЯ
РЕЛЯЦИОННЫХ БАЗ ДАННЫХ
При проектировании реляционной базы данных часто приходится стал-
киваться с проблемой выбора из множества альтернативных вариантов схем
отношений1. По различным причинам одни варианты оказываются более удоб-
ными, чем другие. Мы изучим некоторые свойства схем отношений и рассмо-
трим несколько алгоритмов, позволяющих получать хорошую схему базы
данных (множество схем отношений).
В проектировании схем баз данных центральное место отводится идее
зависимостей данных, т. е. ограничений на возможные отношения, которые
могут быть текущими значениями схемы отношения. Если, например, один
атрибут однозначно определяет другой, подобно тому как ФАМИЛИЯ,
очевидно, определяет АДРЕС в отношении ЧЛЕНЫ из примера 4.12, то
можно сказать, что существует «функциональная зависимость» атрибута
АДРЕС от атрибута ФАМИЛИЯ. Мы будем рассматривать функциональные
зависимости, а также более сложные зависимости, называемые «многознач-
ными», когда один или несколько атрибутов определяют множество значений
одного или нескольких других атрибутов, но в отличие от функциональной
зависимости такое множество может иметь более одного элемента.
Изучив зависимости, мы вернемся к вопросу о выборе подходящего мно-
жества схем отношений, которые представляют данную информацию. Чи-
татель должен иметь в виду, что необходимо сделать целый ряд предвари-
тельных математических замечаний для того, чтобы успешно разобраться
в трудной проблеме автоматического проектирования базы данных. Поэтому
мы вынуждены отвлечься от нашей главной темы для изучения свойств за-
висимостей.
5.1. ПОЧЕМУ ПРОЕКТ БАЗЫ ДАННЫХ МОЖЕТ БЫТЬ ПЛОХИМ?
Прежде чем мы приступим к обсуждению методов проектирования хо-
роших схем баз данных, давайте посмотрим, почему некоторые схемы могут
оказаться неадекватными. В частности, обратимся к схеме отношения
ПОСТАВЩИКИ (НАЗВ_ПОСТ, АДРЕС.ПОСТ, ТОВАР, ЦЕНА)
из примера 4.12. В связи с этой схемой возникает несколько проблем:
1. Избыточность. Адрес поставщика повторяется для каждого постав-
ляемого товара.
1 Напомним, что схема отношения представляет собой множество атрибутов, ассо-
циированных с именем отношении.
152
2. Потенциальная противоречивость (аномалии обновления). Вследствие
избыточности мы можем обновлять адрес поставщика в одном кортеже, ос-
тавляя его неизменным в другом. Таким образом, может оказаться, что для
некоторых поставщиков нет единого адреса. Однако интуитивно мы чувст-
вуем, что он должен быть.
3. Аномалии включения. В базу данных не может быть записан адрес по-
ставщика, если он в настоящее время не поставляет по меньшей мере один
товар. Можно, конечно, поместить неопределенные значения в компоненты
ТОВАР и ЦЕНА кортежа для этого поставщика. Но если он начнет постав-
лять некоторый товар, не забудем ли мы удалить кортеж с неопределенными
значениями? Хуже того, ТОВАР и НАЗВ_ПОСТ образуют ключ данного
отношения, и поиск кортежей с неопределенными значениями в ключе мо-
жет быть затруднительным или невозможным.
4. Аномалии удаления. Обратная проблема возникает при необходимо-
сти удаления всех товаров, поставляемых данным поставщиком, вследствие
чего мы непреднамеренно утрачиваем его адрес.
В этом примере все перечисленные проблемы исчезают, если заменить
отношение ПОСТАВЩИКИ двумя схемами отношений:
ПА (НАЗВ.ПОСТ, АДРЕС.ПОСТ)
ПТЦ (НАЗВ_ПОСТ, ТОВАР, ЦЕНА)
Первая из них, ПА, предусматривает в точности однократное представ-
ление адреса каждого поставщика. Благодаря этому мы избавляемся от из-
быточности данных. Более того, можно ввести адрес поставщика, даже если
в настоящее время он не поставляет каких-либо товаров. Вторая схема от-
ношения, ПТЦ, дает поставщиков, товары, которые они поставляют, и цену,
назначенную каждым поставщиком на свои товары.
Однако остаются нерешенными еще некоторые вопросы. Например, при-
веденная выше декомпозиция имеет существенный недостаток. Чтобы найти
адреса поставщиков сметаны, необходимо теперь построить соединение,
представляющее собой дорогую операцию, в то время как в случае единст-
венного отношения ПОСТАВЩИКИ можно было бы просто выполнить се-
лекцию и проекцию. Каким образом можно определить, является ли указан-
ная выше замена выгодной? Имеют ли место какие-либо другие из перечис-
ленных четырех проблем для новых двух схем отношений? Как найти хоро-
шую замену для плохой схемы отношений? В следующих разделах данной
главы мы постараемся ответить на все эти вопросы.
5.2. ФУНКЦИОНАЛЬНЫЕ ЗАВИСИМОСТИ
В данном и следующих разделах мы познакомим читателя с необходимой
для дальнейшего обсуждения теорией функциональных зависимостей, а за-
тем (в разд. 5.4) вернемся к основной нашей проблеме — проектированию
схем баз данных.
В гл. 3 отмечалось, что отношения могут различными способами исполь-
зоваться для моделирования «реального мира». Кортеж отношения может,
например, представлять некоторый объект и его атрибуты или связь между
объектами. Во многих случаях из известных фактов о реальном мире сле-
дует, что не каждое конечное множество кортежей может быть текущим зна-
чением некоторого отношения, даже если бы эти кортежи имели правильную
арность и их компоненты были выбраны из правильных доменов. Сущест-
вуют два вида ограничений на отношения;
153
1. Ограничения, которые зависят от семантики элементов домена.
Эти ограничения основаны на понимании того, что означают компоненты
кортежей. Например, рост человека не может быть равен 60 футам1 точно
так же, как ни один человек со стажем работы 37 лет не может иметь возраст
25 лет. Было бы полезно, чтобы СУБД обнаруживала такие неправдоподоб-
ные значения, которые возникают из-за ошибок при вводе или вычислении
данных. В гл. 9 рассматриваются способы выражения и использование та-
кого рода «ограничений целостности». К сожалению, они мало или совсем
ничего не говорят о проектировании схем баз данных.
2. Ограничения на отношения, которые зависят только от равенства
или неравенства значений. Эти ограничения связаны не с конкретным зна-
чением некоторого заданного компонента, а с тем, совпадают ли определен-
ные компоненты двух кортежей. В настоящем разделе мы обсудим наибо-
лее важные из таких ограничений, называемые функциональными зависи-
мостями. Имеются, однако, и другие типы ограничений, не зависящих от
конкретных значений данных. Эти ограничения будут рассмотрены в после-
дующих разделах. Как выяснилось, они имеют наибольшее влияние на про-
ектирование схем баз данных.
Пусть R (Аг, А2, ..., Лп) — схема отношения, а X и У — подмножест-
ва {Xj, Л2> • ••> Ап}. Говорят, что «X функционально определяет У» или
«У функционально зависит от X», и обозначают это как X -> У, если в лю-
бом отношении г, являющемся текущим значением R, не могут содержаться
два кортежа, компоненты которых совпадают по всем атрибутам, принадле-
жащим множеству X, но не совпадают по одному или более атрибутам, при-
надлежащим множеству У.
Естественно, функциональные зависимости возникают различными спо-
собами. Если, например, R представляет набор объектов и Alt .... Ап яв-
ляются атрибутами этого набора, аХ — множество атрибутов, образующих
его ключ, то можно утверждать, что X ->• У для любого подмножества У
указанных атрибутов. Это вытекает из того факта, что кортежи г представ-
ляют объекты, а объекты идентифицируются значениями атрибутов ключа.
Следовательно, два кортежа, совпадающие по атрибутам, принадлежащим
X, должны представлять один и тот же объект и поэтому являются одним
и тем же кортежем. Подобным же образом, если R представляет отображение
вида «многие к одному» от набора объектов Е1 к набору объектов Е2 и среди
А( имеются атрибуты, образующие ключ X для Ег и ключ У для Е2, то
справедлива зависимость X ->• У, и фактически X функционально определя-
ет любое множество атрибутов. Однако нельзя утверждать, что У -> X,
если отображение не имеет вида «один к одному».
Следует подчеркнуть, что функциональные зависимости являются ут-
верждениями обо всех отношениях, которые могут быть значениями схемы
отношения R. Мы не можем рассмотреть конкретное отношение г для схемы
R и вывести из этого, какие функциональные зависимости существуют в
R. Например, если г — пустое множество, то оказывается, что существуют
все зависимости. Однако в общем случае они могут не иметь места, так как
изменяется значение отношения, обозначенного R. При рассмотрении кон-
кретного отношения для R можно, однако, обнаружить, что некоторые за-
висимости ие имеют места.
Единственный способ определения функциональных зависимостей для
схемы отношения R заключается в том, чтобы внимательно проанализиро-
вать семантику атрибутов. В этом смысле зависимости являются фактически
1 Одни фут равен 30,48 см. — Примеч. ред.
154
высказываниями о реальном мире. Они не могут быть доказаны. Но мы на-
деемся, что они будут проводиться в жизнь средствами СУБД, если ей это
предписано. Многие системы поддерживают функциональные зависимости,
вытекающие из того, что ключ определяет другие атрибуты отношения. Не-
которые системы поддерживают даже произвольные функциональные за-
висимости .
Нужно отметить, что декларация функциональной зависимости в базе
данных — это решение, которое может быть принято только проектировщи-
ком. Польза такой декларации заключается в том, что система базы данных
будет далее поддерживать для пользователя ограничение целостности. Кро-
ме того, благодаря этой функциональной зависимости, возможно, существу-
ет более эффективная реализация отношения. Однако при этом хранение
некоторой информации становится невозможным. Например, если объявля-
ется, что ИМЯ функционально определяет ТЕЛЕФОН, то ни при каких
обстоятельствах в нашей базе данных не могут храниться два номера теле-
фона для одного лица.
Пример 5.1. Рассмотрим функциональные завнснмости, которые, как мы
допускаем, существуют в базе данных кооператива нз примера 4.12. Естественно пред-
положить, что каждый член кооператива имеет единственный адрес н единственный ба-
ланс н что в кооперативе никогда не будут состоять два члена с одной н той же фамили-
ей. (Если в этом возникнет необходимость, можно воспользоваться прозвищем.) При
таких предположениях мы можем утверждать, что
ФАМИЛИЯ ->- АДРЕС БАЛАНС
Заметим, что для обозначения множества атрибутов обычно используется конка-
тенация нх имен. Так, А±А2 ... Ап — это краткая запись для {Aj, А2, ..., Ап}. Мы
применяем также конкатенацию имен атрибутов для обозначения объединения. Напри-
мер, XY обозначает X (J Y, если X н Y — множества атрибутов.
В отношении ЗАКАЗЫ мы требуем, чтобы
ФАМИЛИЯ ТОВАР -> КОЛИЧЕСТВО
Эта зависимость основана на предположении, что никогда ие может быть двух
заказов на один и тот же товар для одного и того же лица. Иными словами, дополнитель-
ный заказ реализуется добавлением к количеству в старом заказе, а не включением но-
вого кортежа. Рассматривая этот вопрос, мы приходим к выводу, что такое ограниче-
ние явяется единственно разумным. В противном случае мы столкнулись бы с тем, что
в соответствии с рис. 4.7 Брукс мог бы заказать, например, еще 7 фунтов карамели, ио
он не может заказать еще 5 фунтов карамели, поскольку отношение, будучи множест-
вом, не может иметь два идентичных кортежа. В отношении ПОСТАВЩИКИ мы на-
блюдаем следующие завнснмости:
НАЗВ-ПОСТ -> АДРЕС-ПОСТ
НАЗВ_ПОСТ ТОВАР ЦЕНА
У кого-либо может возникнуть желание узиать, имеет ли силу зависимость, по-
добная зависимости АДРЕС_ПОСТ -» НАЗВ_ПОСТ или АДРЕС -> ФАМИЛИЯ.
Обращаясь к рис. 4.7, мы подозреваем, что такая зависимость существует. Однако,
в принципе, ничто не препятствует кооперативу принять двух членов с одним и тем же
адресом нлн иметь двух поставщиков с одним и тем же адресом. Таким образом, мы не
объявляем эти завнсимостн. Существуют другие тривиальные зависимости, такие, как
ФАМИЛИЯ ->- ФАМИЛИЯ
нлн
ФАМИЛИЯ ТОВАР ТОВАР,
и некоторые нетривиальные зависимости, которые следуют из уже объявленных ра-
нее, например
НАЗВ-ПОСТ ТОВАР-> АДРЕС-ПОСТ ЦЕНА
155
Логические следствия зависимостей
Пусть R — схема отношения, а А, В и С — некоторые из ее атрибутов.
Пусть также известно, что в R существуют функциональные зависимости
А -> В и В -> С. Можно утверждать при этом, что А -> С также имеет ме-
сто в R. Для доказательства рассмотрим отношение г, удовлетворяющее за-
висимостям Д->ВиВ->Си содержащее два кортежа /ин, которые сов-
падают по компоненту для А, но не совпадают для С. Далее нужно выяснить,
совпадают ли t и и по компоненту для атрибута В. В случае отрицательного
ответа в г нарушается зависимость А -> В. Если же совпадение имеет место
для В, то, поскольку не совпадают компоненты для С, в г нарушается за-
висимость В -> С. Следовательно, г удовлетворяет зависимости А -> С.
Пусть, вообще, F есть множество функциональных зависимостей для
схемы отношения R и X -+ Y — некоторая функциональная зависимость.
Говорят, что зависимость X -> Y логически следует из F, если для каждого
отношения г со схемой R, удовлетворяющего зависимостям из F, удовлетво-
ряется также X -> Y. Выше мы видели, что если F содержит зависимости
А В и В С, то зависимость А -> С логически следует из F. Пусть F+
обозначает замыкание F — множество функциональных зависимостей, ко-
торые логически следуют из F. Если F = F+, мы говорим, что F — полное
семейство зависимостей.
Пример 5.2. Пусть R = АВС и F ~ {А В, В -* С}. Тогда F+ состоит
нз всех зависимостей X -> V, таких, что выполняется одно нз следующих условий:
1. X содержит А, например АВСАВ, АВ-> ВС или А -> С.
2. X содержит В, но не А, н ¥ не содержит А, например ВС В, В ->~ С или
В^-0.
3. X -» ¥ — одна из двух зависимостей: С -+ С или С -> 0.
Доказательство этого утверждения мы приведем позднее.
Ключи
Рассматривая наборы объектов, мы предполагали, что существует
ключ — множество атрибутов, которое уникально определяет объект. Ана-
логичное понятие существует и для отношений с функциональными зависи-
мостями. Если/? — схема отношения с атрибутами Аг, А3, Ап и функ-
циональными зависимостями F, а X — подмножество ДГД2 ... Ап, то X на-
зывается ключом R, если:
1. X -+ AjA2 ... Ап принадлежит F+.
2. Ни для какого собственного подмножества Y X зависимость
Y -> А1А2 ... Ап не принадлежит F+.
Следует заметить, что вопрос о минимальности ключа (условие 2) не
обсуждался при рассмотрении ключей наборов объектов в гл. 1 или ключей
файлов в гл. 2. Причина этого заключается в том, что без формализма, по-
добного функциональным зависимостям, мы не можем проверить, является
ли данное множество атрибутов минимальным. Читатель должен понимать,
что в настоящей главе термин «ключ» действительно предполагает минималь-
ность. Таким образом, данный ключ некоторого набора объектов только тогда
будет ключом отношения, представляющего этот набор объектов, когда он
является минимальным. В противном случае одно или более подмножеств
ключа набора объектов служит ключом этого отношения.
Поскольку для отношения может существовать более одного ключа, один
из них иногда назначается первичным ключом. Первичный ключ может слу-
жить, например, ключом файла при реализации отношения. Любой ключ
по нашему желанию может быть первичным. В литературе иногда исполь-
156
зуется термин возможный ключ, обозначающий любое минимальное множест-
во атрибутов, которое функционально определяет все атрибуты, а термин
«ключ» резервируется для одного назначенного возможного ключа. Поми-
мо этого в данной работе используется термин сверхключ для обозначения
любого множества атрибутов, содержащего ключ.
Пример 5.3. Для отношения Р и множества зависимостей F нз примера
5.2 существует только один ключ А, так как зависимость А -> АВС принадлежит F+,
но никакой X, не содержащий А, функционально не определяет АВС.
Более интересным примером является схема отношения К (ГОРОД, АДРЕС,
ИНДЕКС), где ИНДЕКС обозначает почтовый индекс отделения связи, обслуживаю-
щего адресатов какой-либо улицы города, а АДРЕС — название улицы и номер дома.
Будем предполагать, что кортеж (с, s, г) принадлежит некоторому отношению со схе-
мой отношения R, если только в городе с имеется здание по адресу s, и г является со-
ответствующим почтовым индексом. В этом случае имеют место следующие нетривиаль-
ные функциональные зависимости:
ГОРОД АДРЕС ИНДЕКС
ИНДЕКС ГОРОД,
т. е. полный адрес (город и адрес в городе) определяет почтовый индекс, а почтовый
индекс определяет город, хотя и не определяет адрес. Можно легко проверить, что
оба множества атрибутов {ГОРОД, АДРЕС) и {АДРЕС, ИНДЕКС) являются ключа-
ми.
Аксиомы функциональных зависимостей
Чтобы определить ключи и понять логические следствия функциональ-
ных зависимостей в общем случае, необходимо вычислить F* из F или по
крайней мере знать для заданного F и функциональной зависимости X -> Y,
содержится ли X -+ Y в F+. Для этого необходимо иметь правила вывода,
которые указывают, как из одной или более зависимостей выводить другие
зависимости. Фактически мы можем сделать большее — предоставить пол-
ное множество правил вывода. Это означает, что при заданном множестве за-
висимостей F правила позволяют нам вывести все зависимости, принадлежа-
щие F+. Более того, эти правила являются надежными в том смысле, что,
используя их, мы не можем вывести из F какую-либо зависимость, которая
не принадлежит F+.
Множество таких правил мы будем называть аксиомами Армстронга
[8], хотя конкретные правила, которые здесь представлены, отличаются от
предложенных Армстронгом. Предположим, что задана некоторая схема
отношения с множеством атрибутов U, универсальным множеством атрибу-
тов, и множество функциональных зависимостей F, связывающих только
атрибуты, принадлежащие U. Тогда имеем следующие правила вывода:
А1: (рефлексивность). Если Y X U, то X -> Y логически следует из
F. Заметим, что это правило дает тривиальные зависимости, т. е. зависимо-
сти, правая часть которых содержится в левой части. Его использование не
зависит от F.
к2'. (пополнение). Если X -> Y и Z е U, то XZ -+ YZ. Напомним, что X,
У и Z являются множествами атрибутов, a XZ — условная сокращенная за-
пись X и Z. Важно напомнить также, что данная зависимость X -> Y либо
принадлежит F, либо может быть выведена из принадлежащих F зависимо-
стей с использованием описываемых аксиом.
АЗ: (транзитивность). Если X Y и Y -> Z, то X -> Z.
Пример 5.4. Рассмотрим снова ситуацию нз примера 5.3, где мы утвержда-
ли, что {АДРЕС, ИНДЕКС)— ключ, т. е.
АДРЕС ИНДЕКС-> ГОРОД АДРЕС ИНДЕКС
157
Докажем это утверждение.
1. ИНДЕКС -> ГОРОД (дано)
2. АДРЕС ИНДЕКС -» ГОРОД АДРЕС (пополнение (1) атрибутом
АДРЕС)
3. ГОРОД АДРЕС ИНДЕКС (дано)
4. ГОРОД АДРЕС-»- ГОРОД АДРЕС ИНДЕКС (пополнение (3) атрибутами ГОРОД
АДРЕС)
5. АДРЕС ИНДЕКС -> ГОРОД АДРЕС ИНДЕКС (по аксиоме транзитивности нз
(2) и (4))
Относительно легко доказывается, что аксиомы Армстронга являются
надежными, т. е. приводят только к истинным заключениям. Более сложно
доказать их полноту, означающую, что эти аксиомы могут быть использова-
ны для получения каждого справедливого следствия из зависимостей. Зай-
мемся сначала вопросом надежности.
Лемма 5.1. Аксиомы Армстронга являются надежными. Иными сло-
вами, если зависимость X -+ Y выведена из F с использованием этих акси-
ом, то она справедлива в любом отнощении, в котором справедливы зависи-
мости из F.
Доказательство. Аксиома рефлексивности А1, очевидно, яв-
ляется надежной. Мы не можем иметь отношение г с двумя кортежами, ко-
торые совпадают по X, но не совпадают по некоторому подмножеству X.
Для доказательства надежности аксиомы пополнения А2 предположим, что
имеется отношение г, которое удовлетворяет зависимости X -+ Y. Однако
в нем существуют два кортежа t н и, которые совпадают по атрибутам XZ,
но не совпадают по YZ. Поскольку эти кортежи не могут не совпадать по
какому-либо атрибуту из Z, t и и должны не совпадать по некоторому атри-
буту, принадлежащему Y. Но тогда t и и совпадают по X, но не совпадают
по Y. Это противоречит нашему предположению о том, что зависимость
X -+ Y справедлива для г. Надежность аксиомы транзитивности АЗ нетруд-
но показать путем простого продолжения приведенного ранее доказатель-
ства того, что изА->ВиВ->С следует А -+ С. Эта часть доказательства
оставляется читателю для упражнения.
Существует несколько других правил вывода, которые следуют из ак-
сиом Армстронга. Три из них будут сформулированы в следующей лемме.
Поскольку надежность Al, А2 и АЗ доказана, мы имеем право использовать
их в нашем доказательстве.
Лемма 5.2.
1. Правило объединения. Если X -> У и X->Z, то YZ.
2. Правило псевдотранзитивности. Если X -+ Y и WY -> Z, то XW-+Z
3. Правило декомпозиции. Если X -+ Y и Z Y, то X -> Z.
Доказательство.
1. Так как дано, что X -> Y, то путем пополнения по X можно вывести
X -> XY. Поскольку задано также, что X -+ Z, благодаря пополнению по
Y получаем XY -+ YZ. По аксиоме транзитивности из X -> XY и
XY-+YZ следует X-+YZ.
2. При условии, что задано X -> Y, мы можем пополнением по W по-
лучить WX ->• WY. Поскольку также известно, что WY -> Z, по аксиоме
транзитивности имеем WX -> Z.
3. Правило декомпозиции вытекает из А1 и АЗ.
Правила объединения и декомпозиции порождают важное следствие:
если А1( ..., Ап — атрибуты, то зависимость X ->• Ах... Ап справедлива,
если и только если зависимость X —А; справедлива для каждого I.
Прежде чем приступить к вопросу о полноте рассматриваемой системы
аксиом, важно определить замыкание множества атрибутов относительно
158
множества функциональных зависимостей. Пусть F — множество функцио-
нальных зависимостей на множестве атрибутов U и пусть X — некоторое
подмножество U. Тогда Х+, замыкание X относительно F, есть множество
атрибутов А, таких, что зависимость X -> А может быть выведена из F по
аксиомам Армстронга. Главное свойство замыкания множества атрибутов
заключается в том, что оно позволяет сразу определить, следует ли зависи-
мость X -+ Y из F по аксиомам Армстронга. Следующая лемма дает ответ
на этот вопрос.
Лемма 5.3. Функциональная зависимость X -* Y следует из ак-
сиом Армстронга, если и только если Y <= Х+.
Доказательство. Пусть Y = ... Ап для атрибутов Аг, ....
Ап. Предположим также, что У s Х+. Тогда по определению Х+, X-^At
выводится для всех I с помощью аксиом Армстронга. Из правила объедине-
ния (лемма 5.2, п. 1) следует X Y. Наоборот, предположим, что зависи-
мость X -> Y следует из аксиом. Для каждого i по правилу декомпозиции
имеет место зависимость X -> Аг. Поэтому Y s Х+.
Теперь мы готовы доказать полноту аксиом Армстронга. Для этого
нужно показать, что если F — заданное множество функциональных за-
висимостей и зависимость X ->• Y не может быть выведена по аксиомам Арм-
стронга, то должно существовать отношение, в котором справедливы все за-
висимости из F, кроме X -> Y, т. е. X -> Y логически не следует из F.
Теорема 5.1. Аксиомы Армстронга являются надежными и пол-
ными.
Доказательство. Надежность аксиом Армстронга была дока-
зана в лемме 5.1. Поэтому нужно доказать только их полноту. Пусть F —
Атрибуты нз Х+ Другие атрибуты
1 1 ... 1 1 1 ... 1
11 . ..1 00-.. О
Рнс. 5.1. Отношение г, показывающее, что зависимость
логически не следует нз F
некоторое множество зависимостей на множестве атрибутов U. Предполо-
жим, что зависимость X -* Y не может быть выведена из аксиом. Рассмотрим
отношение г с двумя кортежами, приведенное на рис. 5.1. Сначала покажем,
что все зависимости в F удовлетворяются отношением г. Допустим, что
V -> W принадлежит F, но не удовлетворяется отношением г. Тогда V Х+,
так как иначе два кортежа г'не совпадали бы по некоторому атрибуту из V.
К тому же W не может быть подмножеством Х+, поскольку в противном
случае зависимость V -> W удовлетворялась бы отношением г. Пусть А —
некоторый атрибут W, не принадлежащий Х+. Так как V sX+, зависимость
X -> V следует из аксиом по лемме 5.3. Зависимость V ->• W принадлежит
F, откуда по аксиоме транзитивности имеем X -> W. Поэтому согласно ак-
сиоме рефлексивности IJZ ->А, и снова благодаря транзитивности имеем, что
зависимость X -> А следует из аксиом. Но в этом случае А принадлежит
Х+. Однако мы предполагали обратное. Это противоречие приводит нас к
выводу о том, что каждая зависимость V -> W из F удовлетворяется отно-
шением г.
Теперь мы должны показать, что зависимость X ->• Y не удовлетворяет-
ся отношением г. Допустим, эта зависимость удовлетворяется. Из очевид-
ного соотношения X Х+ следует, что Y <= Х+, так как в противном слу-
чае два кортежа г совпадали бы по X, Но не совпадали бы по Y. Од-
159
нако тогда по лемме 5.3 зависимость X Y может быть выведена из аксиом.
Получаем противоречие. Следовательно, X -+ Y не удовлетворяется отно-
шением г, даже если каждая зависимость принадлежит F. Отсюда можно
заключить, что всякий раз, когда зависимость X -> Y не может быть вы-
ведена из F по аксиомам Армстронга, она логически не следует из F.
Таким образом, эти аксиомы полны.
Теорема 5.1 имеет некоторые интересные следствия. Мы определили
Х+ как множество атрибутов А, таких, что зависимость X -> А выводится
из данных зависимостей F с помощью аксиом. Теперь можно дать эквива-
лентное определение Х+ как множества атрибутов А, таких, что X -+ А
логически следует из F. Другое следствие состоит в том, что, хотя мы и оп-
ределили F+ как множество зависимостей, которые логически следуют из
F, мы могли бы определить F+ как множество зависимостей, следующих
из F по аксиомам Армстронга.
Вычисление замыканий
Оказывается, что вычисление F+ для множества зависимостей F являет-
ся, вообще говоря, весьма трудоемкой задачей, потому что множество за-
висимостей F+ может быть большим, даже если само F мало. Рассмотрим мно-
жество F = {А -> Blt А -+ В2, ..., А -> Тогда В+ включает все зави-
симости А -> Y, где Y — подмножество множества {Вг, Ва, ..., Вп}. Так
как существует 2" таких множеств Y, не следует рассчитывать даже при ра-
зумных значениях п на то, что удастся легко перечислить В+.
В противоположность этому вычисление Х+ для данного множества ат-
рибутов X не представляет трудностей. Оно требует времени, пропорцио-
нального длине всех выписанных полностью зависимостей в F. По лемме 5.3
определить, принадлежит ли X -> Y замыканию В+, не труднее, чем вычис-
лить Х+. Простой путь вычисления Х+ дает следующий алгоритм.
Алгоритм 5.1. Вычисление замыкания множества атрибутов от-
носительно некоторого множества функциональных зависимостей.
Входные данные. Конечное множество атрибутов U, множе-
ство функциональных зависимостей F на U и множество X = U.
Выходные данные. Х+ — замыкание X относительно F.
Метод. Вычисляем последовательность множеств атрибутов Х(0),
Xй \ ... по следующим правилам:
1. Х<°> есть X.
2. Х(1+1) есть X(i) плюс множество атрибутов А, таких, что в F сущест-
вует некоторая зависимость Y ->Z, А принадлежит Z и Y £= X(i). Посколь-
ку X = Х(0) £ ... Х(о ... £= U и U конечно, мы должны в итоге до-
стигнуть такого г, что X(Z) = X(i+1). Отсюда следует, что X(i) = X(i+1) =
= х<'+2) = Нет необходимости продолжать вычисления после Х('\ если
обнаружено, что X<f) = X<i+1). Можно доказать (доказательство приводит-
ся ниже), что Х+ есть X(f) для значения t, удовлетворяющего указанному ус-
ловию.
Пример 5.5.
Пусть F состоит нз следующих восьми зависимостей:
АВ -> С
С^А
ВС D
ACD-> В
D-+EG
ВЕ-+С
CG-+BD
СЕ -> AG
и X — BD. Чтобы применить алгоритм 5.1, положим Х(°) = BD. Для вычисления
Х<4 найдем зависимости, которые имеют в левой части В, D или BD. Существует толь-
160
ко одна такая зависимость D EG. Поэтому присоединяем £ и G к Х<°) и полагаем
Х(О = BDEG. Чтобы вычислить Х(а), ищем левые части, содержащиеся в XW. Нахо-
дим D -► EG и BE -► С. Таким образом, Х<а) = BCD EG. Для вычисления Х(3) ищем
левые части, содержащиеся в BCDEG. В дополнение к двум ранее найденным зависи-
мостям находим С -► А, ВС -► D, CG -► BD и СЕ —AG. Тогда имеем Х<3) =ABCDEG—
множество всех атрибутов. Следовательно, нет никакой неожидаииости в том, что
ХЮ = ХЮ ^ ... Итак, получаем (BD)+ = A BCD EG.
Алгоритм 5.1 может быть реализован так, чтобы он исполнялся за вре-
мя, пропорциональное сумме длин зависимостей, если для каждой зависимо-
сти Y -> Z иметь счетчик числа атрибутов в Y, которые еще не принадлежат
Х(<>. Для каждого атрибута А мы должны также создать список зависимостей,
в левой части которых появляется А. Когда А присоединяется к некоторому
Х(<), счетчик каждой зависимости в списке для атрибута А уменьшается на
единицу. Если счетчик для Y -> Z становится равным нулю, то мы знаем,
что Y = ХЮ. Наконец, следует поддерживать ХЮ в виде булевского мас-
сива, индексированного по номерам атрибутов. Тогда, если мы обнаружива-
ем, что Y = ХЮ, где Y -* Z — одна из зависимостей, то за время, пропорци-
ональное размеру Z, можно сказать, какие атрибуты в Z должны быть при-
соединены к ХЮ. При вычислении Х<г+1> из Х.Ю от нас требуется лишь ус-
тановить значение «истина» для элементов массива, соответствующих атри-
бутам, которые добавляются к X(i), и нет необходимости копировать ХЮ.
Детальное обсуждение этой модификации алгоритма 5.1 содержится в [22],
хотя и сам этот алгоритм, вероятно, достаточно эффективен в большинстве
случаев.
Теперь мы должны обратиться к проблеме доказательства корректности
алгоритма 5.1. Легко доказать, что каждый атрибут, помещаемый в неко-
торое Х</>, содержится в Х+. Гораздо труднее доказывается, что каждый
атрибут из Х+ помещается в некоторое Х(/).
Теорема 5.2. Алгоритм 5.1 корректно вычисляет Х+.
Доказательство. Сначала индукцией по / покажем, что если
А помещается в ХЮ, то А принадлежит Х+.
Базис, j = 0. Тогда А принадлежит X, и поэтому, конечно, X -> А.
Индукция. Предположим, что j> 0 и Х<‘1~1'> состоит только из
атрибутов, принадлежащих Х+. Предположим далее, что А помещается в
ХЮ в силу того, что А принадлежит Z, Y -> Z принадлежит f и У с
Поскольку Y S согласно гипотезе индукции нам известно, что
Y = Х+. Но тогда X -* Y по лемме 5.3. По аксиоме транзитивности из
X -> Y и Y -> Z следует X -* Z. В соответствии с аксиомой рефлексивно-
сти имеем Z-^A. Поэтому получаем по аксиоме транзитивности Х-+А.
Таким образом, А принадлежит Х+.
Покажем теперь обратное: если А принадлежит Х+, то А принадлежит
некоторому Л(')_ Заметим, что не имеет значения, завершается ли алгоритм
5.1 перед вычислением ХЮ. Действительно, если вычисления прекратятся
при ХЮ = Х<г+1) для некоторого i< j, мы знаем, что ХЮ= ХЮ. Следо-
вательно, возвращаемое значение Х+, в качестве которого принимается Х(<),
включает А. На самом деле мы докажем далее следующий факт: если из
аксиом Армстронга можно вывести, что X -> Y следует из F, то каждый ат-
рибут из Y помещается в некоторое ХЮ. Используем при этом индукцию по
числу строк в доказательстве выводимости X Y. Здесь строка понимает-
ся как зависимость, которая либо принадлежит F, либо следует из аксиомы
рефлексивности или из предыдущей строки (строк) по аксиоме пополнения
или транзитивности. Последней строкой является зависимость X -> Y.
Прежде чем перейти к индукции, следует сформулировать вывод, к ко-
торому мы неоднократно приходили.
6 Зак. 1315
161
Наблюдение (*к Если Хх и Х2 — два множества атрибутов
и Xi Е Х2, то Xlj"> Е Х(2” для всех j.
С неформальной точки зрения исполнение алгоритма 5.1 никогда не
заканчивается с меньшим числом атрибутов, чем то, с которым оно начина-
ется. Формальное доказательство утверждения (*) легко провести индук-
цией по /. Оставляем его как упражнение для читателя и перейдем к доказа-
тельству индукцией по р того, что А принадлежит некоторому Х(/>, где
р — число строк в выводе X -> А из F.
Базис. Одна строка. Тогда либо X -> Y следует по аксиоме рефлек-
сивности, и в этом случае Y Е Х(0), либо X -> Y принадлежит F. В послед-
нем случае каждый атрибут У, несомненно, принадлежит Х(1>.
Индукция. Пусть данное утверждение истинно для доказательств,
содержащих менее р строк, и доказательство X -> Y состоит из р строк.
Если X -> Y принадлежит F или следует из аксиомы рефлексивности, то
мы можем рассуждать так же, как и в базисе. Если X -> У следует по акси-
оме транзитивности из двух предыдущих строк доказательства, например
из X -> Z и Z -> У, то доказательства обеих этих зависимостей состоят ме-
нее чем из р строк. По гипотезе индукции существует некоторое Х(/>, вклю-
чающее все атрибуты из Z. Поэтому имеем z £= X(J). Теперь рассмотрим ис-
полнение алгоритма 5.1 с Z вместо X. Согласно гипотезе индукции сущест-
вует некоторое k, такое, что Z(A) содержит все атрибуты из У. По наблюде-
нию (*), заменяя Х2 на XG) и Xi на Z, получаем, что Х(/+Л) содержит все
атрибуты из У.
Рассмотрим последний случай, когда зависимость X -> У следует из
некоторой предшествующей строки V -> W пополнением ее множеством ат-
рибутов Z. Тогда VZ = X и WZ = Y. Известно, что доказательство V -> W
состоит менее чем из р строк. Поэтому по гипотезе индукции, если алгоритм
5.1 начинает исполняться с V, существует некоторое j, такое, что W Е У(,).
В соответствии с (*), если алгоритм 5.1 начинает исполняться с X = VZ,
то W Е Х(Р. ПосколькуZ s X, имеем Z Е X(J). Тогда V^Z, принадлежащее
У, является подмножеством Х(Р. Этим и завершается доказательство ин-
дукцией.
По лемме 5.3, если А принадлежит Х+, доказательство зависимости
X -> А может быть выведено из F с использованием аксиом. Следовательно,
из приведенного выше доказательства индукцией вытекает, что А принадле-
жит некоторому Х(Р, и, таким образом, А принадлежит множеству, которое
вырабатывается по алгоритму 5.1 как значение Х+. Значит, этот алгоритм
никогда не возвращает ни слишком много, ни слишком мало. Он возвращает
в точности Х+.
Покрытия множеств зависимостей
Пусть F и G — множества зависимостей. Будем считать, что F и G
эквивалентны, если F+ = G+. В этом случае иногда говорят, что F покры-
вает G (и G покрывает F). Легко проверить, являются ли F и G эквивалент-
ными. Для каждой зависимости Y -> Z в F проверяется, содержится ли эта
зависимость в G+. При этом используется алгоритм б.Рдля вычисления
У+. Затем проверяется, справедливо ли соотношение Z Е У+. Если ока-
зывается, что некоторая зависимость Y -> Z в F не принадлежит G+, то,
несомненно, F+ ^G+. Если же каждая зависимость в F принадлежит G+,
1 Здесь имеется в виду замыкание У относительно множества зависимостей G, —
Примеч. ред.
162
то каждая зависимость V -> W в Г+ принадлежит G+. Доказательство того,
что V -> W принадлежит G+, можно провести в два этапа. Сначала убежда-
емся в том, что каждая зависимость Y -> Z в F принадлежит G+, а затем про-
веряем принадлежность V-+W замыканию F+. Аналогичным образом мы по-
ступаем, когда нужно проверить, каждая ли зависимость в G также при-
надлежит F+. Тогда F и G являются эквивалентными, если и только если
каждая зависимость в F принадлежит G+ и каждая зависимость в G принад-
лежит F+.
Следующая лемма устанавливает важный факт, связанный с эквивалент-
ностью.
Лемма 5.4. Каждое множество функциональных зависимостей F
покрывается некоторым множеством зависимостей G, в которых ни одна из
правых частей не имеет более одного атрибута.
Доказательство. Пусть G — множество зависимостей X -> А,
таких, что для некоторой зависимости X -> У в F А принадлежит У. Тогда
зависимость X -> А следует из зависимости X -* У по правилу декомпози-
ции. Таким образом, G S F+. Но F £= G+, поскольку если У = Ах ... Ап,
то X -+ У следует из X -* Ах.X -+ Ап в соответствии с правилом объе-
динения.
Для разработки теории проектирования схем баз данных оказывается
полезным рассмотрение более сильных ограничений на покрытия, чем то,
что правые части имеют всего лишь один атрибут. Говорят, что множество
зависимостей F является минимальным, если:
1. Правая часть каждой зависимости в F содержит единственный атрибут.
2. Ни для какой зависимости X -► А в F множество F — {X -г А} не эк-
вивалентно F.
3. Ни для какой зависимости X -> А в F и собственного подмножества
Z s X множества F — {X —А) и {Z -> А} и F не эквивалентны.
Как подсказывает интуиция, условие (2) гарантирует, что никакой ат-
рибут в любой левой части не является избыточным. Поскольку каждая пра-
вая часть имеет только один атрибут, в соответствии с условием (1) никакой
атрибут в правой части, очевидно, не является избыточным.
Теорема 5.3. Каждое множество зависимостей F эквивалентно
некоторому минимальному множеству F-.
Доказательство. Примем на основании леммы 5.4, что ни од-
на из правых частей зависимостей в Г не имеет более одного атрибута. Что-
бы удовлетворялось условие (2), будем просматривать в некотором порядке
все зависимости F. Если для какой-либо зависимости X -> У окажется, что
F — {X -> У} эквивалентно F, удалим X ->У из F. При этом различный по-
рядок рассмотрения зависимостей может привести к разным результатам.
Пусть, например, задано множество F:
АВ А -> С
В->А С-> А
Здесь можно исключить В -> А и А -> С или В -> С, но все три зави-
симости исключить нельзя.
Если условие (2) удовлетворяется, попытаемся добиться удовлетворе-
ния условия (3), рассматривая снова в некотором порядке оставшиеся в F
зависимости и атрибуты в их левых частях. Если можно исключить некото-
рый атрибут из какой-либо левой части и все-таки иметь эквивалентное мно-
жество атрибутов, то такой атрибут исключается. Это делается до тех пор,
пока ни один атрибут нельзя будет больше исключить ни из одной левой ча-
G*
163
сти. Здесь вновь на результат может влиять порядок, в котором исключают-
ся атрибуты. Если, например, задано:
АВ-+С
А-+В
В-+А,
то можно исключить А или В из АВ -> С, но нельзя исключить оба атрибу-
та.
Пример 5.6. Рассмотрим множество зависимостей F из примера 5.5. Если
использовать алгоритм из леммы 5.4 для расщепления правых частей, получим;
АВ - > С BE- > С
С - > А CG- > В
ВС - > D CG - > D
ACD- > В СЕ - -А
D - > Е СЕ - * G
D - > G
Ясно, что зависимость СЕ А избыточна, поскольку она следует из зависимости
С А. Подобным же образом избыточна зависимость CG -► В, так как из СО D,
С А и A CD В следует СО -► В, что может быть проверено вычислением (CG)+.
Никакие другие зависимости не являются избыточными. Однако ACD -► В может быть
замещена зависимостью CD В, поскольку С А. Полученное таким образом мини-
мальное покрытие для F показано на рис. 5.2, а. Другое минимальное покрытие,
построенное нз F исключением СЕ -► А, СО -► D и ACD -► В, показано на рис. 5.2, б.
Отметим, что эти два минимальных покрытия имеют разное число зависимостей.
АВ—>С
С—>А
BC—>D
CD—>B
D—+E
D—+G
BE—С
CG—+D
CE—+G
a)
AB—>C
C—*A
BC—>D
D-—>E
D-+G
BE-+C
CG—>B
CE-^G
6)
Рис. 5.2. Два минимальных покрытия
5.3. ДЕКОМПОЗИЦИЯ СХЕМ ОТНОШЕНИЙ
Декомпозицией схемы отношений R — {Дъ Д2, ..., Ап} называется за-
мена ее совокупностью р = {/?!, R2, ..., подмножеств R, таких, что
Ri U R2 U U Rk = При этом не требуется, чтобы Rt были непересе-
кающимися. Один из доводов в пользу декомпозиции заключается в том, что
она может снять часть проблем, упомянутых в разд. 5.1. Вообще, осущест-
вление декомпозиции некоторого первоначального множества схем отноше-
ний, когда это оправданно, входит в обязанности лица, проектирующего
базу данных (администратора базы данных).
Пример 5.7. Рассмотрим схему отношения ПОСТАВЩИКИ, введенную
в примере 4.12, но для краткости записи обозначим атрибуты S (НАЗВ_ПОСТ), А
(АДРЕС_ПОСТ), I (ТОВАР) и Р (ЦЕНА). Предположим, что имеют место следующие
функциональные зависимости: S -► А и SJ -► Р. В разд. 5.1 уже упоминалось, что за-
мена схемы отношения SA/Р двумя схемами SA и SJP позволяет избежать некоторых
проблем. Например, в SAJP мы не можем хранить адрес поставщика, если он ие по-
ставляет по крайней мере один товар. В отношении SA для записи адреса поставщика
не обязательно, чтобы он поставлял какой-либо товар.
164
Можно усомниться в том, все ли так хорошо, как нам это кажется, ког-
да мы заменяем SAIP на S4 и SIP в примере 5.7. Пусть, например, неко-
торое отношение г есть текущее значение SAIP. Если база данных Исполь-
зует ЗЛ и SIP вместо SAIP, то мы можем, естественно, ожидать, что те-
кущие отношения для этих двух схем отношений будут проекция-
ми г на и SIP, т. е. rsA = л$Л(г) и rSip = nsip(r). Каким об-
разом можно узнать, что г$а и rsip содержат ту же самую информацию,
что и г? Один из способов заключается в проверке возможности вычисления
г только на основе знания rsA и rsip. Мы утверждаем, что единст-
венным способом восстановления г является вычисление естественного со-
единения rsA и rsip1. Причина заключается в том, как будет доказано
в нижеследующей лемме, что если принять s — гзл^><] rsip, то л$д (s) =
= rSA и nSip(s) = rsip. Если же s #= г, то при заданных rsA
и rsip не существует никакого способа, позволяющего определить, ка-
кое из отношений — г или $ — было первоначальным отношением для схе-
мы SAIP. Иными словами, если естественное соединение не восстанавлива-
ет первоначальное отношение, то не существует какого-либо способа, обес-
печивающего его однозначное восстановление.
Соединение без потерь информации
Пусть R — схема отношения, в результате декомпозиции которой по-
лучены схемы Rlt R2, ..., Rh и D — множество зависимостей. Говорят, что
эта декомпозиция обладает свойством соединения без потерь (относительно
D), если каждое отношение г для R, удовлетворяющее D, может быть пред-
ставлено в виде
Г = Яд, (г) >< ля, (г) >< ... ><J nRk(г),
т. е. г является естественным соединением его проекций на все Rt. Из сде-
ланных выше замечаний очевидно, что свойство соединения без потерь весь-
ма желательно для декомпозиции. Поэтому мы несколько подробнее рассмо-
трим вопрос о соединениях без потерь.
Основные свойства отображений проекции-соединения доказываются
в лемме 5.5. Введем сначала некоторые обозначения. Если р = (Rlt R2,
.... Rh), то тР является отображением, которое определяется соотношением
тр(г) = ОО яя.(г), т. е. тр (г) — соединение проекций г на схемы отноше-
<=1 1
ний из р. Таким образом, условие соединения без потерь относительно D
может быть выражено следующим образом: для всех г, удовлетворяющих
D, г = тр (г). Введем также другое полезное соглашение об обозначениях.
Если t — кортеж и X — некоторый список атрибутов, то будем предпола-
гать, что t [X] обозначает список компонентов t для атрибутов из X. Напри-
мер, можно выразить лх (г) так: {t [X]/f принадлежит г}.
Лемма 5.5. Пусть R — схема отношения, р = (Rlt ..., Rh) — де-
композиция R, г — отношение для R и rt = nR{ (г). Тогда:
а) г £= тр (г);
б) если s = тр (г), то nR( (s) = rt;
в) тр (тр (г)) = тр (г).
х См. определение естественного соединения в разд. 4.1.
165
Доказательство.
а) Пусть t принадлежит г. Тогда для каждого i ti — t [R,] принадле-
жит гг. По определению естественного соединения t принадлежит тр (г),
поскольку t совпадает с по атрибутам схемы Rt для всех i.
б) Так как согласно п. (a) rSs, пц. (г) = jir. (s), т. е. г, s (s).
Чтобы доказать соотношение лд. (s) £= гг, предположим для некоторого
конкретного/, что принадлежит л^; (s). Тогда в s имеется некоторый кор-
теж t, такой, что t [7?г] — tj. Так как t принадлежит s, для каждого j сущест-
вует некоторое и} в /у, такое, что t [/? J = Uj. Таким образом, в частности,
t [/?;] принадлежит г;. Но t = tit и поэтому принадлежит rt. Следо-
вательно, л«. (s) S rt. Отсюда можно сделать вывод, что rt = jtr. (s).
в) Если $ = /пр (г), то из п. (б) имеем л«г (s) = г;. Таким образом,
k
тР (s) = X r4 = m₽ (r).
i = 1
Заметим, что при каждом i, если гг — некоторое отношение для Ri
k
и s = ><]гг, то л«. (s) не обязательно равно гг. Причина заключается в том,
что г,- может содержать «безработные» кортежи. Например, если RT = АВ,
R2 = ВС, гг — {flibi} и r2 = {5^, btct}, то s — {яА/й} (в предположении,
что порядок этих трех атрибутов в s есть АВС) и л вс (s) = ¥= г2.
Однако в общем случае л«. (s) £= rh и если каждое гг является проекцией
некоторого одного отношения г, то лд. (s) — rt.
Способность хранить «безработные» кортежи представляет собой одно
из преимуществ декомпозиции. Как упоминалось ранее, это преимущество
должно быть сбалансировано с необходимостью вычислять больше соеди-
нений для ответов на запросы в случае, если осуществлена декомпозиция
схем отношений. При рассмотрении всех аспектов проблемы можно, вообще
говоря, прийти к выводу, что декомпозиция желательна лишь тогда, когда
требуется решать такие проблемы, как избыточность, описанная в разд. 5.1.
Проверка свойства соединения без потерь
Оказывается, можно достаточно легко определить, обладает ли деком-
позиция свойством соединения без потерь относительно некоторого множест-
ва функциональных зависимостей.
Алгоритм 5.2. Проверка на соединение без потерь.
Входные данные. Схема отношения R = Аг ... Ап, множест-
во функциональных зависимостей F и декомпозиция р = (Rlt .... Rk).
Выходные данные. Решение о том, обладает ли декомпози-
ция р свойством соединения без потерь.
Метод. Строим таблицу с п столбцами и k строками. Столбец j со-
ответствует атрибуту Aj, а строка i — схеме отношения Rt. На пересечении
строки i и столбца / поместим символ о,, если Aj принадлежит R(. В против-
ном случае поместим туда символ Ь^.
Повторно «рассматриваем» каждую из зависимостей X-+Y в F до тех пор,
пока в таблице невозможно будет сделать какие-либо изменения. Всякий
раз, «рассматривая» зависимость X -> Y, мы ищем строки, которые совпа-
дают по всем столбцам, соответствующим атрибутам из X. При обнаруже-
нии двух таких строк отождествляем их символы в столбцах, соответствую-
щих атрибутам из У. Если при этом один из отождествляемых символов ра-
вен а}, приравниваем и другой а}. В том случае, когда они равны Ьи и Ьи,
делаем их оба равными Ьи или btj по своему усмотрению.
166
После модификации строк таблицы указанным выше образом может
обнаружиться, что некоторая строка стала равной ... ак. Тогда декомпо-
зиция р обладает свойством соединения без потерь. В противном случае'она
не обладает таким свойством.
Пример 5.8. Рассмотрим декомпозицию SA1P на ЗЛ и S1P, как и в приме-
ре 5.7. Здесь имеют место зависимости 3 А и S1 -> Р. Получаем следующую началь-
ную таблицу:
3 А Z Р
«1 as ^13 614
62а а3 а*
Поскольку 3 -► А и две строки совпадают по S, мы можем отождествлять их сим- волы для А, заменив 6аа иа аг. В результате имеем таблицу
3 А / Р
а1 ai 61S 614
«1 «« аз «4
Так как одна строка состоит из всех а, мы имеем дело с соединением без потерь.
Приведем более сложный пример. Пусть R = ABCDE, R4 AD, Rt = АВ,
В3 = BE, R4 — CDE и Rs = AE и имеются функциональные зависимости:
А - С DE-+C
В-С СЕА
С — D
Начальная таблица показана иа рис. 5.3, а. Применяя зависимость А С, мы
можем отождествить символы Ь13, Ьгз и Ьь3. Используем далее зависимость В -> С
и отождествляем эти символы с Ь33. На рис. 5.3, б показан результат, где й13 выбран как
представитель отождествленных символов. Рассматривая теперь зависимость С -► D,
отождествляем а4, Ь24, Ьм и Ьь4, выбирая в качестве результирующего символа а4. На-
конец, зависимость DE С позволяет отождествлять Ь13 с а3, а СЕ -* А — символы
&Э1, 641 и ах. Результат показан на рис. 5.3, в. Поскольку средняя строка представляет
собой все а, декомпозиция имеет соединение без потерь.
Интересно отметить, что возможны предположения об упрощении ал-
горитма 5.2 путем отождествления только символов, одним из которых яв-
ляется at. Приведенный выше пример показывает, что дело обстоит не так.
Если бы мы не начали с отождествления d18, fe28, Ью и д58, то строка из всех
а никогда не могла бы быть получена.
Теорема 5.4. Алгоритм 5.2 корректно определяет, обладает ли
декомпозиция свойством соединения без потерь.
Доказательство. Предположим, что конечная таблица, полу-
ченная в результате применения алгоритма 5.2, не содержит строки, состоя-
щей из всех а. Такую таблицу можно рассматривать как отношение г для
схемы R. При этом строки являются кортежами, а aj и bi} — различными
символами, выбранными из домена Aj. Отношение г удовлетворяет зависи-
мостям F, поскольку алгоритм 5.2 модифицирует таблицу всякий раз, ког-
да обнаруживается нарушение зависимостей. Мы утверждаем, что г =#
#= тр (г). Ясно, что г не содержит кортежа ... ап. Но для каждого Rt
существует некоторый кортеж t, в г, а именно кортеж, являющийся строкой
I, такой, что h [7?;] состоит из всех а.
Следовательно, соединение всех (г) содержит кортеж со всеми а,
так как этот кортеж совпадает с t, для всех I. Отсюда можно заключить, что,
167
если конечная таблица, полученная с помощью алгоритма 5.2, не содержит
строки со всеми а, то декомпозиция р не обладает свойством соединения без
потерь. Кроме того, в этом случае отношение г для R таково, что
тр (г) ф г.
Наоборот, предположим, что конечная таблица содержит строку со
всеми а. Эта таблица может рассматриваться как сокращенная запись выра-
жения реляционного исчисления с переменными на доменах:
... ап|(Э М ••• (Я (R (®i) Л Л R (5.1)
где wt — i-я строка начальной таблицы. Формула (5.1) определяет функ-
цию тр, так как тр (г) содержит произвольный кортеж аг ... ап, если и
А в С D Е
«1 feX2 fel3 at feis
а2 &23 Ь24 fess
fesi о2 fess b3i Os
о3 at о.
01 fe«2 fes3 Ьц «5
а)
A В c D E
01 fel2 fel3 at feis
01 a2 fel3 ^24 fess
fesi o2 fel3 b3i o6
fen feia a3 a. o5
01 fe*2 feis b3i a.
6)
A В C D E
O1 fel2 a3 «1 feis
01 o2 a3 01 fess
01 a2 a3 01 a.
01 ^42 a3 O1 a,
01 feg2 a3 01 o.
в)
Рис. 5.3. Применение алгоритма 5.2
только если для каждого i в г имеется некоторый кортеж, содержащий а
в атрибутах из Ri и произвольные значения в других атрибутах.
Поскольку, как предполагалось выше, любое отношение для схемы R,
к которому может быть применена формула (5.1), удовлетворяет зависимо-
стям F, мы можем сделать вывод о том, что эта формула эквивалентна мно-
жеству аналогичных формул, в которых отождествлены некоторые из а и
(или) Ь. Модификации, сделанные в таблице алгоритмом 5.2, таковы, что она
всегда является краткой записью некоторой формулы, значение которой на
отношении г равно тр (г) всякий раз, когда г удовлетворяет F, что легко
может быть доказано индукцией по числу отождествленных символов. По-
скольку конечная таблица содержит строку со всеми а, выражение исчисле-
ния с переменными на доменах для конечной таблицы имеет вид
{ах ... (ах ... ап) Д ...}. (5.2)
168
Значение (5.2) в применении к отношению г для R является, очевидно,
Подмножеством г. Если, однако, г удовлетворяет F, то значение (5.2) есть
тр (г), и по лемме 5.5, п (а), имеем rS тр (г). Таким образом, в случае когда
г удовлетворяет F, получаем г при вычислении по формуле (5.2), и потому
г = trip (г). Иными словами, декомпозиция р обладает свойством соединения
без потерь относительно F .
Алгоритм 5.2 работает для декомпозиций на любое число схем отноше-
ний. Однако при декомпозиции на две схемы можно предложить более про-
стую проверку. С этим вопросом связана следующая теорема.
Теорема 5.5. Если р = (Rx, R2) — декомпозиция R и F — мно-
жество функциональных зависимостей, то р обладает свойством соединения
без потерь относительно F, если и только если Rx n R2 -> Rx — R2 или
Ri Л R2-> R2 — Rx. Заметим, что эти зависимости не обязательно должны
принадлежать заданному множеству F. Достаточно, чтобы они принадле-
жали F+.
Доказательство. Начальная таблица, используемая при при-
менении алгоритма 5.2, показана на рис. 5.4, хотя мы опустили индексы при
Ri—| F2—Ri
Строка для Rx а а ... а aa...albb...b
Строка для а а ... a bb...b\aa... а
Рис. 5.4. Общая таблица для случая двух строк
а и Ь, которые могут быть легко определены и, во всяком случае, являются
несущественными. Нетрудно показать индукцией по числу символов, отож-
дествляемых алгоритмом 5.2, что если Ь в столбце для атрибута А изменяет-
ся на а, то А принадлежит (Rx Л R2)+. Можно также показать индукцией по
числу шагов, необходимых для доказательства с помощью
аксиом Армстронга, что любое b в столбцах для атрибутов из Y изме-
няется на а. Таким образом, строка для Rt становится строкой всех а,
если и только если R2 — Rx s (Rx n R2)+, т. e. Rx Л R2-> R2 — Rx. Ана-
логично строка для R2 становится строкой всех а, если и только если
Ri Л R2 —► Ri — R2. я
Пример 5.9. Предположим, что R — АВС и F = {А -► В). Тогда декомпози-
ция R на АВ и АС обладает свойством соединения без потерь, поскольку АВ Л АС —
— А, АВ — АС = В1, и имеет место зависимость А -► В. Одиако, если осуществить
декомпозицию R на Rx = АВ и Ra = ВС, мы обнаружим, что Rx Л Rt — В и В функ-
ционально не определяет ни Rx — R2 = А, ни Rt — Ri — С. Таким образом, деком-
позиция АВ и ВС ие обладает свойством соединения без потерь относительно F =
= {Л -► В), что можно заметить, рассматривая отиошеиие г = (а&Сг, a^cz} для R.
Тогда лАВ (г) = (a^i, azbj, лвс (г) = {Ь^, 6хса) и лАВ (г)><лвс (г) = {aiMi-
Gx6xca, a2ftiCi, ctzbiCg }• Я
Декомпозиции, сохраняющие зависимости
Как мы уже выяснили, желательно, чтобы декомпозиция обладала свой-
ством соединения без потерь. Это является гарантией того, что любое от-
ношение может быть восстановлено из его проекций. Другое важное свойст-
во декомпозиции р = (Rx, ..., Rft) схемы отношения R заключается в том, что-
бы множество зависимостей F для R было выводимым из проекций F на схе-
мы отношений Ri. Формально проекцией F на множество атрибутов Z,
1 Чтобы понять смысл уравнений, подобных этому, не забывайте, что ЛХЛ2 ...
Ап обозначает {Лх, Л2.Лл).
169
обозначаемой nz (F), называется множество зависимостей X-+Y, в F+,
таких, что XY = Z. (Заметим, что зависимость X -> Y не обязательно при
надлежит F. Она должна принадлежать только F+.) Будем говорить, что
декомпозиция р сохраняет множество зависимостей F, если из объединения
всех зависимостей, принадлежащих лдг (F) для i = 1, 2, ..., k, логически
следуют все зависимости, принадлежащие F.
Стремление к тому, чтобы р сохраняла F, естественно: зависимости
в F могут рассматриваться как ограничения целостности для отношения R.
Если бы из спроецированных зависимостей не следовало F, то мы могли бы
обнаружить такие текущие значения Rit представляющие отношение R в
декомпозиции р = (/?х, .... /?h), которые не удовлетворяют F, даже когда
р обладает свойством соединения без потерь относительно F. С другой сто-
роны, каждое обновление одного из Rt потребовало бы осуществления со-
единения, для того чтобы проверять, не нарушаются ли данные ограничения.
Пример 5.10. Рассмотрим задачу из примера 5.3 с атрибутами ГОРОД,
АДРЕС и ИНДЕКС, для которых были введены сокращенные обозначения С, S и Z.
Были установлены также зависимости CS -* Z и Z -> С. Декомпозиция схемы отноше-
ния CSZ иа CZ и SZ обладает свойством соединения без потерь, поскольку (SZ Г) CZ) -»
-> (CZ — SZ). Однако проекция F = {CS -+ Z, Z С) на SZ дает только тривиальные
зависимости, которые следуют из рефлексивности, в то время как проекция на CZ
дает Z С и тривиальные зависимости. Можно проверить, что нз Z-*-C и тривиальных
зависимостей не следует CS -+• Z, поэтому данная декомпозиция не сохраняет зависи-
мости.
Например, соединением двух отношений, представленных иа рис. 5.5, а и 5.5, б,
является отношение из рис. 5.5, в. Отношение иа рис. 5.5, а удовлетворяет тривиальным
зависимостям, как и любое другое отношение. Отношение на рис. 5.5, б удовлетворяет
тривиальным зависимостям и зависимости Z -*• С. Однако их соединение на рис. 5.5, в
нарушает зависимость CS Z.
S Z С Z
Площадь техники, 545 02138
Площадь техники, 545 02139
Кембридж, Массачусетс 02138
Кембридж, Массачусетс 02139
а)
С
б)
Кембридж, Массачусетс Площадь техники, 545 02138
Кембридж, Массачусетс Площадь техники, 545 02139
в)
Рис. 5.5. Соединение, нарушающее функциональную зависи-
мость
Следует отметить, что декомпозиция может обладать свойством соеди-
нения без потерь относительно множества зависимостей F, но тем не менее
не сохраняет F. Один из таких случаев представлен в примере 5.10. Кроме
того, декомпозиция может сохранять F, не обладая, однако, свойством со-
единения без потерь. Например, это имеет место при F = {А -> В, С D),
R = ABCD и р = (АВ, CD).
5.4. НОРМАЛЬНЫЕ ФОРМЫ СХЕМ ОТНОШЕНИЙ
Определен ряд различных свойств или «нормальных форм» схем отно-
шений с зависимостями. Наиболее важные из них называются «третьей нор-
мальной формой»1 и «нормальной формой Бойса—Кодда». Эти нормальные
1 Существуют первая и вторая нормальные формы. Есть даже четвертая нормаль-
ная форма. Но всему свое время...
170
формы гарантируют, что большинство из проблем избыточности и аномалий,
рассмотренных в разд. 5.1, не будет иметь места.
Чтобы определить указанные термины, договоримся сначала назы-
вать атрибут А в схеме отношения R первичным, если он является элемен-
том какого-либо ключа R (напомним, что может существовать множество
ключей). В противном случае А называется непервичным атрибутом.
Пример 5.11. В схеме отношения CSZ из примера 5.10 все атрибуты яв-
ляются первичными, поскольку при заданных зависимостях CS -> Z и Z -> С ключа-
ми являются CS и SZ.
В схеме отношения ABCD с зависимостями АВ -* С, В -* D и ВС -> А ключа-
ми являются, в чем нетрудно убедиться, только АВ и ВС. Поэтому А, В и С — пер-
вичные атрибуты, a D — непервичный
Третья нормальная форма
Схема отношения R находится в третьей нормальной форме, если не
существует ключа X для R, множества атрибутов Y S R и непервичного
атрибута А из R, не принадлежащего X или Y, таких, что
1. XY справедлива в R
2. Y -> А справедлива в R, но
3. Y X не имеет места в R.
Если Y — подмножество X и поэтому в соответствии с (3) Y является
собственным подмножеством X, то говорят, что в R имеется частичная за-
висимость. Если же Y не является подмножеством X, то в R имеется тран-
зитивная зависимость. Когда R удовлетворяет указанным выше условиям
при Y s X, но не обязательно в других случаях, будем считать, что R на-
ходится во второй нормальной форме1.
Пример 5.12. Схема отношения SAIP из примера 4.12 с зависимостями
SI -> Р и S -> А не находится в третьей нормальной форме, а фактически и во второй
нормальной форме. Пусть X = SI и У = S. Поскольку единственным ключом являет-
ся SI, А — непервичиый атрибут. Тогда справедливы зависимости X -> V и V -> А,
но зависимость Y X, означающая здесь S -* SI, ие имеет места. Заметим, что в этом
случае X Y и Y -* А не только справедливы в /?. Они являются, кроме того, задан-
ными зависимостями. Вообще, достаточно, чтобы зависимости X -► Y и Y -> А следо-
вали из заданного множества зависимостей, даже если оии и не заданы непосредствен-
но.
Рассматриваемая в примере 5.11 схема отношения CSZ находится в третьей нор-
мальной форме. Поскольку все ее атрибуты — первичные, условия для третьей нор-
мальной формы выполняются автоматически.
В качестве примера схемы отношения, находящейся во второй, но ие в третьей
нормальной форме, можно привести схему с атрибутами S (универмаг), I (товар), D
(номер отдела) и М (заведующий). Предположим, что имеют место следующие функцио-
нальные зависимости: SI D (каждый товар в каждом универмаге продается, по край-
ней мере, в одном отделе) и SD -► М (каждый отдел в каждом универмаге имеет одно-
го заведующего). Единственным ключом является SI. Если мы допустим, что X = SI,
Y — SD н А = М, то третья нормальная форма нарушается. Не существует, однако,
каких-либо частичных зависимостей, так как никакое собственное подмножество ключа
SI функционально ие определяет D или М.
1 Упомянем также «первую нормальную форму». Эта форма требует, чтобы домен
для каждого атрибута состоял из неделимых значений, а ие множеств или кортежей
значений нз более элементарного домена или доменов. Мы не рассматривали домены,
состоящие из множеств, и поэтому считаем возможным игнорировать первую нормаль-
ную форму. В действительности отношение для нас — синоним термина «отношение в
первой нормальной форме», используемого в литературе.
171
Мотивировка третьей нормальной формы
Можно предположить, что функциональные зависимости X -> Y пред-
ставляют не только налагаемые на отношения ограничения целостности, но
также и связи, которые требуется хранить в базе данных. Иными словами,
в случае присваивания некоторых значений атрибутам в X важно знать ас-
социируемые с ними значения каждого атрибута из Y. Если имеется час-
тичная зависимость У -> 4, где X — ключ и Y — собственное подмно-
жество X, то в каждом кортеже, используемом для представления ассоциа-
ции Х-значения со значениями других атрибутов, кроме А и атрибутов
в X, должна появиться та же самая ассоциация между Y и А. Эта ситуация
хорошо видна на примере схемы отношения SAIP, где S -> А является
частичной зависимостью, и адрес поставщика должен повторяться для каж-
дого поставляемого им товара. Третья нормальная форма исключает такую
возможность и избыточность, к которой она приводит, а также аномалии
обновления.
При наличии транзитивной зависимости X -> У -> 4 мы не можем ас-
социировать У-значение с Х-значением, если не существует 4-значения,
ассоциированного с У-значением. Эта ситуация приводит к аномалиям
включения и удаления, когда нельзя включить ассоциацию Х-к-У без ассо-
циации У-к-4. Кроме того, если удаляется 4-значение, ассоциированное
с заданным У-значением, мы утрачиваем и ассоциацию Х-к-У. Например,
в отношение со схемой SIDM с зависимостями SI^-D и рассма-
триваемой в примере 5.12, мы не можем записать кортеж для отдела, торгую-
щего в Цветущей долине шляпами, если в этом отделе нет заведующего.
Нормальная форма Бойса — Кодда
Будем говорить, что схема отношения R с зависимостями F находится
в нормальной форме Бойса—Кодда, если всякий раз, когда в R имеет место
зависимость Х->4 и 4 не приналежит X, X включает некоторый ключ R.
Иными словами, допускаются только такие нетривиальные зависимости, в
которых ключ функционально определяет один или более других атрибу-
тов.
Пример 5.13. Схема отношения CSZ из примера 5.11 с зависимостями
CS -> Z и Z -> С, находящаяся в третьей нормальной форме, тем не менее не находится
в нормальной форме Бойса—Кодда. Причина этого заключается в том, что задана за-
висимость Z -» С, ио атрибут Z ие является ключом CSZ,
Как показывает приведенный пример, схема отношения может нахо-
диться в третьей нормальной форме, но не быть при этом в нормальной фор-
ме Бойса—Кодда. Однако отношение в нормальной форме Бойса—Кодда
всегда находится в третьей нормальной форме. Нормальная форма Бойса—
Кодда обладает теми же достоинствами, что и третья нормальная форма —
избавление от аномалий включения и удаления, а также от избыточности.
Вместе с тем из примера 5.13 можно заметить, что нормальная форма Бой-
са—Кодда устраняет некоторые аномалии, не предотвращаемые третьей
нормальной формой. Так, в указанном примере мы не можем записать кор-
теж для города, к которому относится индекс, если мы не знаем адреса с
этим индексом.
Имеет смысл отметить, что отношения, предназначенные для представ-
ления некоторого набора объектов или отображения вида «многие к одному»
между наборами объектов, будут находиться в нормальной форме Бойса—
Кодда, если не существует непредвиденных связей между атрибутами.
172
Теорема 5.6. Если схема отношения R с функциональными за-
висимостями F находится в нормальной форме Бойса—Кодда, то она нахо-
дится и в третьей нормальной форме.
Доказательство. Представим себе, что R находится в нор-
мальной форме Бойса—Кодда, но не в третьей нормальной форме. Тогда
существует частичная или транзитивная зависимость X -> Y -> А, где X —
ключ R, А не принадлежит X или Y и Y -> X не принадлежит F+. В этом
случае Y не включает ключ R, так как иначе имела бы место зависимость
Y -> X. Но А не принадлежит Y. Поэтому Y -> А противоречит условию,
что отношение находится в нормальной форме Бойса—Кодда.
Приведение к нормальной форме Бойса — Кодда
с получением декомпозиции, обладающей свойством
соединения без потерь
Оказывается, что любая схема отношения может быть приведена в
нормальную форму Бойса—Кодда таким образом, чтобы декомпозиция об-
ладала свойством соединения без потерь. Возможно также приведение в
третью нормальную форму с получением декомпозиции, обладающей свой-
ством соединения без потерь и сохраняющей зависимости. Однако схема
отношения может оказаться неприводимой в нормальную форму Бойса—
Кодда с сохранением зависимостей. Схема отношений CSZ из примера 5.13
служит примером такой ситуации. Она не находится в нормальной форме
Бойса—Кодда, поскольку имеет место зависимость Z -> С. Если тем не ме-
нее произвести декомпозицию CSZ таким образом, чтобы во всяком случае
CSZ не являлась одной из схем в декомпозиции, то зависимость CS -> Z
не выводится из спроецированных зависимостей. Прежде чем привести ал-
горитмы декомпозиции, сформулируем некоторые свойства естественных
соединений, которые нам потребуются.
Лемма 5.6.
а) Предположим, что R — схема отношения с функциональными за-
висимостями F. Пусть далее р = (7?ъ ..., — декомпозиция R, обладаю-
щая свойством соединения без потерь относительно F, а Ег для конкрет-
ного i обозначает проекцию F на Rit т. е. множество X Y в F+, таких, что
X и Y являются подмножествами Rt. Наконец, допустим, что ст = (Slt ...,
Sm) — декомпозиция Rit обладающая свойствами соединения без потерь от-
носительно Ft. Тогда декомпозиция R в (Rlt ..., Ri-U Sx, ..., Sm, Ri+1,,...,
Rh) обладает свойством соединения без потерь относительно F.
б) Предположим, что R, F и р имеют свойства, указанные в п. (а). ‘
Пусть т = (/?!, .... Rh, Rh+1, ..., Rn) — декомпозиция R в некоторое мно-
жество схем отношений, которое включает схемы отношений из р. Тогда т
также обладает свойством соединения без потерь относительно F.
Доказательство. Каждое из этих утверждений выводится с
помощью алгебраических выкладок из определения декомпозиции, обладаю-
щей свойством соединения без потерь. Оставим формальные доказательства
для упражнений и ограничимся здесь лишь интуитивными рассуждениями.
Причина справедливости п. (а) состоит в том, что если взять отношение г
для R и спроецировать его на каждое R;, получая отношения г,, а затем
спроецировать rh на Sp, получая отношения sp, то свойство соединения без
потерь обеспечивает возможность восстановления г} путем построения со-
единения отношений Sp. Далее, мы можем посредством соединения отношений
г; восстановить г. Поскольку естественное соединение является ассоциатив-
ной операцией (еще одно упражнение для читателя), порядок, в котором мы
173
выполняем соединение, не имеет значения. Поэтому г восстанавливается не-
зависимо от того, в каком порядке осуществляется соединение отношений
гj a Sp'
Для доказательства п. (б) мы снова аппелируем к ассоциативности есте-
ственного соединения. Заметим, что если проецировать отношение г для R
на Ri, i — 1,2, ..., п, то можно восстановить г соединением его проекций на
Rv ..., Rh. Так как Rlt ..., Rk включают все атрибуты из R, дальнейшие
соединения могут продуцировать лишь подмножества того, что мы уже име-
ем, — отношения г. Но по лемме 5.5а г S тх (г). Поэтому мы не можем за-
кончить процесс менее чем с г, т. е. тх (г) — г. При этом т — декомпозиция,
обладающая свойством соединения без потерь.
Алгоритм 5.3. Приведение в нормальную форму Бойса—Код-
да с получением декомпозиции, обладающей свойством соединения без по-
терь.
Входные данные. Схема отношения R и функциональные за-
висимости F.
Выходные данные. Декомпозиция R, обладающая свойством
соединения без потерь, такая, что каждая схема отношения в декомпози-
ции находится в нормальной форме Бойса—Кодда относительно проекции
F на эту схему.
Метод. Декомпозицию р для R конструируем итеративным методом.
При этом р будет все время обладать свойством соединения без потерь отно-
сительно F. Первоначально р состоит только из R. Если S — схема отноше-
ния из р и S не находится в нормальной форме Бойса—Кодда, то пусть
Х-> А — зависимость, имеющая место в S, где X не содержит ключа S, а
А не принадлежит X. Тогда в S должен существовать некоторый атрибут,
который не принадлежит Л и не принадлежит X. В противном случае X
содержал бы ключ S. Заменим S в р на Sj и S2, где состоит из Л и атри-
бутов X, a S2— из всех атрибутов S, за исключением А.
По теореме 5.5 декомпозиция S на Sx и S2 обладает свойством соедине-
ния без потерь относительно множества зависимостей, спроецированных на
S, поскольку Sx A S2 = X и X -> Sx — S2 = А. По лемме 5.6а р, в кото-
ром S заменено на Зх и S2, обладает свойством соединения без потерь,
если этим свойством обладает р. Поскольку и в S1( и в S2 меньше атрибутов,
чем в S, мы достигнем в конце концов некоторого момента, когда любая
схема отношения в р будет находиться в нормальной форме Бойса—Кодда.
При этом р все еще обладает свойством соединения без потерь, поскольку
начальное р состояло только из R, и все модификации сохраняли свойство
соединения без потерь.
Пример 5.14. Рассмотрим схему отношения CTHRSG, где С — курс, Т —
преподаватель Я — час, R — аудитория, S — студент и G — оценка. Предположим,
что имеют место следующие функциональные зависимости:
С -* Т — каждый курс ведет одни преподаватель;
HR -> С— в аудитории одиовремеиио может читаться только один курс;
НТ ->~ R — преподаватель одновременно может находиться только в одной ау-
дитории;
CS -> G— каждый студент имеет одну оценку по каждому курсу;
HS -> R — студент может находиться только в одной аудитории одновременно.
Единственный ключ для рассматриваемой схемы отношения — HS.
Чтобы привести эту схему отношения к нормальной форме Бойса—Кодда, мож-
но прежде всего рассмотреть зависимость CS -► G, которая нарушает условие, посколь-
ку CS ие содержит ключа. Таким образом, сначала по алгоритму 5.3 произведем деком-
позицию CTHRSG на CSG н CTHflS. Для осуществления дальнейших декомпозиций
необходимо вычислить F+ и спроецировать его на CSG н CTHRS.
174
Заметим, что этот процесс обычно требуёт значительного времени, поскольку раз*
мер F+ может экспоненциально зависеть от размера F. Даже в этом относительно про*
стом примере F+, естественно, содержит все тривиальные зависимости, выводимые по
аксиоме рефлексивности, и, помимо зависимостей из F, некоторые другие нетривиаль-
ные зависимости, например CH -> R, HS -+ С И HR -> Т. После того как получено
F+, выбираем зависимости, которые вовлекают только С, S и G. Они представляют со-
бой множество зависимостей F, спроецированное на CSG. Это множество имеет ми-
нимальное покрытие, состоящее только из зависимости CS G. Все остальные за-
висимости в этом множестве выводятся из иее по аксиомам Армстронга. Проецируем
также F+ на CTHRS. Множество,
TH — R
HS-+ R
полученное в результате проек-
ции, имеет минимальное покры-
тие
С -> Т
HR С
н единственным ключом для
CTHRS является HS.
Легко проверить, что CSG
находится в нормальной форме
Бойса—Кодда относительно
спроецированных на нее зависи-
мостей. Схема отношения CTHRS
должна подвергнуться дальней-
шей декомпозиции. Мы можем
выбрать зависимость С -> Т, что
приведет к разбиению рассматри-
ваемой схемы иа СТ и CHRS.
Минимальными покрытиями для
спроецированных зависимостей
являются: С -► Т для СТ, а также
CH -> R, HS -> R и HR — С для
CHRS. Для последней схемы
единственным ключом является
HS. Отметим, что зависимость
CH -> R требуется в покрытии
CHRS, хотя в CTHRS она выво-
дится из С -> Т и TH -» R.
Здесь СТ находится в нор-
мальной форме Бойса— Кодда, и
еще одна декомпозиция CHRS,
использующая, например, зави-
симость CH -> R, приводит схе-
му полной базы данных к требуе-
мой форме. На рис. 5.6 показаны
Рис. 5.6. Дерево декомпозиции
три декомпозиции с ключами и
минимальными покрытиями для
множеств спроецированных зави-
симостей.
Окончательная декомпозиция CTHRSG — совокупность схем CSG, СТ, CHR
и CHS. Это—неплохой проект базы данных, поскольку четыре его схемы отношений
представляют в виде таблиц соответственно:
1. Оценки студентов по курсам.
2. Преподавателя каждого курса.
3. Часы занятий по каждому курсу, аудиторию для каждого занятия.
4. Расписание курсов (с указанием времени занятий) для каждого студента.
Ради справедливости нужно отметить, что ие всякая декомпозиция порождает
схему базы данных, которая настолько хорошо соответствует нашим интуитивным со-
ображениям о том, какая информация должна быть представлена в виде таблиц в базе
данных. Если, например, на последнем шаге декомпозиции использовать вместо
CH R зависимость HR -> С, то можно получить схему HRS вместо CHS. При этом
HRS представляла бы аудиторию, в которой студент может находиться в заданный час,
а не занятие, иа котором он присутствует. Последнее, несомненно, дает более фунда-
ментальную информацию.
Другая проблема, связанная с декомпозицией, представленной на рис. 5.6, за-
ключается в том, что эта декомпозиция ие сохраняет зависимость TH -► R. Иными
175
словами, из проекции на CSG, СТ, CHR и CHS, которая может быть представлена по*
крытнем
CS^G HR — С
С -+Т HS^C
CH -R
найденным путем взятия минимальных покрытий в каждом Из листьев На рис. 5.6,
не выводится зависимость TH-+R. Например, отношение для CTHRSG, показан-
ное ниже
С Т н R S G
С1 t h Г1 Si gi
са t h ra sa g?
Не удовлетворяет TH -► R. Тем не меиее его проекции иа CSG, СТ, CHR и CHS удов-
летворяют всем спроецированным зависимостям.
Ранее упоминалось, что процесс проецирования зависимостей, когда мы
конструируем F+ из F и далее выбираем зависимости с конкретным множе-
ством атрибутов, может иметь оценку, экспоненциально зависящую от чис-
ла зависимостей в F. Возникает естественное желание узнать, нельзя ли
сделать алгоритм 5.3 на основе другого подхода к декомпозиции так, чтобы
время исполнения его было менее, чем экспоненциальным. Бири и Берн-
штейн [18] доказали, к сожалению, что определение того, находится ли
схема отношения в нормальной форме Бойса—Кодда, является NP-пол-
ной задачей1. Таким образом, весьма маловероятно, что может быть най-
ден существенно лучший алгоритм.
Приведение в третью нормальную форму
с сохранением зависимостей
Как мы видели из примеров 5.10 и 5.13, не всегда возможно привести
схему отношения в нормальную форму Бойса—Кодда и при этом сохранить
зависимости. Тем не менее в любом случае можно найти сохраняющую за-
висимости декомпозицию в третью нормальную форму, о чем свидетельст-
вуют следующие алгоритм и теорема.
Алгоритм 5.4. Приведение схемы отношения в третью нор-
мальную схему с сохранением зависимостей.
Входные данные. Схема отношения R и множество функцио-
нальных зависимостей F, которое мы без потери общности будем считать ми-
нимальным покрытием.
Выходные данные. Сохраняющая зависимости декомпозиции
схемы отношения R, такая, что каждая входящая в нее схема отношения
находится в третьей нормальной форме относительно проекции F на эту
схему.
Метод. Если существует некоторый атрибут в R, участвующий в
левой или правой части какой-либо зависимости из F, то этот атрибут может
в принципе сам по себе образовать некоторую схему отношения и его можно
1 NP-полнота задачи предполагает, Что она по природе своей с большой вероят-
ностью является экспоненциальной. Теория этого вопроса излагается в книге Ахо,
Хопкрофта и Ульмаиа [2], а также Гарэя и Джонсона [72].
176
исключить из Я1. Если в одной из зависимостей F участвуют все атрибуты
R, то выходные данные образует само R. В противном случае декомпози-
ция, образующая выходные данные, состоит из схемы ХА для каждой
зависимости X -+ А в F. Если, однако, в F имеются зависимости X -> Alt
X Аг, .... X-> Ап, то может быть использована схема ХАх ... Ап
вместо ХА t для 1 i п, и такая подстановка обычно является предпочти-
тельной.
Пример 5.15. Рассмотрим вновь схему отношения CTHRSG из примера
5.14. Заданное множество функциональных зависимостей имеет следующее минималь-
ное покрытие:
СТ
HR-+C
НТ ^R
CS-+G
HS R
Алгоритм 5.4 дает множество схем отношений СТ, CHR, HRT, CGS и HRS.
Теорема 5.7. Алгоритм 5.4 дает сохраняющую зависимости де-
композицию, состоящую из схем отношений в третьей нормальной форме.
Доказательство. Так как спроецированные зависимости вклю-
чают покрытие для F, декомпозиция, очевидно, сохраняет зависимости.
Предположим, что в F имеется зависимость X -> А, которая включает все
атрибуты из R, оставшиеся после удаления атрибутов, не участвующих в
какой-либо зависимости. В этом случае мы утверждаем, что R находится в
третьей нормальной форме. Прежде всего замечаем, что X должно быть
ключом R, так как F является минимальным покрытием. Несомненно, име-
ет место зависимость X -> R. Если некоторое собственное подмножество
7 £ X есть ключ, то X -> А может быть заменена в F на Y -> А без изме-
нения замыкания. Это противоречит нашему предположению о том, что
F — минимальное покрытие. Покажем теперь, что R всегда находится в тре-
тьей нормальной форме.
Случай 1. Предположим, что в R существует некоторая транзи-
тивная зависимость V -+ W -> В. Если А не принадлежит V, то пусть Z
состоит из V и атрибутов X, за исключением В и атрибутов W. Так как зави-
симость V W -> В транзитивна, то либо В, либо некоторый атрибут из
W — V не принадлежит А. Поэтому Z — собственное подмножество X. По-
скольку Z = V U (X — W — В) и задана зависимость V -+ W -+ В, име-
ем Z X. Таким образом, X — не ключ R, и мы пришли к противоречию.
Пусть теперь А принадлежит V, a Z Определяется указанным выше способом.
В связи с тем что имеет место зависимость Z-> R, существует некоторое
подмножество U S Z, которое является ключом R. Если А принадлежит
U, то R имеет единственный первичный атрибут, так как X = R —- А
также является ключом. Следовательно, R автоматически находится в тре-
тьей нормальной форме. Если же А не принадлежит U, то U — собственное
подмножество X, которое функционально определяет X. Это обстоятельство
противоречит тому, что X является ключом.
Случай 2. Существует частичная зависимость X У В. Ес-
ли В=/=А, то, поскольку ?£Хв частичной зависимости, X — В есть
собственное подмножество X, которое определяет X. Это противоречит
1 Иногда желательно, чтобы два или более атрибутов, например Л и В, вместе
входили в некоторую схему отношения, даже если не существует связывающей их
функциональной зависимости. Так, может иметься связь вида «многие ко многим»
между А и В. Идея Бернштейна [23] заключается во введении фиктивного атрибута 0
и функциональной зависимости АВ -»• 0 для принудительного создания этой ассоциа-
ции. После завершения проектирования базы данных атрибут 0 исключается.
177
предположению о том, что X — ключ. Если В = А, то Y -> А, и Y — соб-
ственное подмножество X. Снова приходим к противоречию, на этот раз с
тем, что F — минимальное покрытие. Этим мы завершаем доказательство
того, что, если некоторая зависимость в F включает все атрибуты из R,
то R находится в третьей нормальной форме.
Пусть теперь X -*- А представляет собой зависимость в F, которая вклю-
чает не все атрибуты. Мы утверждаем, что ХА находится в третьей нормаль-
ной форме относительно проекции F на ХА. Необходимо только заметить,
что X должно быть ключом ХА, иначе F не будет минимальным покрытием.
Тогда действует тот же аргумент, что и выше, но R заменяется на ХА.
Приведение в третью нормальную форму
с сохранением зависимостей
и соединением без потерь
Мы видели, что можно произвести декомпозицию любой схемы отноше-
ния R на множество схем р = (Rlt ..., Rk), таких, что р обладает соеди-
нением без потерь и каждое Rt находится в нормальной форме Бойса—Код-
да (а следовательно, и в третьей нормальной форме). Мы можем также
выполнить декомпозицию R на множество схем ст = (S1; ..., Sm), таких,
что ст сохраняет множество зависимостей F, и каждое S; находится в тре-
тьей нормальной форме. Можно ли найти декомпозицию, которая имеет оба
эти свойства? Следующая теорема показывает, что это может быть сделано
просто путем присоединения к ст некоторой схемы отношения X, где X
является ключом R.
Теорема 5.8. Пусть ст — декомпозиция R, образованная схема-
ми отношений в третьей нормальной форме и построенная по алгоритму 5.4,
и пусть также X — ключ R. Тогда т = ст и {Л") — декомпозиция R, такая,
что все составляющие ее схемы отношений находятся в третьей нормальной
форме. Эта декомпозиция сохраняет зависимости и обладает свойством со-
единения без потерь.
Доказательство. Легко показать, что если бы существовала
какая-либо транзитивная или частичная зависимость в X, то некоторое
собственное подмножество X функционально определяло бы X, а следова-
тельно, и R. Поэтому X не было бы ключом в данном случае. Таким образом,
X, а также элементы декомпозиции ст, находятся в третьей нормальной фор-
ме. Так как ст сохраняет зависимости, этим свойством обладает, очевидно,
и т.
Для доказательства того что т обладает свойством соединения без по-
терь, применим табличный тест из алгоритма 5.2. Докажем, что строка для
X становится строкой из всех а. Рассмотрим порядок Л1( Л2, ..., Ак, в ко-
тором атрибуты из R — X добавляются к Х+ в алгоритме 5.1. В конце кон-
цов, несомненно, добавляются все атрибуты, так как X — ключ. Далее
индукцией по i доказывается, что столбец, соответствующий Л,, в строке
для X устанавливается в аг в алгоритме 5.2.
Базис i = 0 тривиален. Предположим, что доказываемый результат
справедлив для i — 1. Тогда Лг добавляется к Х+ вследствие некоторой за-
данной функциональной зависимости Y Лг, где Y = X и {Лг, .... Лг_1).
Далее, YAt принадлежит ст, и строки для YAt и X совпадут по Y (они
представляют собой все а) после того, как столбцы Х-строки для Лп ...,
Лг_! сделаются равными а. Таким образом, эти строки будут совпадающи-
ми по Л г во время выполнения алгоритма 5.2. Поскольку /Лг-строка со-
стоит из at, такой же должна быть и Х-строка.
178
Очевидно, в некоторых случаях т не является наименьшим множеством
схем отношений, обладающим свойствами, указанными в теореме 5.8. Мы
можем последовательно удалять по одной схеме отношения из т до тех пор,
пока сохраняются желаемые свойства. В результате получается много раз-
личных схем баз данных, в зависимости от порядка, в котором мы удаляли
схемы отношений, поскольку исключение одной из них может предотвра-
тить исключение других.
Пример 5.16. Возьмем объединение схемы базы данных, продуцированной
для СТHRSG в примере 5.15, с ключом SH и попытаемся получить некоторую декомпо-
зицию, обладающую свойством соединения без потерь и сохраняющую зависимости.
Оказывается, что SH — подмножество HRS, которое является одной нз уже отобран-
ных схем отношений. Таким образом, SH может быть исключено, и схема базы данных
из примера 5.15, т. е. СТ, CHR,HRT, CGS и HRS, будет тем не менее удовлетворять
требованиям. Хотя некоторые собственные подмножества этого множества из пяти схем
отношений представляют собой декомпозиции, обладающие свойством соединения без
потерь, мы можем проверить, что нз спроецированных зависимостей для любых четырех
из них не следует полное множество зависимостей F. Об этом упоминалось в при-
мере 5.15.
5.5. МНОГОЗНАЧНЫЕ ЗАВИСИМОСТИ
В предыдущих разделах предполагалось, что единственным возможным
видом зависимостей данных является функциональная зависимость. На са-
мом деле существует несколько видов зависимостей, и по крайней мере один
из них — многозначная зависимость — заслуживает серьезного изучения.
Предположим, что задана некоторая схема отношения R, а X и Y — подмно-
жества R. Будем говорить, что«Х мультиопределяет Y» или что «существует
многозначная зависимость Y от X», и обозначим этот факт как X >> Y,
если при заданных значениях атрибутов из X существует множество, со-
стоящее из нуля или более ассоциированных значений атрибутов из Y,
и это множество У-значений не связано каким-либо образом со значениями
атрибутов в R — X — Y.
Формально мы считаем, что в R имеет место зависимость X >-У, если
всякий раз, когда г — некоторое отношение для R, a t и s — два кортежа
из г, такие, что t [X] — s [X] (т. е. t и s совпадают по атрибутам X), г со-
держит также кортежи и и о, где:
1. и [X] = v [X] = ИХ] = s[X],
2. и [У] = НУ] и и [R — X — У] = s [R — X — У],
3. v [У] = s (У] и v [R — X — У] = t[R — X — У]1.
Это означает, что можно поменять местами У-значения в t и s с тем,
чтобы получить два новых кортежа, которые также должны принадлежать г.
Отметим, что в приведенном определении не предполагалось, что X и У не
пересекаются.
П р и м е р 5.17. Рассмотрим схему отношения CTHRSG из предыдущего раз-
дела. На рис. 5.7 представлено одно из возможных отношений для данной схемы отно-
шения. В этом простом случае имеется только одни курс с двумя студентами. Однако
здесь можно обнаружить несколько характерных деталей, которые, как мы предпола-
гаем, имеют место в любом отношении для этой схемы отношеиня. Курс может читать-
ся в разные дни недели, каждый раз в различных аудиториях. Любому студенту соот-
ветствует множество кортежей для всех предусмотренных расписанием занятий по всем
курсам. Оценка по курсу повторяется в каждом кортеже.
1 Заметим, что мы могли бы исключить предложение (3). Ойо следует из (1) н (2),
если поменять местами i и s.
179
Таким образом, мы предполагаем, что в общем случае имеет место многозначная
зависимость С -»—>- HR, т. е. имеется множество пар час—аудитория, ассоциирован-
ных с каждым курсом и не ассоциированных с другими атрибутами. Например, если в
формальном определении многозначной зависимости принять
t = Курс 101 Дидвуд Понедельник, 9.00 222 Кланк Хор.
s = KypclOl Дидвуд Среда, 9.00 333 Зонкер Удовл,
то можно предположить, что существует возможность обменять значения атрибутов
(Понедельник, 9.00; 222) из t со значениями (Среда, 9.00; 333) в s с тем, чтобы полу-
чить два новых кортежа;
и = KypclOl Дидвуд Понедельник, 9.00 222 Зоикер Удовл.
о = Курс101 Дидвуд Среда, 9.00 333 Кланк Хор. +
Рис. 5.7 подтверждает, что и и v в действительности принадлежат г.
С T н R S G
KypclOl Дидвуд Понедельник, 9.00 222 Кланк Хор.+
KypclOl Дидвуд Среда, 9.00 333 Кланк Хор.+
KypclOl Дидвуд Пятница, 9.00 222 Кланк Хор.+
KypclOl Дидвуд Понедельник, 9.00 222 Зоикер У довл.
KypclOl Дидвуд Среда, 9.00 333 Зонкер У довл.
KypclOl Дидвуд Пятница, 9.00 222 Зонкер Удовл.
Рис. 5.7. Пример отношения для схемы CTHRSG
Следует подчеркнуть, что зависимость С HR справедлива не из-за того, что
она имела место в одном отношении на рис. 5.7. Она справедлива в силу предположения,
основанного на нашем понимании смысла атрибутов о том, что если какой-либо курс с
читается в час hx в аудитории г1 преподавателем t± для студента slt имеющего оценку
gi, и в час h2 в аудитории г2 преподавателем t2 для студента s^, имеющего оценку g2,
то этот курс читается также и в час h± в аудитории преподавателем /2 Для студента
s2, получившего оценку g2.
Заметим также, что многозначная зависимость С ->-> Н не имеет места. Не
имеет места и зависимость С -»—>- R. Для доказательства рассмотрим отношение г,
представленное на рис. 5.7, с кортежами t и s, приведенными выше. Если бы имела ме-
сто зависимость С ->—>- Н, мы могли бы рассчитывать, что найдется кортеж
KypclOl Дидвуд Понедельник, 9.00 333 Зонкер Удовл.
которого на самом деле нет. Существует, одиако, ряд других многозначных зависимо-
стей, например С ->—>- SG и HR ->-> SG. Имеются, кроме того, тривиальные много-
значные зависимости вида HR ->-> R. Мы докажем также, что из существования каж-
дой функциональной зависимости X -► V следует и существование многозначной за-
висимости X —>—> Y.
Аксиомы функциональных и многозначных зависимостей
Представим теперь надежное и полное множество аксиом, позволяющих
делать заключения о множестве функциональных и многозначных зависи-
мостей на множестве атрибутов U. Первые три аксиомы — это аксиомы Арм-
стронга только для функциональных зависимостей. Мы повторим из здесь.
А1: (рефлексивность дляфункциональныхзависимостей). Если Y £~ X £= U,
то X -> Y.
А2: (пополнение для функциональных зависимостей). Если имеет место
X -> Y и Z s U, то XZ -> YZ.
АЗ: (транзитивность для функциональных зависимостей). Если имеют ме-
сто зависимости X -> Y и Y -> Z, то X -> Z.
180
Следующие три аксиомы применяются к многозначным зависимостям.
А4: (дополнения для многозначных зависимостей). Если X > > Y, то
Х^-> U — X — Y.
А5: (пополнение для многозначных зависимостей). Если Х—>—+Y и V = W,
то WX-+-+VY.
Аб: (транзитивность для многозначных зависимостей). Если X —> Y
и Y ->-> Z, то X ->-> Z — Y.
Имеет смысл сравнить аксиомы А4—Аб с А1—АЗ. Аксиома А4 (пра-
вило дополнения) не имеет аналога для функциональных зависимостей.
Аксиома рефлексивности А1, оказывается, не имеет аналога для многознач-
ных зависимостей. Однако тот факт, что X -*—* Y имеет место, когда Y s X,
вытекает из А1 и следующего правила (аксиома 7, которая будет сформули-
рована позднее): если X -+ Y, то X —Y. Аксиома Аб слабее аналогичной
аксиомы транзитивности АЗ. Более общее утверждение о том, что из X Y
и Y >—* Z следует X > > Z, оказывается несправедливым. Например, мы
видели в примере 5.17, что С HR и, конечно, HR -+-* Н имеют место,
но тем не менее зависимость С->-> Н не существует. Для частичной компен-
сации того, что аксиома Аб слабее АЗ, воспользуемся версией А5, более
строгой, чем аналогичная аксиома пополнения А2 для функциональных за-
висимостей. Мы могли бы заменить А2 следующим: из У и V s W
вытекает WX -> VY, но для функциональных зависимостей это правило лег-
ко доказывается исходя из Al, А2 и АЗ.
Последние две аксиомы связывает функциональные и многозначные за-
висимости:
А7: Если X -* Y, то X ->-> Y.
А8: Если X > > Y, Z S Y, и для некоторого W, непересекающегося с Y,
имеем W -> Z, то X -> Z также имеет место.
Мы не будем приводить здесь Доказательство полноты и надежности
всей системы аксиом А1—А8. Докажем, однако, что некоторые из этих ак-
сиом являются надежными, т. е. что они следуют из определений функцио-
нальных и многозначных зависимостей. Доказательство надежности осталь-
ных аксиом, а также того, что любой справедливый вывод может быть сделан
с использованием аксиом (полнота аксиом), оставляем для упражнений
читателю.
Начнем с доказательства Аб — аксиомы транзитивности для многознач-
ных зависимостей. Допустим, что в некотором отношении г, определенном на
множестве атрибутов U, зависимости X > » Y и Y > Z справедливы, но
X —>—>- Z — У не имеет места. Тогда в г имеются кортежи t и s, где НХ] =
= s [XI, но нет такого кортежа и, что и [X] — t [X], и [Z — Y] = t{Z — У]
и и [U — X — (Z — У)] = s [U — X — (Z — У)]. Поскольку справедлива
зависимость X > > У, кортеж v, удовлетворяющий соотношениям v [X] =
= t [X], v [У] = s [У]mv\U — X — У] = t [U — X — У], принадлежит г.
Итак, v и $ совпадают по У. Таким образом, поскольку У >-Z, в г имеется
кортеж w, для которого w [У] =*= S [У], w [Z] = v [Z] и w [U — У— Z\ =
= sW —Y — Z].
Можно утверждать, что w (X) t [X], так как по атрибутам из
Z П X w совпадает с v, которое совпадает с t. По атрибутам из X — Z w сов-
падает с s и s совпадает с t по X. МОЖНО также утверждать, что w [Z - У] —
= t [Z — У], поскольку w совпадает* с v по Z — У и v совпадает с t по
Z — У. Наконец, мы утверждаем, что w [V] = s [VI, где V — U X -
— (Z — У). В приведенных рассуждениях w, несомненно, совпадает с s по
V —Z, и, манипулируя множествами, мы можем показать, что V П Z
= (У Л Z) — X. Но w совпадает с v по Z и v совпадает с s по У. Поэтому
1>;1
совпадает с s по V A Z, а также по V — Z. Следовательно, w совпадает с s
по V. Если рассмотреть определение и, то можно теперь увидеть, что w = и.
Но мы утверждали, что w принадлежит г. Поэтому и принадлежит г вопре-
ки нашему предположению. Таким образом, в конце концов X ->—> Z — У,
и аксиома А6 доказана.
Докажем теперь аксиому А8. Пусть имеется отношение г, в котором
имеют место X > У, и W -> Z, где Z Е Y и W П Y — пусто, но X -> Z
несправедливо. Тогда в г существуют кортежи s и t, такие, что s [X] = t [X],
но s [Z] у= / [Z], Применяя X -*-+• У к s и t, имеем, что в г существует такой
кортеж и, что и [X] = t [X] = s [X], «[У] = НИ и u[U — X — У] =
s [(7 — X — У]. Поскольку W Л У — пустое множество, и и s совпадают
по W. Так как Z £= У, и и t совпадают по Z. Наконец, из того что s и t
не совпадают по Z, следует несовпадение кортежей и н s по Z. Но это проти-
воречит тому, что W -> Z, поскольку и и «совпадают по W, но не совпадают
по Z. Отсюда зависимость X -> Z не может не иметь места, и правило А8
доказано.
Таким образом, частично доказана следующая теорема.
Теорема 5.9. (Бири, Фейгин и Говард [20]). Аксиомы А1—А8
являются надежными и полными для функциональных и многозначных за-
висимостей. Другими словами, пусть D — множество функциональных и
многозначных зависимостей на множестве атрибутов U, и £>+ — множество
функциональных и многозначных зависимостей, логически выводимых из D
в том смысле, что каждое отношение над U, которое удовлетворяет D, удо-
влетворяет также зависимостям из D+. Тогда D+ в точности является мно-
жеством зависимостей, которые выводятся из D по аксиомам А1—А8.
Остальная часть доказательства этой теоремы оставляется читателю в
качестве упражнения.
Дополнительные правила вывода
для многозначных зависимостей
Существует ряд других правил для функциональных и многозначных за-
висимостей. Конечно, для функциональных зависимостей по-прежнему при-
менимы сформулированные в лемме 5.2 правила объединения, псевдотран-
зитивности и дексцЦдозиции. Приведем здесь некоторые из этих «других»
правил.
1. (П разило объединения для многозначных зависимостей). Если Х-*-> У
и X ->-> Z, то X YZ.
2. (Правило псевдотранзитивности для многозначных зависимостей).
Если X> У и WY-+-+Z, то WX-+-+Z — WY.
3. (Смешанное правило псевдотранзитивности). Если X -»—>• У и
ХУ ->Z, то X -> Z — У.
4. (Правило декомпозиции для многозначных зависимостей). Если
X у и X Z, то X У П Z, X У — Z и X Z — Y.
Доказательство справедливости перечисленных правил мы оставляем
читателю в качестве упражнения. Методы доказательства подобны исполь-
зованным выше для аксиом А6 и А8.
Следует отметить, что правило декомпозиции для многозначных зави-
симостей слабее соответствующего правила для функциональных зависи-
мостей. Последнее позволяет непосредственно вывести из X -> У, что
X -> А для каждого атрибута А в У. Правило для многозначных зависимо-
182
стей дает возможность лишь из X ► Y сделать вывод о том, что X А
при существовании некоторого Z, удовлетворяющего условиям: X ->—> Z
и либо Z n Y — А, либо Y — Z = А.
Однако правило декомпозиции для многозначных зависимостей и пра-
вило объединения позволяют сформулировать следующее утверждение о
множествах Y, таких, что X ->--->- Y для заданного X.
Теорема 5.10. Пусть U — множество всех атрибутов. Тогда мож-
но построить разбиение U — X на множества Ylt Г2, ..., Yh, такое, что при
Z s U — X имеем X ->-->- Z, если и только если Z есть объединение не-
которых Y i.
Доказательство. Построим начальное разбиение U — X, по-
местив все атрибуты U — X в один блок. Предположим, что на некотором
шаге получено разбиение IFi, ..., Wn и X ->--* Wt для i = 1, 2, .... п. Если
X ->-> Z и Z не является объединением некоторых Wi, заменим каждое
W,, такое, что Wi fl Z и Wi —Z оба непустые, множествами W, П Z и
Wt — Z. По правилу декомпозиции X > Wi П Z и X ->--> W, — Z.
Поскольку невозможно осуществлять разбиение конечного множества ат-
рибутов бесконечно, мы найдем в конце концов, что каждое Z, такое, что
X ->—>-Z, является объединением некоторых блоков разбиения. По правилу
объединения X мультиопределяет объединение какого-либо множества бло-
ков.
Будем называть множества F1( ..., Yk, сконструированные выше для
X из множества функциональных и многозначных зависимостей D, бази-
сом зависимостей для X (относительно £>). Заметим, что если X Уг, то
Yt должно состоять из одного-единственного атрибута в соответствии с пра-
вилом декомпозиции для функциональных зависимостей и аксиомой А7 (каж-
дая функциональная зависимость является многозначной).
Пример 5.18. Мы установили в примере 5.17, что С-*-* HR, Таким обра-
зом, по правилу дополнения С -+—► TSG. Известно, также, что С -> Т. Таким образом,
по аксиоме А7 С -» -» Т. Согласно правилу декомпозиции С >• 30. Можно проверить,
что С не мультиопределяет никакого единственного атрибута, за исключением Т илн
самою С. Таким образом, базисом зависимостей для С является Т, HR и SG.
Замыкание множества функциональных
и многозначных зависимостей
При заданном множестве функциональных и многозначных зависимо-
стей/? мы хотели бы найти множествоD+ всех функциональных и многознач-
ных зависимостей, логически выводимых из D. Можно вычислить D+, на-
чиная с D и применяя аксиомы А1—А8 до тех пор, пока будет возможен вы-
вод новых зависимостей. Этот процесс, однако, может потребовать времени,
экспоненциально зависящего от числа зависимостей в О. Часто требуется
только знать, следует ли из D конкретная зависимость X Y или X ->—> Y.
Такой вопрос возникает, например, если нужно исключить избыточные за-
висимости.
Чтобы проверить, имеет ли место многозначная зависимость X Y,
достаточно определить базис зависимостей X и посмотреть, является ли
Y — X объединением каких-либо его множеств. Так, в примере 5.18 мы
знаем, что С -•>->- CTSG, поскольку TSG есть объединение Т и SG. К тому
же, имеет место зависимость С > > HRSG. Но С т->—>- TH несправедливо,
так как TH пересекается с блоком HR базиса зависимостей, однако не вклю-
чает все атрибуты HR. Для Вычисления базиса зависимостей X относительно
D в соответствии с теоремой Бири [17] достаточно найти базис относительно
множества многозначных зависимостей М, где М состоит:
183
1) из всех многозначных зависимостей в D и
2) из множества многозначных зависимостей X .,,, X > > Ап для
каждой функциональной зависимости X -> Y в D, где Y = ... Ап и
Лп ..., Ап — атрибуты.
Другая теорема Бири [17] дает способ выделения нетривиальных
функциональных зависимостей из базиса зависимостей, вычисленного отно-
сительно множества многозначных зависимостей М. Можно показать, что
если X не включает А, то X -> А имеет место, если и только если
1) А — одноэлементное множество из базиса зависимостей X относительно
множества зависимостей М и
2) существует некоторое множество атрибутов Y, не включающее А, такое,
что У -> Z принадлежит D и А принадлежит Z.
Кроме того, Бири [17] дает алгоритм с полиномиальным временем для
вычисления базиса зависимостей X относительно М.
Алгоритм 5.5. Вычисление базиса зависимостей.
Входные данные. Множество многозначных зависимостей М
на множестве атрибутов U и множество X S U.
Выходные данные. Базис зависимостей X относительно М.
Метод.
1. Пусть Т — множество множеств Z s U, таких, что для некоторого
W -*—> Y в М имеем W Е X, и Z есть либо Y — X, либо U — X — Y.
2. До тех пор пока Т не превратится в совокупность непересекающихся мно-
жеств, будем находить в нем очередную пару пересекающихся множеств
Zi и Z2 и заменять ее множествами ZY — Z2, Z2 — Ztv. Zx f] Z2, отбрасывая
пустое множество в том случае, если одно из Zj и Z2 содержится в другом.
Пусть в результате мы получили совокупность множеств S.
3. До тех пор пока возможны изменения в S, будем находить зависимости
V > > W в М и некоторое множество Y в S, такие, что Y пересекается с
W, но не пересекается с V. Заменяем УвЗнаУп^иУ — W.
4. Окончательно полученная совокупность множеств S есть базис зависи-
мостей для X.
Поскольку шаги (2) и (3) вызывают только разбиение множеств и за-
вершаются, когда расщепление больше не может быть сделано, ясно, что
для выполнения алгоритма 5.5 требуется время, полиномиально зависящее
от размера М и U. В самом деле, внимательная реализация позволяет испол-
нять алгоритм за время, пропорциональное числу зависимостей в М, ум-
ноженному на куб числа атрибутов в U. Доказательство этого факта, а так-
же корректности алгоритма 5.5 можно найти в работе Бири [17].
Соединение без потерь
Алгоритм 5.2 помогает определить, когда декомпозиция (Л\, ..., Rk)
схемы отношения R обладает свойством соединения без потерь в предполо-
жении, что в отношениях для Д существуют только функциональные за-
висимости. Этот алгоритм может быть обобщен на случай существования мно-
гозначных зависимостей следующим образом:
1. Строим таблицу из величин а и Ь, как в алгоритме 5.2.
2. Строим совокупность таблиц, считая некоторую таблицу Т уже построен-
ной и либо а) отождествляя два символа вследствие функциональной за-
висимости, как и в алгоритме 5.2, либо б) выбирая многозначную зависи-
мость X > Y и две строки t± и t2 из некоторой таблицы, таких, что
[X] = t2 [X], и добавляя строку и, где и [X] = [X], и [У] = [У]
и и [/? — X — Y] = t2 [7? — X — У], если и уже не принадлежит Т.
184
3. Поскольку не создаются никакие новые а и Ь, может существовать толь-
ко конечное число таких таблиц. Если какая-либо из них имеет строку из
всех а, то рассматриваемая декомпозиция схемы отношения обладает свой-
ством соединения без потерь1, в противном случае это не так.
Однако в случае декомпозиции R на две схемы существует значительно
более простой тест на соединение без потерь.
Теорема 5.11. Пусть R— схема отношения и р = (Rlt R2)—
декомпозиция R. Пусть также D —множество функциональных и много-
значных зависимостей на атрибутах R. Тогда р обладает свойством соеди-
нения без потерь, если и только если Rr п R2 -> Ri — R2 (или, что эк-
вивалентно, по правилу дополнения RjClRu-*-> R2— Ri).
Доказательство, р обладает свойством соединения без потерь,
если и только если для любого отношения г с множеством зависимостей D
и любых двух кортежей t и s из г кортеж и, удовлетворяющий условиям
и [Ril = t [RJ и и [R2] = s IR2], принадлежит г, если он существует. Но
и существует, если и только если t [Rx fl R2] — s [Rj p R2L Таким образом,
принадлежность кортежа и отношению г в точности определяется условием
Ri П R2-*-> Ri—R2 или, что эквивалентно, R± Г) R2 > > R2 — Rx-
Заметим, что теорема 5.11 для случая, когда зависимости являются
только функциональными, следует из теоремы 5.5 и аксиомы А7. Однако
теорема 5.5 вообще неприменима, если существуют многозначные зависи-
мости.
5.6. ЧЕТВЕРТАЯ НОРМАЛЬНАЯ ФОРМА
Существует обобщение нормальной формы Бойса—Кодда, называемое
четвертой нормальной формой, которое применяется к схемам отношений
с многозначными зависимостями. Пусть R — схема отношения и D — мно-
жество зависимостей, имеющих место в R. Будем говорить, что R находится
в четвертой нормальной форме, если всякий раз, когда существует много-
значная зависимость X -+ ->- Y, где Y — не пусто и не является подмно-
жеством X, и XY состоит не из всех атрибутов R, X содержит какой-
либо ключ R. Определение понятия «ключа» не изменилось в связи с пред-
ставлением многозначных зависимостей. Оно по-прежнему означает множе-
ство атрибутов, которое функционально определяет R.
Заметим, что в случае, когда D включает только функциональные
зависимости, если R находится в четвертой нормальной форме, оно находит-
ся и в нормальной форме Бойса—Кодда. Для такого случая X -+ ->- Y долж-
но означать, что X -> У. Предположим, что R не находится в нормальной
форме Бойса—Кодда, так как существует некоторая функциональная зави-
симость X -> А, где X не содержит никакого ключа. Если ХА = R, то,
без сомнения, X включает какой-либо ключ. Следовательно, ХА не вклю-
чает всех атрибутов, и нарушение четвертой нормальной формы зависимо-
стью X —> А, представляющей собой специальный случай многозначной
зависимости X > >- Y, является непосредственным.
Мы можем найти декомпозицию р = (Rlt ..., Rh) схемы отношения R,
обладающую свойством соединения без потерь относительно D, такую, что
каждое R, находится в четвертой нормальной форме. Для этого поступим сле-
дующим образом. Начнем с р, состоящего только из R, как в алгоритме 5.3
(приведение к нормальной форме Бойса—Кодда). Если в р существует не-
1 Относительно заданного множества зависимостей D, имеющих место для R. —
Примеч. ред.
185
которая схема отношения, не находящаяся в четвертой нормальной форме
относительно D, спроецированного на S1, то в 5 должна существовать за-
висимость X -» > У, где X не содержит какого-либо ключа S, У — не
пусто и не является подмножеством X, и ХУ S. Можно предположить,
что X и У не пересекаются, поскольку зависимость X > > У — X следует
из X ->-> У по аксиомам Al, А7 и правилу декомпозиции. Заменим тогда
S двумя схемами отношений Sj = ХУ и S2 = S — Ус числом атрибутов,
меньшим, чем у S. Поскольку Sj П5а->->Sr — S2, соединение Sx и S2
является по теореме 5.7 соединением без потерь относительно D, спроеци-
рованного на S.
Оставляем читателю в качестве упражнения доказательство того, что
повторное выполнение декомпозиции, рассмотренной выше, продуцирует
множество схем отношений, которые имеют соединение без потерь относи-
тельно D. Остается невыясненной одна важная деталь: как при заданных
R, D и S s R определить множество зависимостей в S, т. е. проекцию D
на S. Теорема Ахо, Бири и Ульмана [1] утверждает, что это множество мож-
но найти следующим образом:
1. Вычислить D+.
2. Для каждого X —> У в D+, если X S, то в S имеет место зависимость
X-+Y n S2.
3. Для каждого X ->—> У в D+, если X S S, то в S имеет место зависимость
А->-> У Л S.
4. Из того факта, что D остается в силе для R, не может быть выведено ни-
каких иных зависимостей для S.
Пример 5.19. Снова исследуем схему отношения CTHRSG, введенную в
примере 5.14. Ранее уже указывалось минимальное покрытие
С Т CS-+G
HR -> С HS-^R
НТ — R
для соответствующих функциональных зависимостей. Оказывается, что одна много-
значная зависимость С ->-> HR вместе с указанными выше функциональными зависи-
мостями позволяет вывести все многозначные зависимости, справедливость которых нам
интуитивно ясна. Мы видели, например, что из С -*•-+ HR и С -* Т следует зависимость
С ->—»- SG. Известно также, что HR -> СТ, поэтому HR СТ. По правилу дополне-
ния HR SG, т. е. для заданных часа и аудитории существует ассоциированное
с ними множество пар (студент, оценка), где студент числится в списке слушателей
курса, который читается в этой аудитории в этот час, а оценка получена им за усвое-
ние данного курса. Читателю предлагается провести дальнейшее исследование множе-
ства многозначных зависимостей, выводимых из пяти заданных функциональных зави-
симостей и одной многозначной зависимости.
Чтобы привести схему отношения CTHRSG в четвертую нормальную форму,
можно начать, например, с зависимости С ->—>- HR, которая нарушает условия этой
формы, поскольку С не содержит ключа. Вспомним, что SH является единственным
ключом для CTHRSG. В результате декомпозиции CTHRSG получим CHR и CTSG.
Схема отношения CHR имеет ключ HR. Многозначная зависимость С -+-> HR не на-
рушает четвертой нормальной формы для CHR, так как ее левая и правая части вместе
1 Позднее мы обсудим, как найти проекцию множества функциональных и много-
значных зависимостей.
2 Заметим, что, поскольку X -> Y fl S также принадлежит £>+, это правило
эквивалентно рассмотренному ранее правилу проецирования функциональных зави-
симостей.
186
содержат все атрибуты CHR. Никакие другие спроецированные иа CHR функциональ-
ные или многозначные зависимости не нарушают четвертой нормальной формы. По-
этому дальнейшей декомпозиции CHR не требуется.
Для CTSG дело обстоит не так. Единственный ключ здесь—CS, но тем не менее
имеется многозначная зависимость С -»—► Т, которая следует из зависимости С Т.
Поэтому мы заменяем CTSG на СТ и CSG. Обе последние схемы отношений находятся
в четвертой нормальной форме относительно спроецированных на них зависимостей.
Поэтому получаем декомпозицию CHR, СТ и CSG, обладающую свойством соединения
без потерь, и все схемы отношений находятся в четвертой нормальной форме.
Интересно отметить, что когда в примере 5.14 мы приводили CTHRSG к нор-
мальной форме Бойса—Кодда, в результате были получены эти три схемы отношений,
а также схема CHS. Если ие учитывать многозначную зависимость С ->—>- HR, деком-
позиция р = (CHR, СТ, CSG] может не обладать свойством соединения без потерь.
Но если принять во внимание С -+—> HR, по теореме 5.11 легко доказать, что указан-
ная декомпозиция обладает этим свойством. В качестве упражнения читатель должен
найти такое отношение г =“ для СТHRSG, что (г) =/= г, и, кроме того, г удовлетворяет
всем данным функциональным зависимостям (но, конечно, не зависимости С ->—>-HR).
Встроенные многозначные зависимости
При попытке приведения схемы отношения R в четвертую нормальную
форму возникает еще одно осложнение. Могут существовать некоторые мно-
гозначные зависимости, которые, по нашему предположению, справедливы
для проекции любого вероятного отношения г для R на подмножество
X s R, но тем не менее мы не предполагаем, что эти зависимости имеют
место в самом г. Такая зависимость называется встроенной в /?, и следует
быть осторожным при записи всех ограничений, которые, как мы считаем,
имеют место в отношениях г для R, чтобы не проигнорировать эту встроен-
ную многозначную зависимость. Нужно заметить, что встроенных функцио-
нальных зависимостей не существует. Легко показать, что если зависимость
Y Z имеет место, когда любое вероятное отношение г для R проецирует-
ся на X, то эта зависимость также имеет место в R. Такое утверждение не-
справедливо для многозначных зависимостей, что подтверждается следую-
щим примером.
Пример 5.20. Предположим, что имеются атрибуты С (курс), S (студент)
Р (подготовительный курс) и Y (год, в Котором студент слушал подготовительный курс).
Единственная нетривиальная функциональная или многозначная зависимость —
SP -* Y. Поэтому можно осуществить декомпозицию CSPY, получив в результате
CSP и SPY. Эти схемы, очевидно, находятся в четвертой нормальной форме.
Многозначная зависимость С * S не имеет места. Например, отношение г
для CSPY может содержать кортежи
Курс402 Джойс КурсЗП 1978
Курс402 Смит Курс401 1979
но тем не менее в нем может не быть кортежа
Курс402 Джонс Курс401 1979
По всей вероятности, Джонс прослушал курс 401, поскольку это — необходимое
условие для зачисления его на курс 402, но, возможно, он слушал курс 401 ие в 1979 г.
Подобным же образом в CSPY не имеет места зависимость С >- Р.
Если, однако, спроецировать любое законное отношение для CSPY на CSP, то
можно было бы предположить существование С > S. По правилу дополнения за-
висимость С ->-+ Р имела бы место при условии, что от зачисленного в списки слушате-
лей студента требовалось когда-либо прослушать каждый подготовительный курс для
данного курса. Таким образом, С > S и С Р являются встроенными многознач-
ными зависимостями для R. В результате CSP в действительности не находится в чет-
вертой форме, и следует выполнить его декомпозицию на CS и СР. Эта замена позволя-
ет избежать повторения имени студента для всех подготовительных курсов данного
курса, в списках которого он числится.
187
Интересно обратить внимание на то, что декомпозиция р = (CS, СР, SPY) обла-
дает свойством соединения без потерь, если мы признаем, что С —>—+ S является встро-
енной зависимостью для CSP. В таком случае при любом заданном отношении г для
CSPY, которое удовлетворяет SP Y и зависимости С -•—>- S в CSP, можно доказать,
что (г) = г. Однако это нельзя доказать, предполагая только функциональную за-
висимость SP -> Y. Читатель в качестве упражнения может найти какое-либо отноше-
ние г, удовлетворяющее SP -*• Y и не удовлетворяющее встроенной зависимости, для
которого тр (г) =/= г.
УПРАЖНЕНИЯ
5.1. Предположим, что мы имеем для инвестиционной фирмы базу данных, со-
стоящую из следующих атрибутов: В (маклер), 0 (контора маклера), / (вкладчик),
S (акции), Q (количество акций, которыми владеет вкладчик) и D (дивиденд, выплачи-
ваемый по акции).
а) Найдите ключ для схемы отношения R = BOSQID.
б) Сколько ключей имеет схема отношения Р? Докажите правильность получен-
ного ответа.
в) Приведите R в нормальную форму Бойса—Кодда таким образом, чтобы полу-
ченная декомпозиция обладала свойством соединения без потерь.
г) Приведите R в третью нормальную форму таким образом, чтобы получить де-
композицию, обладающую свойством соединения без потерь и сохраняющую зависимо-
сти.
5.2. Предположим, что мы решили представлять схему отношения R из упраж-
нения 5.1 двумя схемами 1SQD и IBO. Какую избыточность и какие аномалии вы пред-
видите?
5.3. Пусть вместо этого R представляется схемами отношений SD, IB, ISQ и
ВО. Обладает ли данная декомпозиция свойством соединения без потерь?
5.4. Допустим, что мы представляем R из упражнения 5.1 с помощью ISQ, IB,
SD и ISO. Найдите минимальные покрытия для зависимостей (из упражнения 5.1),
спроецированных на каждую из этих схем. Определите минимальное покрытие для объе-
динения спроецированных зависимостей. Сохраняет ли зависимости такая декомпози-
ция?
5.5. В базе данных из упражнения 5.1 заменим функциональную зависимость
S -> D многозначной зависимостью S -»—► D, т. е. D будет теперь представлять «ис-
торию» дивидендов акций.
а) Найдите базис зависимостей I.
б) Найдите базис зависимостей BS.
в) Приведите R в четвертую нормальную форму.
* 5.6. Завершите доказательство теоремы 5.5. Для этого дайте формальное дока-
зательство того, что в строку для Rt а записывается, если и только если /?1П -> А.
5.7. Завершите доказательство леммы 5.5. Для этого покажите, что если г с s,
то (г) с (s).
5.8. В примере 5.10 мы утверждали, что из Z С не следует CS->-Z. Докажите
это утверждение.
5.9. В конце разд. 5.3 утверждалось, что р = (АВ, CD) является декомпозицией
схемы отношения ABCD, сохраняющей зависимости, но не обладающей свойством со-
единения без потерь при условии, что заданы зависимости А -> В и С -> О. Проверь-
те это утверждение.
** 5.10. Закончите доказательство теоремы 5.9- Покажите, что аксиомы А1—А8
являются надежными и полными.
* 5.11. Проверьте правила объединения, псевдотранзитивности и декомпозиции
для многозначных зависимостей.
* 5.12. Дайте формальное доказательство леммы 5.6 а) о том, что результат пос-
ледовательности декомпозиций, обладающих свойством соединения без потерь, сам об-
ладает этим свойством. Докажите также лемму 5.6 б): добавление схем (без новых атри-
бутов) к декомпозиции, обладающей свойством соединения без потерь, сохраняет это
свойство декомпозиции.
* 5.13. Проверьте утверждение в примере 5.20 о том, что существует такое от-
ношениег, удовлетворяющее зависимости SP К,чтолс5 (г)><лср (r)><nspy (г)=£
=0= г. Проверьте также, что это отношение не удовлетворяет зависимости С S
в CSP.
* 5.14. Интересная перспектива состоит в том, что после декомпозиции схемы
отношения R на множество схем (Rt,..., Rk) мы можем формулировать запросы, как
188
если бы R существовало в базе данных, используя при необходимости соединение Rj
для реализации запроса. Пусть в запросе участвует множество атрибутов S С R.
Разработайте как можно более эффективный алгоритм для нахождения наименьшего
подмножества множества {R1( R^}, соединение схем которого включает S, такое,
что соединение элементов этого подмножества обладает свойством соединения без по-
терь.
* 5.15. Другой подход к проблеме, высказанной в предыдущем упражнении,
состоит в том, чтобы сохранить дерево декомпозиции, построенное алгоритмом 5.3
при приведении R в нормальную форму Бойса—Кодда. Если в некотором запросе уча-
ствует множество атрибутов 5, найдите узел в дереве с минимальным числом листьев,
являющихся его потомками, такой, что схемы отношений в этих листьях включают все
атрибуты из S. (Заметим, что соединение потомков любого узла в дереве должно быть
соединением без потерь.) Приведите эффективный алгоритм нахождения такого узла.
* 5.16. Определите относительные достоинства и недостатки подходов, представ-
ленных в общих чертах в упражнениях 5.14 и 5.15.
* * 5.17. Покажите WP-полноту следующих задач:
а) Определить, имеет ли схема отношения ключ размера k или менее.
б) Определить, находится ли схема отношения в нормальной форме Бойса—
Кодда.
Библиографические замечания
Функциональные зависимости были впервые исследованы Коддом [42]. Аксио-
мы функциональных зависимостей впервые даны Армстронгом [8]. Использованные
здесь аксиомы предложены Бири, Фейгином и Говардом [20]. Алгоритм 5.1 вычисления
замыкания множества атрибутов заимствован у Бернштейна [24]. Алгоритм 5.2 провер-
ки на соединение без потерь — из работы Ахо, Бири и Ульмана [1]. Теорема 5.5 (спе-
циальный случай соединения двух отношений) была доказана в части «если» Делобелем
и Кейси [54] и в противоположном «направлении» Риссаненом [138].
Третья нормальная форма определена Коддом в [42], а нормальная форма Бой-
са— Кодда в [41]. Приведение к третьей нормальной форме с сохранением зависимостей
(алгоритм 5.4) рассматривается Бернштейном [23], хотя он использует «синтетический»
подход и начинает проектирование схемы не с универсального отношения. Теорема 5.8,
позволяющая привести отношение в третью нормальную форму так, чтобы декомпози-
ция обладала свойствами соединения без потерь и сохранения зависимостей, доказана
в работе Бискапа, Дейэла и Бернштейна [26]. Связанные с этим результаты получены
также Осборном [127]. Проблема эквивалентности декомпозиций заданных отношений
была решена Бири, Мендельзоном, Сейгивом и Ульманом [21]. Линг и Томпа [106]
обобщили понятие третьей нормальной формы с целью учета избыточности в рамках
нескольких различных схем отношений.
Многозначные зависимости были предложены независимо Фейгином [65], Делобе-
лем [53] и Заниоло [183], хотя эта концепция упоминалась ранее в тезисах Делобеля в
1973 г. Аксиомы для многозначных зависимостей взяты из работы Бири, Фейгииа и
Говарда [20]. Вопрос о независимости подмножеств этих аксиом был рассмотрен Мен-
дельзоиом [117]. В то же время Бискап [25] показал, что если йе допускается универ-
сальное отношение, то они образуют без аксиомы дополнения надежное и полное мно-
жество. Базис зависимостей и алгоритм 5.5 обсуждаются Бири [17]. Хегихара и др.
[82] предложили более эффективный метод проверки, выводится ли данная многознач-
ная зависимость из других. Встроенные многозначные зависимости были рассмотрены
Фейгином [65], Делобелем [53], а также Танакой, Камбаяси и Ядзимой [166].
Многозначные зависимости являются специальным случаем зависимости соеди-
нений, где от соединения п отношений для некоторого п > 2 требуется, чтобы оно бы-
ло соединением без потерь (Риссанен [139]). Многозначная зависимость соответствует
случаю п = 2. Фейгин [67] дал «пятую» нормальную форму, основываясь на отсутствии
нетривиальных зависимостей соединения в схеме отношений. В дальнейшем он усилил
этот результат [68], показав, что возможно осуществить декомпозицию схем отношений
так, чтобы единственными оставшимися зависимостями были функциональные зависи-
мости неключевых атрибутов от ключа и ограничения, отражающие ограниченные раз-
меры доменов для атрибутов.
Проблема тестирования на соединение без потерь при заданных многозначных и
функциональных зависимостях была рассмотрена Ахо, Бири и Ульманом [1], в то вре-
мя как Мейер, Мендельзон и Сейгив [113] обратились к случаю, когда существуют
и зависимости соединений. Лид и Демерс [108] предложили более эффективный способ
тестирования иа соединение без потерь.
189
Проблема адекватности декомпозиции рассмотрена с нескольких точек зрения.
Арора и Карлсон [9] рассмотрели условия соединения без потерь и сохранения зависи-
мостей как понятие адекватности, а Риссанен [138] определил декомпозицию как име-
ющую независимые компоненты, если существует взаимно-однозначное соответствие
между отношениями для универсальной схемы, которая удовлетворяет зависимостям,
и проекциями отношений, удовлетворяющими спроецированным зависимостям. Мейер,
Мендельзон, Садри и Ульман [ 112[ показали, что эти понятия эквивалентны для функ-
циональных, но не для многозначных зависимостей.
Условия, налагаемые на отношения, соответствующие зависимости соединений,
определенной на их схемах отношений, исследованы Никола [123], а также Мендель-
зоном и Мейером [118].
Обсуждаемой в упражнениях 5.14 и 5.15 проблеме нахождения соединений без
потерь, охватывающих атрибуты запроса, посвящены работы Шенка и Пинкерта [147]
и Камбаяси [95].
Для ряда задач, касающихся проблематики данной главы, доказана их NP-пол-
нота. Например, МР-полными являются задачи, в которых проверяется, находится ли
некоторая схема отношения в нормальной форме (Бири и Бернштейн [18]), и определя-
ется ключ минимального размера для схемы отношения (Лакизи и Осборн [109]).
Полезный обзор по проектированию реляционных баз данных с дополнительной биб-
лиографией подготовлен Бири, Бернштейном и Гудмэном [19].
ГЛАВА 6
ОПТИМИЗАЦИЯ ЗАПРОСОВ
Языки запросов высокого уровня, подобные рассмотренным в гл. 4,
позволяют записывать запросы, для исполнения которых требуется много
времени. Время их исполнения может быть в значительной степени сокра-
щено, если процессор языка запросов перефразирует запрос перед его ис-
полнением. Такие улучшения принято называть «оптимизацией», хотя
перефразированный запрос не обязательно оказывается оптимальным из
всех возможных способов его реализации, и более подходящим был бы тер-
мин «улучшение» или «усовершенствование». В настоящей главе мы будем
изучать методы оптимизации выражений реляционной алгебры и выражений
реляционного исчисления. Особенно важное значение имеет исследование
выражений, которые включают соединение или декартово произведение с
последующим оператором селекции и, возможно, проекции, поскольку они
используются в весьма часто применяемых типах запросов и в наибольшей
степени чувствительны к оптимизации. В разд. 4.3 было показано, как
можно упростить один из таких запросов.
6.1. ОБЩИЕ ЗАМЕЧАНИЯ ОБ ОПТИМИЗАЦИИ
Прежде всего может возникнуть вопрос, почему некоторые запросы
требуют для исполнения значительного времени? Главным «преступником»
по крайней мере, в языках запросов, основанных на реляционной модели,
является запрос, который включает соединение или декартово произведение
либо эквивалентную конструкцию в реляционном исчислении. Рассмотрим,
например, выражение АВ X CD1. Если нужно получить значение этого про-
изведения, у нас нет иного выбора, чем организовать просмотр одного файла,
скажем, файла, реализующего отношение АВ, и для каждой записи г, пред-
ставляющей некоторый кортеж, просматривать полный файл отношения CD.
При этом строится конкатенация г с каждой записью последнего файла.
В разумной реализации в основную память следует загрузить как мож-
но больше блоков файла для отношения АВ, оставляя, однако, простран-
ство для одного блока файла, поддерживающего отношение CD. Далее мож-
но осуществить конкатенацию каждой записи АВ в основной памяти с за-
писями из блока файла CD, поскольку он также находится в памяти. Такая
стратегия уменьшает число необходимых загрузок каждого блока CD с
коэффициентом, равным числу записей АВ, которые могут поместиться в
основной памяти. Если
1) отношения АВ и CD имеют соответственно пав и пСо записей2,
1 В этой главе мы будем часто использовать список атрибутов как имя отношения
с такими атрибутами.
2 Речь идет, конечно, о записях файла, представляющего данное отношение в
среде хранения базы данных (см. гл. 2). — Примеч. ред.
191
2) в одном блоке АВ и CD помещается соответственно Ьав и Ьсо запи-
сей и
3) в основной памяти может находиться т блоков,
то общее число доступов к блокам составляет пав!Ьср Для чтения
файла АВ и («cd/^cd) (пав/(гп — 1) Ьдд)) — для чтения файла CD, кото-
рое необходимо произвести пдд/(/п — 1) Ьдв раз. Таким образом, всего
требуется
плв /1 t пср
Ьав \ (w—1)&со
доступов. Если пав = пср = Ю ООО, Ьав — Ьсо = 5 и т = 100, чис-
ло доступов составляет 42 400. При 20 доступах к блокам в секунду вычисле-
ние этого декартова произведения потребует 35 мин.
В том случае, когда в запросе требуется напечатать декартово произве-
дение, мы почти ничего больше не можем сделать. Однако полный запрос
часто оказывается подобным следующей Ql/fL-программе:
range of х is А В
range of у is CD
retrieve (x.A)
where x.B = y.C and y.D 99
В алгебраических терминах такой запрос требует вычисления значения
выражения
яд (ob=cad=99 (ЯВ X CD)).
Если переместить селекцию D=99 внутрь декартова произведения,
получая при этом
ла (ов=с (АВ х Оо=э9 (CD))),
то достигается значительная экономия, как показывает следующий далее
анализ. Можно воспользоваться также тем, что ав=с преобразует декар-
тово произведение в эквисоединение, и записать поэтому последнюю формулу
в виде
Яд (АВ £><] Ор = 99 (CD)).
в=с
Рассмотрим теперь, как вычислять значение этой формулы. Если бы
файл для CD был индексирован по D, доступов к нескольким его блокам
оказалось бы достаточно, чтобы найти записи с D— 99. Даже при отсутствии
индекса необходимо всего лишь один раз просмотреть файл CD для нахож-
дения всех записей с D = 99, что потребует ncpIbcD доступов. В приве-
денном выше случае потребовалось бы 2000 доступов. В случае когда полу-
чаемое в результате множество записей помещается в основную память,
мы можем просмотреть файл АВ только один раз, используя для вычисления
произведения АВ X Od=99 (CD) при заданных оценках псо и Ьсо еще
2000 доступов и в то же время выполняя селекцию Ов=с и проекцию на
А. Однако если файл АВ имеет индекс |то В, мы можем принять во внимание
селекцию ав=с при вычислении декартова произведения и получить для
каждой записи CD (с, 99) за несколько! доступов записи АВ с В—с.
Таким образом, реорганизованный запрос требует при заданных выше
размерах файлов ие более одной десятой числа доступов к блокам, требуемых
для обработки первоначального запрета. Если же существуют указанные
индексы и записей с D—99 оказываемся не слишком много, время испол-
нения переформулированного запроса может быть на несколько порядков
меньше, чем в первоначальном случае.
I!»,'
Реализация соединений
Реализация соединения, в особенности не являющегося эквисоедине-
нием вида Л В может содержать ловушки, подобные тем, с кото-
в< с
рыми нам приходится сталкиваться в декартовом произведении. Необходимо
тщательно продумать даже реализацию эквисоединения вида АВ [><] CD.
в—с
Если просто просматривать записи АВ и CD и искать удовлетворяющие усло-
вию В = С, то потребуется так же много времени, как и для вычисления декар-
това произведения АВ х CD. Однако мы можем использовать индексы по
В и (или) С, созданные, если это необходимо, непосредственно в процессе
выполнения операции, и тогда время вычислений будет линейно зависеть от
размеров обоих отношений. Другой подход заключается в том, чтобы отсор-
тировать АВ по В и CD по С, а затем просмотреть каждый файл один раз
для поиска записей, удовлетворяющих условию равенства по полям В и С.
В зависимости от типов данных Ви С время сортировки может либо линейно
зависеть от размеров отношений, либо быть порядка п log п при сортировке
файла из п записей1. Если имеется относительно немногоразличных значений
атрибутов В и С, создание индекса может быть осуществлено главным об-
разом в основной памяти и поэтому требует времени, пропорционального
размерам отношений. В этой ситуации можно, вероятно, предпочесть созда-
ние индекса сортировке.
Общие стратегии оптимизации
В приведенном выше неформальном примере были предложены некото-
рые общие стратегии оптимизации. Существуют и другие стратегии, которые,
очевидно, также следует рассмотреть.
1. Выполнять операции селекции по возможности раньше. Это преоб-
разование запросов в большей степени, чем любое другое, влияет на эконо-
мию времени исполнения, поскольку оно направлено на уменьшение коли-
чества промежуточных результатов вычислений.
2. Целесообразно предварительно обрабатывать файлы перед выполне-
нием соединения (или, что эквивалентно, декартова произведения с последую-
щей селекцией). Мы упоминали о двух важных идеях предварительной об-
работки: сортировке файлов и создании индексов. Каждая из них позволяет
эффективно ассоциировать общие значения в двух файлах.
3. Искать общие подвыражения в выражении. Если результат общего под-
выражения представляет собой небольшое отношение, которое можно прочи-
тать из внешней памяти за значительно меньшее время, чем требуется для
его вычисления, целесообразно один раз предварительно вычислить это об-
щее подвыражение. В данную категорию, вообще говоря, попадают подвы-
ражения, использующие соединение, не изменяющиеся при перемещении се-
лекции внутрь его. Интересно заметить, что общие подвыражения будут по-
являться часто, когда запрос выражается в терминах представлений, по-
скольку для его исполнения следует сделать подстановку выражения для
представления.
4. Собирать в каскады селекции и проекции. Последовательность таких
операций, каждая из которых требует только одного операнда, может выпол-
няться одновременно, за один просмотр файла операнда.
1 Описание эффективных методов сортировки файлов во внешней памяти читатель
может найти, например, в книге Кнута [101].
7 Зак. 1315 193
5. Комбинировать проекции с предшествующими или последующими,
двуместными операциями. Нет необходимости устраивать просмотр файла
только для исключения определенных полей, если эти поля могут быть ис-
ключены либо при создании файла, либо при его первом использовании.
6. Комбинировать некоторые селекции с предшествующим декартовым
произведением и выполнять вместо них соединения. Как мы уже видели, со-
единение, в особенности эквисоедииение, может быть выполнено значитель-
но дешевле декартова произведения тех же самых отношений. В том случае,
когда результат декартова произведения R х S является аргументом какой-
либо операции селекции и эта операция включает логическое «и» сравнений
между атрибутами R к S, совокупность произведения и селекции представ-
ляет собой в действительности соединение. Отметим, что сравнение, не
включающее никаких атрибутов R или никаких атрибутов S, можно выпол-
нить до произведения, что даже лучше, чем преобразование произведения
в соединение1.
6.2. АЛГЕБРАИЧЕСКОЕ МАНИПУЛИРОВАНИЕ
Большинство сформулированных выше стратегий предусматривает пре-
образование алгебраических выражений. Поэтому при изучении проблем
оптимизации прежде всего полезно рассмотреть ряд алгебраических законов,
которые применяются к операторам реляционной алгебры. Будем предпола-
гать, что процессор запросов начинает обработку с построения дерева раз-
бора для алгебраического выражения. Сам язык запросов может быть чистым
языком реляционной алгебры, подобным ISBL, или языком, подобным
SQUARE либо SEQUEL, с некоторыми алгебраическими возможностями.
В последнем случае в результате грамматического разбора запроса получа-
ется дерево, в котором одни операторы являются операторами реляционной
алгебры, а другие — специальными операторами этого языка. Кроме того,
язык запросов может быть языком реляционного исчисления, но процессор
этого языка сначала транслирует его выражения в алгебраические. Напри-
мер, оптимизатор языка QUEL, который обсуждается в следующем разделе,
начинает обработку запроса с того, что предполагает операцию декартова
произведения отношений Rx X Rt X ... X если используются опера-
торы range вида
range of it is Ri
для i = 1, 2, .... k. Далее предложение where в запросе заменяется селек-
цией, и с помощью проекции получаются компоненты, упоминаемые в пред-
ложении retrieve.
Эквивалентность выражений
Прежде чем «оптимизировать» выражения, мы должны четко представ-
лять себе, ко/да два выражения являются эквивалентными. Напомним, что
существуют два определения понятия отношения (см. разд. 4.1), которые
имеют несколько различные математические свойства. Первое определение
заключается в том, что отношение — это множество кортежей длины k при
некотором фиксированном k, и два отношения равны, если и только если они
являются одним и тем же множеством кортежей. Согласно второму определе-
1 Благодаря существенному, как правило, уменьшению размеров отношений-
операндов. — Примеч. ред.
194
нию отношение рассматривается как множество отображений множества
имен атрибутов на множество значений. Два отношения считаются равными,
если они являются одним и тем же множеством отображений. Отношение в
первом смысле может быть преобразовано в отношение во втором смысле,
если мы дадим столбцам имена атрибутов. Можно также преобразовать от-
ношение во втором смысле в отношение в первом смысле, выбрав некоторый
фиксированный порядок атрибутов.
Здесь используется только второе определение, согласно которому от-
ношение есть множество отображений множества атрибутов на множество
значений. Это связано с тем, что все существующие языки запросов преду-
сматривают или даже требуют именования столбцов в отношении. Более
важно, однако, что в любых известных приложениях порядок печати столб-
цов в таблице несуществен, поскольку каждый столбец маркируется именем
собственного атрибута. Там, где это возможно, мы будем заимствовать имена
атрибутов отношения, являющегося результатом алгебраического выраже-
ния, из имен атрибутов в аргументах выражения. Потребуем также, чтобы
назначались имена для результатов объединения или разности множеств.
Выражение в реляционной алгебре, операнды которого являются пере-
менными-отношениями 7?х, /?2,.... Rk и, возможно, константами-отношения-
ми, определяет отображение кортежей отношений (гх, г2, .... rh), где. rt есть
отношение арности, соответствующей Rit на единственное отношение — от-
ношение, которое получается после подстановки каждого rt вместо Rt и вы-
числения выражения. Два выражения £х и Ей являются эквивалентными,
что записывается как Ег як £а, если они представляют одни и те же отобра-
жения, т. е. если подставить одни и те же отношения вместо идентичных имен
в эти два выражения, то будет получен один и тот же результат. При таком
определении эквивалентности мы можем перечислить правила (законы),
позволяющие осуществлять некоторые полезные алгебраические преобразо-
вания.
Законы, касающиеся соединений
и декартовых произведений
1. Законы коммутативности для соединений и произведений. Если £х
и £2 — реляционные выражения, и F — условие, налагаемое на атрибуты
Ег и £/, то
Ei £>*-3 ^2s ^15
F F
£х £><3 Ег в Е% £><3 Ей
£х X £2=а £2 X £х.
Докажем первый из них — закон коммутативности для соединений.
Пусть £х имеет атрибуты Дх, ..., Ап и £2 — атрибуты 5Х, ..., Вт. Мы не
предполагаем, что атрибуты At и Вг различны. Пусть далее гх и г2 — произ-
вольные отношения для £х и £2 соответственно. Тогда значением £х £><] £2
является множество отображений v атрибутов Дх, ..., Ап, Ви ..., Вт на их
значения, таких, что существуют отображения р.х и р2 в гх и г2 соответст-
венно, для которых
a) v [A J = рх [Дг] для i = 1, 2, .... п,
1 Мы ссылаемся на атрибуты по их именам. Если существуют два или более атри-
бутов с одним и тем же именем А, введем для них обозначения В. A, S. А и т. д. с тем,
чтобы различать их в условии F.
Т
195
6) v [Bjl = |ia (Sil для i = 1, 2, ..., m, и
в) условие F становится истинным при подстановке v [С] для каждого име-
ни атрибута С в F.
Если выразить значение Е2[><ЗЕХ таким же образом, то будет видно, что
F
это — в точности то же самое множество, и эквивалентность доказана. За-
метим, что если отношения рассматривались бы как множества кортежей, а
не отображений, операции соединения, естественного соединения и декарто-
ва произведения не были бы коммутативными, поскольку был бы сущест-
вен порядок компонентов в результирующих отношениях.
2. Законы ассоциативности для соединений и произведений. Если Ех,
Е2 и Е9 — реляционные выражения, a Ft и F2 — условия, то
(£х Е2) ><] E3sEx ><] (Е2 >< Е3);
Ft Ft Ft Ft
(Ех >< Е2) >< Ea и Ех ><| (Е2 Е3);
(Ех х Е2) х Е3 = ЕХ х (Е2 х Е3).
Оставляем доказательства этих законов в качестве упражнения для чи-
тателя.
Законы, касающиеся операций селекции и проекции
Каскад из нескольких проекций может быть скомбинирован в одну про-
екцию. Это выражается следующим законом:
3. Каскад проекций
«л,....ап («в,.вт (Е)) S Ял,...ап (Е).
Заметим, что этот закон для каскада проекций справедлив, когда имена
атрибутов Лх, ..., Ап принадлежат множеству атрибутов Ег.
Подобным же образом каскад селекций может быть скомбинирован в
одну селекцию, которая проверяет все условия одновременно. Это выражает-
ся так:
4. Каскад селекций
°Ft (Of, (Е)) s= Of,af, (Е).
5. Перестановка селекции и проекции
Of (ял,...лп (Е)) = лЛ1..ап (Of (Е)).
В более общем случае, если условие F вовлекает также атрибуты Вх,...,
Вт, которых нет среди Дх, ..., Ап, то
«л,....л_ (of (Е)) = лА1.a (oF (яд,.лй, в,...в„ (£)))•
6. Перестановка селекции с декартовым произведением.
Если все атрибуты, упоминаемые в F, являются атрибутами Ех, то
oF (Ех X Е2) sb OF (Ех) X Е2.
Отсюда имеем полезное следствие: если F имеет вид Ех Д Е2, где Ех
включает только атрибуты Ех, a F2 — только атрибуты Е2, то в соответст-
вии с законами 1, 4 и 6 получаем
Of (Et X Е2) ss а Ft (Ех) X Of, (Е2).
196
Кроме того, если в используются только атрибуты Еъ а в F2 — ат-
рибуты и Elt и Е2, мы можем утверждать, что
Оу? (ЕХ X Е %) =ЯС (оFt (ЕХ) X Е2).
Таким образом, часть селекции может быть выполнена до произведе-
ния.
7. Перестановка селекции с объединением. Если имеется выражение
Е — Ег (J Е2, то можно принять, что атрибуты Ех и Е2 имеют одинаковые
имена с атрибутами Е или, по крайней мере, что задано соответствие, кото-
рое ассоциирует каждый атрибут Е с единственным атрибутом Ех и единст-
венным атрибутом Е2. Таким образом, можно записать
Of (£1 U £2) s’ Of (£х) U Of (Е2).
Если имена атрибутов в Ех и (или) £2 фактически отличаются от имен ат-
рибутов в Е, то формулы F в правой части должны быть модифицированы с
тем, чтобы в них использовались соответствующие имена.
8. Перестановка селекции с разностью
aF (Ei — Е2) a 0F (£1) — of (£2).
Как и в .случае правила 7, если имена атрибутов в Ех и £2 различаются,
мы должны заменить атрибуты F в правой части формулы соответствующими
именами в Ех. Заметим также, что селекция aF (Е2) не необходима. При
желании ее можно заменить на Е2. Однако обычно выполняют селекцию, по
крайней мере, из соображений эффективности. Во многих случаях Ор (Е2)
существенно легче вычисляется, чем Ег, поскольку первое из них является
значительно меньшим множеством.
Мы не будем приводить формулировки законов, позволяющих «выталки-
вать» селекцию вперед и выполнять ее раньше соединения, поскольку соеди-
нение всегда может быть выражено как декартово произведение с последую-
щей селекцией, а в случае естественного соединения — проекцией. Таким
образом, законы «выталкивания» селекции перед соединением следуют из
правил 4, 5 и 6.
Законы выноса проекции таким образом, чтобы она предшествовала де-
картову произведению или объединению, подобны сформулированным выше
правилам б и 7. Однако заметим, что не существует общего способа выноса
проекции так, чтобы она предшествовала разности.
9. Перестановка проекции с декартовым произведением. Пусть Ех и Е2—
реляционные выражения, Лх, ..., Ап — список их атрибутов, причем
Вх, ..., Вт — атрибуты выражения Ех, а остальные атрибуты Сх, ..., Ск —
атрибуты выражения Е2. Тогда
Яд, Ап (£1 X £2) 91 лВ1 вт (£1) X яс, ch (£2)-
10. Перестановка проекции с объединением
яд,...дп (£х U £2) за яд,.дп (£х) U яд,..ап (£2).
Как и в п. 7, если имена атрибутов вЕхи (или)£2 отличаются от имен
атрибутов вЕхи £2, мы должны заменить Лх, ..., Ап в правой части соот-
ветствующими именами.
197
Алгоритм оптимизации реляционных выражений
Приведенные выше законы можно применять для «оптимизации» реля-
ционных выражений. Получаемые в результате «оптимизированные» выраже-
ния удовлетворяют принципам, изложенным в разд. 6.1, хотя ни в коей мере
не гарантируется, что они являются оптимальными среди всех эквивалент-
ных выражений. Мы попытаемся перемещать операции селекции и проекции,
насколько это возможно, вниз в дереве разбора выражения, хотя нам хоте-
лось бы организовать каскад таких операций в виде одной селекции с одной
последующей проекцией. По возможности будем также группировать опе-
рации селекции и проекции с предшествующей двуместной операцией, та-
кой, как объединение, декартово произведение или разность множеств.
Если операндами двуместной операции являются селекции и (или)
проекции1, применяемые к листьям дерева, имеют место некоторые специаль-
ные случаи. Следует внимательно рассмотреть, как нужно выполнять эту
двуместную операцию. Иногда целесообразно слить с ней селекцию или про-
екцию. Например, когда двуместная операция представляет собой объеди-
нение, можно слить операции селекции и проекции, находящиеся ниже ее
в дереве, без потери эффективности, поскольку мы так или иначе должны ко-
пировать операнды, чтобы сформировать объединение. Если, однако, двумест-
ной операцией является декартово произведение без последующей селекции,
которая превратила бы его в эквисоединение, предпочтительнее выполнить
сначала селекцию и проекцию, оставляя результаты во временном файле, так
как размер файлов-операндов весьма влияет на время, требуемое для вычис-
ления полного декартова произведения.
Результатом выполнения нашего алгоритма является программа, вклю-
чающая следующие шаги;
1) выполнение одиночной селекции или проекции,
2) выполнение селекции и проекции или
3) выполнение декартова произведения, объединения либо разности
множеств, которым, возможно, предшествуют или за которыми следуют опе-
рации селекции и (или) проекции, применяемые к одному или обоим операн-
дам.
Предполагается, что шаги 1 и 2 реализуются за один просмотр отношения
операнда. В результате создается временное отношение. Шаги типа 3 реали-
зуются путем применения, если это требуется в данном случае, операции
селекции и (или) проекции к каждому кортежу отношений-операндов вся-
кий раз при осуществлении доступа к ним, с использованием при необходимо-
сти последующих операций селекции и (или) проекции к каждому кортежу,
генерируемому как часть результирующего отношения. Результат помеща-
ется во временное отношение.
Алгоритм 6.1. Оптимизация реляционных выражений.
Входные данные. Дерево, представляющее выражение ре-
ляционной алгебры.
Выходные данные. Программа для вычисления выражения.
Метод.
1. Представляем каждую селекцию opt/\.../\Fn (Е) в виде каскада
аг, (... (стрп (Е)) ...) с помощью правила 4.
2. Перемещаем каждую селекцию, насколько это возможно, вниз в де-
реве, используя правила 4—8.
1 Автор имеет в виду результаты операций селекции и (или) проекции. — При-
меч. ред.
198
3. Перемещаем каждую проекцию в дереве вниз настолько, насколько
это возможно, используя правила 3, 9 и 10 и обобщенное правило 5. Заме-
тим, что правило 3 приводит к исчезновению некоторых проекций, в то
время как обобщенное правило 5 расщепляет проекцию на две, одна из ко-
торых может перемещаться по дереву вниз. Проекция исключается также,
если она проецирует выражение на все его атрибуты.
4. Комбинируем каждый каскад селекций и проекций в одиночную се-
лекцию, одиночную проекцию или селекцию с последующей проекцией, ис-
пользуя правила 3—5. Заметим, что это преобразование может противоре-
чить эвристике «делай проекцию как можно раньше», но после минутного
размышления мы приходим к выводу, что более эффективно выполнить все
операции селекции, а затем все операции проекции за один просмотр отноше-
ния, чем чередовать эти операции в нескольких просмотрах.
5. Разбиваем внутренние узлы полученного в результате дерева на
группы следующим образом. Каждый внутренний узел, представляющий дву-
местный оператор (х, U или —), принадлежит группе вместе с непосредст-
венными его предками, которые помечены унарными операторами (о или
л). Включаем также в группу любую цепь потомков данного узла, помечен-
ных унарными операторами, завершающуюся в листе. Исключением являет-
ся случай, когда двуместный оператор представляет собой декартово произ-
ведение без последующей селекции, которая комбинировалась бы с произве-
дением, образуя эквисоединение.
6. Создаем программу из нескольких шагов для вычисления каждой
группы в любом порядке, но так, чтобы никакая группа не вычислялась ра-
нее групп — ее потомков.
Пример 6.1. Рассмотрим базу данных библиотеки, состоящую из сле-
дующих отношений:
КНИГИ (НАЗВАНИЕ, АВТОР, НАЗВ-ИЗД, НОМЕР-БК)
ИЗДАТЕЛИ (НАЗВ-ИЗД, МЕСТО_ИЗД, АДРЕС_ИЗД)
ЧИТАТЕЛИ (ФАМИЛИЯ, АДРЕС, ГОРОД, НОМЕР-КАРТЫ)
ВЫДАЧИ (НОМЕР-КАРТЫ, НОМЕР-БК, ДАТА)
Поясним некоторые атрибуты:
НАЗВ_ИЗД
НОМЕР-БК
МЕСТО_ИЗД
АДРЕС_ИЗД
НОМЕР—КАРТЫ
ДАТА
— название издательства;
— номер книги по каталогу Виблиотеки конгресса1;
— место издания — город, в котором находится из-
дательство;
— улица и номер дома, где размещается издательство;
— номер библиотечной карточки читателя;
— дата выдачи книги читателю.
Для того, чтобы зиать, у кого находится книга, мы можем использовать представление
ХВЫДАЧИ, которое содержит дополнительную информацию о выданных книгах.
Это представление является естественным соедииеиием отношений КНИГИ, ЧИТАТЕ-
ЛИ и ВЫДАЧИ, которое может быть определено, например, следующим образом:
л5(ор(ВЫДАЧИ, ЧИТАТЕЛИ, КНИГИ)),
где
F = ЧИТАТЕЛИ. НОМЕР—КАРТЫ =» ВЫДАЧИ.НОМЕР-КАРТЫ
ДКНИГИ.НОМЕР-ВК = ВЫДАЧИ.НОМЕР—ВК,
S = НАЗВАНИЕ, АВТОР, НАЗВ-ИЗД, НОМЕР-ВК, ФАМИЛИЯ, ГОРОД,
АДРЕС, НОМЕР—КАРТЫ, ДАТА.
1 Одна из крупнейших библиотек мира, основанная в 1800 г. конгрессом США.—
Притч- р«д-
199
Пусть потребовалось перечислить книги, которые были выданы до некоторого
момента времени, например до 1.01.78. Это можно сделать с помощью выражения
л (о (ХВЫДАЧИ)).
НАЗВАНИЕ ДАТА <1.01.78
После подстановки определения ХВЫДАЧИ получаем для этого выражения де-
рево разбора, показанное на рис. 6.1.
Первый шаг оптимизации заключается в расщеплении селекции по условию F
иа две с условиями КНИГИ.НОМЕР_БК = ВЫДАЧИ.НОМЕР_БК и
ЧИТАТЕЛИ.НОМЕР_КАРТЫ = ВЫДАЧИ.НОМЕР-КАРТЫ соответственно. Далее
мы перемещаем каждую из трех операций селекции как можно ниже в дереве. Селекция
СТДАТА <1.01.78 перемещается ниже проекции и двух селекций по правилам 4 и 5. Затем
б?
.ДАТА *1.01.78
SE
НАЗВАНИЕ, АВТОР, КНИГИ. Н0МЕР_БК,
ФАМИЛИЯ, ГОРОД, АДРЕС,
ЧИТАТЕЛИ. НОМЕР_КАРТЫ,ДАТА
6
КНИГИ. HOMEPJK-ВЫДАЧИ HOMEPJK
А ЧИТАТЕЛИ. НОМЕР_КАРТЫ~-
ВЫДАЧИ. НОМЕР—КАРТЫ
Рис. 6.1. Дерево разбора выражения
эта селекция применяется к произведению (ВЫДАЧИ X ЧИТАТЕЛИ) X КНИГИ. По-
скольку ДАТА — это единственный атрибут, упоминаемый в селекции, и в то же вре-
мя атрибут только отношения ВЫДАЧИ, мы можем заменить
а ((ВЫДАЧИ X ЧИТАТЕЛИ) X КНИГИ)
ДАТА<1 .01.78
на
(а (ВЫДАЧИ X ЧИТАТЕЛИ)) X КНИГИ,
ДАТА<1.01.78
а затем на
((сг (ВЫДАЧИ)) X ЧИТАТЕЛИ) X КНИГИ.
ДАТА<1.01.78
Теперь переместим эту селекцию, насколько это возможно, вниз. Селекция с ус-
ловием КНИГИ.НОМЕР_БК=ВЫДАЧИ.НОМЕР_БК не может быть перемещена
ниже любого из декартовых произведений, поскольку в ней используется атрибут от-
ношения КНИГИ и атрибут, не принадлежащий этому отношению1. Однако селекция
по условию ЧИТАТЕЛИ.НОМЕР_КАРТЫ=ВЫДАЧИ.НОМЕР_КАРТЫ может быть
перемещена вниз и применена к произведению
СТДАТА< 1.01.78 (ВЫДАЧИ) X ЧИТАТЕЛИ.
1 Мы можем использовать законы коммутативности и ассоциативности произ-
ведения и затем переместить эту селекцию на один уровень вниз. Но тогда мы ие смог-
ли бы переместить вниз селекцию по условию ЧИТАТЕЛИ,НОМЕР^ КАРТЫ =
= ВЫДАЧИ.НОМЕР_ КАРТЫ.
200
Заметим, что ВЫДАЧИ.НОМЕР_КАРТЫ представляет собой имя атрибута
отношения, полученного в результате селекции <ТдАТА 1.01.78 (ВЫДАЧИ), по-
скольку это атрибут отношения ВЫДАЧИ.
Мы можем затем по правилу 3 скомбинировать две проекции в одну —
"название- Полученное в результате дерево представлено на рис. 6.2, По
обобщенному правилу 5 мы можем далее заменить "название я
°книги.номер_бк=выдаЧи.номер_вК каскадом:
л
НАЗВАНИЕ
О
КНИГИ.НОМЕР - БК=ВЫДАЧИ.НОМЕР-БК
Л
НАЗВАНИЕ,КНИГИ.НОМЕР—БК.ВЫДАЧИ.НОМЕР—БК
9Г
| НАЗВАНИЕ
* КНИГИ. НОМЕРЛН-ВЫДАЧИ. НОМЕРЛК
КИНГИ
ЧИТАТЕЛИ. НОМЕРЛАРТЫ-ВЫДАЧИ. НОМЕРЛАРТЫ
X
ЧИТАТЕЛИ
ЪаТЛСШ. 78
ВЫДАЧИ
Рнс. 6.2. Дерево, в котором операции селекции опущены вниз,
а проекции — скомбинированы
Применим теперь правило 9 с целью замены последней из этих проекций
на "название,книги.номер—бк* примененную к отиошеиию КНИГИ, н
"выдачи.номер-вк> примененную к левому операнду декартова произведения
более высокого уровня на рис. 6.2.
Последняя проекция взаимодействует с помещенной ниже селекцией по обобщен-
ному правилу 5. В результате получаем каскад:
л
ВЫДАЧИ.НОМЕР—БК
о
ЧИТАТЕЛИ .НОМЕР—КАРТЫ=ВЫДАЧИ.НОМЕР—КАРТЫ
Л
ВЫДАЧИ.НОМЕР- БК,ЧИТАТЕЛИ.НОМЕР —КАРТЫ,
ВЫДАЧИ. НОМЕР-КАРТЫ
Последняя из этих проекций «просеивается» через декартово произведение по прави-
лу 9 и частично через селекцию Оддтас 1.01.78 по обобщенному правилу 5.
Далее мы обнаруживаем, что в выражении
л (ВЫДАЧИ)
ВЫДАЧИ.НОМЕР-БК,ВЫДАЧИ. НОМЕР-КАРТЫ,ДАТА
проекция является излишней, поскольку в ией упоминаются все атрибуты отношения
ВЫДАЧИ. Поэтому исключаем эту проекцию. Окончательно полученное дерево пока-
201
зано на рис. 6.3. Группы операторов обведены на этом рисунке пунктирными линиями.
Каждое из декартовых произведений является фактически эквисоедииением, если ском-
бинировать его с селекцией, находящейся выше в дереве. В частности, селекция, при-
меняемая к Отношению ВЫДАЧИ, и проекция отношения ЧИТАТЕЛИ ниже первого
произведения могут быть успешно с ним скомбинированы. Программа, выполняющая
алгоритм, представленный на рис. 6.3, будет, очевидно, выполнять сначала нижнюю
группу операторов, а потом — верхнюю.
_----------J\ fННИГИ.Н0МЕР_ВН-8ЫДАЧИ.Н0МЕР-БК\
/ ^ВЫДАЧИ. НОМЕР-Е^^ ^ИГИ. НОМЕР-БК, НАЗВАНИЕ /
/ «Г '\книги J
! t ЧИТАТЕЛИ. НОМЕР-КАРТЫ V--.
^ВЫДАЧИ. НОМЕР-КАРТЫ --------"
I ^ВЫДАЧИ. НОМЕР-ЕН, Я\ЧИТАТЕЛИ. НОМЕР-НАРТЫ)
1 \8ЫДАЧИ. НОМЕР КАРТЫ I /
\ 6 ЧИТАТЕЛИ S
j ^ATA«1.D1.7B
\вЫДАЧИ
Рис. 6.3. Окончательное дерево с группированием операторов
6.3. АЛГОРИТМ ДЕКОМПОЗИЦИИ ДЛЯ ЯЗЫКА QUEL
Рассмотрим теперь несколько подробнее алгоритм, используемый в про-
цессоре языка QUEL. Этот алгоритм, хотя и разработан для языка, осно-
ванного на исчислении, может быть также использован для алгебраических
языков. Помимо идеи из предыдущего раздела о том, что операции селекции
должны выполняться возможно ранее, в алгоритме процессора языка QUEL
заложена, по крайней мере, еще одна важная идея, с которой мы до сих пор
не встречались, — о разумной декомпозиции декартовых произведений и со-
единений.
Рассмотрим запрос в языке QUEL:
range of 4 is
range of fh is Rk
retrieve (a)
where F
Здесь a — список атрибутов, принадлежащих отношениям 7?1( ..., Rk,
a F — условие, налагаемое на атрибуты отношений Rt. Формальный смысл
этого запроса дается выражением
na(aF(Ri х Rt х ... х Rk)).
(6-1)
Заметим, что некоторые из отношений Rt могут быть одними и теми же.
Поскольку атрибуты в а и F ассоциированы с переменными tit мы можем
определить, на какую копию отношения ссылаются термы в а и F, если два
или более отношений Rt являются одинаковыми.
202
Если применить методы алгебраического манипулирования, рассмо-
тренные в предыдущем разделе, то мы можем переместить селекцию и проек-
цию, насколько это возможно, внутрь декартовых произведений. Можно,
однако, воспользоваться также свойствами ассоциативности и коммутатив-
ности произведений, чтобы выбрать для них хорошее упорядочение. Некото-
рый неочевидный метод, помогающий выбрать рациональный порядок про-
изведений, используется в оптимизаторе языка QUEL. С целью мотивировки
этого метода предположим, что нужно получить естественное соединение
отношений АВ, ВС и CD, где А, В, С и D — имена атрибутов. По законам
коммутативности и ассоциативности соединение можно производить в лю-
бом желаемом порядке. Худшее, что мы могли бы сделать, — это начать с
вычисления Л В [><] CD, поскольку данное соединение в действительности яв-
ляется декартовым произведением. Более приемлемый вариант— вычислить
соединение АВ [>< ВС, а затем соединение результата с CD. Неплох и вари-
ант, начинающийся с ВС [><] CD, поскольку он симметричен предыдущему.
Проанализируем относительные преимущества подходов к этой проб-
леме. Предположим для простоты, что каждое из трех указанных отношений
имеет п кортежей и что, когда вычисляется естественное соединение отноше-
ний с одним общим атрибутом, число кортежей в результирующем отноше-
нии равно р 1, умноженному на максимум из числа кортежей в обоих
операндах. Допустим также, что домен каждого атрибута достаточно мал для
того, чтобы было удобно создать индекс по любому атрибуту. При этом вре-
мя на создание индекса оценивается произведением константы с на число
кортежей в отношении. Предположим, наконец, что время, требуемое для
вычисления соединения, если созданы необходимые индексы, равное?, умно-
женному на размер результата.
При этих предположениях время вычисления АВ [><] ВС складывается
из времени сп создания индекса для одного из двух отношений по атрибуту
В и dpn — времени собственно вычисления соединения. Тогда при вычисле-
нии (АВ [><] ВС) >< CD требуется время сп для вычисления индекса по С
для CD, меньшего отношения, а также dp*n — времени последующего вы-
числения соединения. Общее время составляет, следовательно,
2сп + d (рЛ + р) п. (6.2)
Существует и другой способ, позволяющий вычислять соединения. Со-
здадим сначала индекс для АВ по В и для CD по С, Этот шаг требует вре-
мени 2сп. Далее просмотрим кортежи (blt соотношения ВС. Используем ин-
дексы для нахождения всех кортежей в АВ с В-значениями и все кортежи
в CD с С-значениями сх. Об’единим, наконец, декартовы произведения та-
ких множеств и получим значение соединения 4B[><]BC[><]CD. Время,
необходимое для выполнения данного шага, пропорционально числу по-
лученных кортежей, которое равно 0 (ргп). Поэтому соединение полностью
вычисляется за время, равное
2сп + ер*п, (6.3)
где е — некоторая константа.
Если рассмотреть детально этот процесс и вычисление соединения, по-
добного АВ >< ВС, то можно обнаружить, что d и е примерно одинаковы.
Поскольку d = е, значение (6.2) превышает значение (6.3). Кроме того, при
втором подходе не используется дополнительное пространство, за исключе-
нием пространства для индексов, в то время как вычисление двух соединений
требует пространства для временного отношения.
Таким образом, желательно осуществлять реализацию естественного
соединения трех отношений, два из которых имеют нвпересекающиеся мно-
го»
жества атрибутов, с помощью декомпозиции отношения, пересекающегоск
с.двумя другими, т. е. во время просмотра кортежей этого отношения. Если
рассмотреть теперь запрос в языке QUEL, представленный формулой (6.1),
то можно заметить, что в данном случае речь идет о декартовом произведении,
а не о соединении. Предположим, однако, что условие F — это логическое
«и» одного или более термов и каждый терм включает равенство двух атри-
бутов. Тогда декартово произведение может трактоваться как совокупность
эквисоединений. Мы можем применить подход, основанный на декомпозиции,
к эквисоединениям точно так же, как и к естественным соединениям с уче-
том того, что обеспечивающие связь между двумя отношениями атрибуты
имеют в этих отношениях различные имена. Условие селекции F не обязатель-
но должно быть логическим «и» термов. Оно может включать также связки
«или» и «не». Более того, в F могутиспользоваться сравнения между атрибу-
тами, отличные от «=» . Эти ситуации усложняют описываемый алгоритм
декомпозиции, но обсуждаемый метод весьма эффективен на больших фраг-
ментах запросов, для которых условия селекции представлены как логи-
ческие «и» равенств между атрибутами и значениями констант.
Граф связей
Предположим, что имеется декартово произведение отношений ...,
к которому должна быть применена операция селекции Qf1A...af .
Каждое Ft может быть произвольно сложным условием, но мы предполага-
ем, что оно не является логическим «и» двух или более условий. Построим
граф1 G, в котором каждому Rit i = 1, 2, ..., k и каждому экземпляру кон-
станты в любом из условий Fj соответствует некоторый узел. Двум экзем-
плярам одного и того же имени отношения или одной и той же константы со-
ответствуют два разных узла. Далее найдем для каждого F} множество вхо-
дящих в него констант, а также множество отношений Rt, таких, что Fj
использует один или более атрибутов Rt. Эти множества отношений и кон-
стант определяют некоторое множество узлов G. Создадим «ребро», которое
в принципе является гиперребром, связывающим это множество узлов, и
сопоставим ему метку Fj. В общем случае, когда Fj имеет вид = а
или /?г.Л = Rm-B, «ребро» представляет собой настоящее ребро, связываю-
щее два узла, хотя в более сложных случаях «ребро» связывает много узлов.
Полезно следующее замечание. Поскольку каждому экземпляру констант-
ты соответствует единственный узел bG, узлы для констант имеют лишь по
одному инцидентному им ребру.
Пример 6.2. Рассмотрим отношения из примера 6.1 и предположим, что
имеется QUEL-программа, представленная на рис. 6.4. Эта программа должна печа-
тать фамилии всех читателей, которые берут книги, опубликованные в том же городе,
в котором они живут. Алгебраически этот запрос выражается декартовым произведе-
нием
КНИГИ X ИЗДАТЕЛИ X ЧИТАТЕЛИ X ВЫДАЧИ,
к которому нужно применить селекцию, специфицированную в предложении where,
и затем проецировать полученное отношение на ЧИТАТЕЛИ.ФАМИЛИЯ. Граф свя-
зен для этого запроса показан на рис. 6.5. Заметим, что все узлы на рис. 6.5 являются
гиперузлами, которые оказываются обычными узлами, т. е. множествами из двух уз-
лов. Й
1 Фактически G представляет собой гиперграф, поскольку его «ребра», вообще
говоря, представляют собой гиперребра, т. е. множества из одного, двух нли более
узлов, а не пары узлов, как в обычном графе. В наиболее важном и часто встречающем-
ся случае ребра являются парами узлов.
204
range of t. is КНИГИ
range of s is ИЗДАТЕЛИ
range of и is ЧИТАТЕЛИ
range of v is ВЫДАЧИ
retrieve (и. ФАМИЛИЯ)
where tHOMEP_BK = v.HOMEP_BK
and и.НОМЕР—КАРТЫ = v. НОМЕР_КАРТЫ
and f. НАЗВ_ИЗД = s-НАЗВ.-ИЗД
and и.ГОРОД = я.ГОРОД
Рис. ,6.4 QUEL-программа
КНИГИ. НОМЕР_БК“
ВЫДАЧИ. НОМЕР_БК
КНИГИ. НЯЗВ „ИЗД-
ИЗДЯТЕЛИ. назв„изд
выдачи. номер_кярты
-ЧИТАТЕЛИ. НВМЕР.КЙРТЫ
(издятели'')
Г0Р0Д=МЕСТ0_ИЗД
( выдачи )
ЧИТАТЕЛИ
Рис. 6.5. Граф связей для программы, представленной на
рис.. 6.4
Декомпозиция графа связей
Исполнение запроса можно рассматривать как последовательность опе-
раций над графом связей, где для каждой операции строится новое отноше-
ние, используемое в качестве промежуточного шага в обработке запроса, а
также производятся изменения самого графа. По окончании этого процес-
са граф исчезнет, и будет построено отношение, обозначенное запросом. Во
время его построения одни узлы символизируют новые отношения, а дру-
гие — новые «константы», являющиеся отдельными кортежами или множест-
вами кортежей (отношениями), которые, по нашему предположению, пред-
ставляют собой малые множества и которые мы интерпретируем как отдель-
ные кортежи.
В дальнейшем узлы, окруженные двойными линиями, символизируют
константы в .этом обобщенном смысле. Узел константы всегда имеет
только одно инцидентное ему ребро. Если ребро, соединяющее два узла,
снабжено меткой вида А = В, оно называется простым ребром. Для деком-
позиции графа связей используются рассматриваемые ниже построения
1. Инстанциация. Простое ребро, связывающее отношение с констан-
той, фактически является селекцией. Селекция выполняется следующим
образом. Пусть имеется простое ребро между узлами пи т, где п представ-
ляет отношение г, а т — константу, которая является единственным зна-
чением V. Исключим узел т так, чтобы не изменилось отношение, обозначен-
ное полным графом. Если константа представляет собой единственное зна-
чение v, то метка простого ребра имеет вид А = V, где А — некоторый ат-
рибут отношения г. Тогда исключаем ребро (п, т) и узел т, а узлу п ставим
205
в соответствие отношение ад=0 (г)- Полагаем, что это отношение «мало».
Поэтому узел представляет теперь константу, которая является малым от-
ношением.
2. Разбиение. Пусть имеется узел п, представляющий отношение г,
и k ребер, инцидентных п. Для вычисления обозначенного полным графом
отношения можно осуществить просмотр кортежей t в г и для каждого t
создать граф, обозначающий отношение первоначального графа, в котором г
заменено на {/}. Пусть при этом е будет «ребром» (которое может быть ин-
цидентно более чем двум узлам), инцидентным п, и F — формулой, ассоци-
ированной с е. Заменим в F каждый экземпляр атрибута А отношения г
константой t [А] и для каждого компонента t, упомянутого в F, создадим
узел, представляющий значение константы из этого компонента. Предполо-
жим, что е инцидентно всем созданным узлам, но больше не инцидентно узлу
п. Сделаем то же самое для каждого узла, инцидентного п, а затем исключим
узел п. Выполнив вычисления по полученному графу, получим в результате
отношение s. Возьмем далее декартово произведение s X {<}. Объединение
таких декартовых произведений по всем кортежам t в г даст в результате от-
ношение, обозначенное исходным графом.
Теперь мы можем дать полный алгоритм декомпозиции графа связей.
Этот алгоритм рекурсивен. Он вызывает сам себя для обработки модифи-
цированных графов и возвращает отношение, являющееся значением, обо-
значаемым графом, для обработки которого он вызван. Для получения зна-
чения, соответствующего заданному запросу, строим его граф, связей и вызы-
ваем для этого графа алгоритм декомпозиции. Полученное отношение, яв-
ляющееся селекцией, примененной к произведению, проецируем на компо-
ненты, упоминаемые в предложении retrieve. Читатель может в качестве
упражнения модифицировать алгоритм так, чтобы выполнять проекции как
можно раньше.
Алгоритм 6.2. Вычисление результата запроса путем декомпози-
ции.
Входные данные. Граф связей G.
Выходные данные. Отношение REL (G), обозначаемое гра-
фом G.
Метод. Применяем инстанциацию или р азбиение в соответствии со
следующими условиями:
1. Выполняем инстанциацию, пока это возможно.
2. Если выполнение инстанциации невозможно, пытаемся произвести
разбиение какого-либо узла п, имеющего инцидентные ему ребра. При этом
предпочтение отдается тому из них, которому инцидентны только простые
ребра. При наличии нескольких узлов такого рода выбираем один из них,
представляющий «малое» постоянное отношение (подобные отношения со-
здаются в результате инстанциаций). Если такового не существует, выбира-
ем узел, при исключении которого граф станет несвязным1. В случае когда
это невозможно, выбираем произвольный узел с простыми инцидентными
ребрами. Наконец, если и этого сделать нельзя, то выбираем любой узел,
желательно из числа представляющих «малые» отношения, а при отсутствии
такой возможности — из тех, удаление которых приводит к разбиению гра-
фа на два и более связных компонента.
1 Нахождение таких узлов — нетривиальная задача, но существует алгоритм
для их поиска [2]. Заметим, что Предпочтение несвязности графа соответствует тому
предпочтению, которое мы отдаем просмотру кортежей ВС в соединении
АВ><ВС|><СО, что обсуждалось в начале данного раздела.
206
3. Выбрав узел п для разбиения, приступаем к замене его узлами, вы-
ражающими значения констант для каждого кортежа t отношения, соот-
ветствующего п, как указывалось в определении разбиения. В результате
получаем граф Gt. Применяя алгоритм 6.2 рекурсивно к G{, вычисляем от-
ношение REL (G(). Окончательным результатом является U (REL (G() X
X {(}). Заметим, что реализуемый алгоритмом 6.2 метод вычисления Gt при-
меним для произвольного t. Поэтому алгоритм должен быть исполнен только
для одного «родового» Gt. К тому же областью определения t являются обыч-
но малые множества. Поэтому объединение не может быть очень большим.
4. К данному пункту мы приходим, если после использования инстан-
циаций везде, где это возможно, не остается каких-либо узлов, к которым
применимо разбиение. В таком случае окончательным результатом являет-
ся декартово произведение отношений, представляемых каждым из оставших-
ся узлов. И
Н0МЕР_БК~
t[HOMEP_BK]
НЯЗВ-ИЗД =
Б[НЯЗВ„ИЗД]
(^выдачи
(иЗДЯТЕЛи'')
ВЫДЯЧИ. НОМЕР-КЯРТЫ
“ЧИТЯТЕПИ. НОМЕРАЯРТЫ
ГОРОД^МЕСТО^ИЗД
Рис. 6.6. Типичный граф Gt
Пример 6.3. Применим алгоритм 6.2 к графу связей, представленному на
рнс. 6.5. Поскольку инстанциацня здесь невозможна, переходим к разбиению. Все ребра
являются простыми, но не существует «малых» отношений и нет узлов, удаление кото-
рых превращало бы граф в несвязный. Следовательно, мы можем применить разбиение
к любому узлу. Выберем узел КНИГИ. Если t — произвольный кортеж в отношении
КНИГИ, заменяем граф на рис. 6.5 графом, приведенным иа рис. 6.6. В принципе,
имеется один такой граф для каждого t, хотя их декомпозиции являются, по существу,
одними и теми же, и нам нужно оперировать только одним графом, чтобы исследовать,
каким образом вычислять отношение, обозначаемое каждым из них.
Применим теперь алгоритм 6.2 к графу Gt, представленному на рис. 6.6. Имеются
две возможности использования инстанциации .— по отношению к узлам констант
t [НОМЕР_БК] и t [НАЗВ_ИЗД]. В результате этих операций узлы, представляющие
отношения ВЫДАЧИ и ИЗДАТЕЛИ на рис. 6.6, представляют теперь «малые» отноше-
ния:
Lt = ст (ВЫДАЧИ)
НОМЕР-БК=< [НОМЕР—БК]
Pi = О (ИЗДАТЕЛИ)
НАЗВ—ИЗД—t [НАЗВ-ИЗД]
Результирующий граф показан иа рис. 6.7.
Теперь мы должны выбрать одно из «малых» отношений Li или Plt по которому
будет осуществляться разбиение. Допустим, что выбрано Lx. Пусть и — типичный
кортеж Lv Создадим для каждого и граф G(U, как показано иа рис. 6.8, а. Приме-
нив иистанциацию, заменим отношение ЧИТАТЕЛИ отношением
Bi = ст (ЧИТАТЕЛИ)
НОМЕР-КАРТЫ »и [НОМЕР-КАРТЫ]
207
Получаем граф, представленный на рис. 6.8, б. Последнее разбиение, напри-
мер по Bi, дает граф GfUD на рис. 6.8, в для каждого v из Вх. С помощью иистанциации
получаем граф, показанный на рис. 6.8, г, где
= a (PJ.
МЕСТО—ИЗД=о[ГОРОД]
Выполнив шаг 4 алгоритма 6.2, имеем REL (Gjud) = В качестве REL (G<u)
принимаем U (REL (6<ив) X {о}). Заметим, что Вх — «малое» отношение и его факти-
оев,
Рис. 6.7. Типичный граф Gt после иистанциации
Рис. 6.8. Дальнейшие шаги в процессе декомпозиции
ческое значение зависит от t и и. Получаем далее
REL (GJ = U (REL (6(и) X {«}),
и € Lt
где Z-x — отношение из рис. 6.7. Поскольку L± зависит от t, имеем окончательно
REL (G) = U (REL (Gt) X {*})-
iе книги
Пример 6.4. Пусть имеется программа в языке Quel:
range of t is КНИГИ
range of и is ВЫДАЧИ
range of v is ЧИТАТЕЛИ
retrieve (^.ФАМИЛИЯ, ^.НАЗВАНИЕ)
where о.НОМЕР-КАРТЫ = «.НОМЕР-КАРТЫ
and и. НОМЕР—БК = f.HOMEP_BK
208
Эта программа печатает список читателей и названия читаемых ими книг. Граф
связей G показан на рис. 6.9. Первым шагом здесь должно быть разбиение, и мы отда-
ем предпочтение узлу ВЫДАЧИ, поскольку он один превращает граф в несвязный, и
не существует «малых» отношений. Получаем для каждого и из ВЫДАЧИ граф, пока-
занный на рис. 6.10, а. Дважды применяя далее инстанциацию, имеем граф на
рис. 6.10, б, где
~ аНОМЕР_ВК = «[НОМЕР_БК] (КНИГИ)
= стномер_КАРТЫ = и[НОМЕР_КАРТЫ] (ЧИТАТЕЛИ)
КНИГИ
КНИГИ. НОМЕР. 6Н
ВЫДАЧИ. НОМЕР-бК
выдачи. номер.карты
ЧИТАТЕЛИ. НОМЕР.КАРТЫ
Рис. 6.9. Граф связей G
Н0МЕР_бК= НОМЕР.НАРТЫ*
и [НОМЕР-БК] 11[Н0МЕР^МРТЫ]
( КНИГИ ) (читатели)
а)
Рис. 6.10. Шаги декомпозиции
Теперь можно получить REL (Gu) = X В2 и ответ иа запрос
REL (6) = U (REL (Gu) X {и}).
ие ВЫДАЧИ
6.4. ТОЧНАЯ ОПТИМИЗАЦИЯ ДЛЯ ПОДМНОЖЕСТВА
РЕЛЯЦИОННЫХ ЗАПРОСОВ
Ранее были показаны некоторые способы преобразования запросов в эк-
вивалентные, которые могут быть обработаны более эффективно, чем исход-
ные. Можем ли мы, однако, быть уверенными в том, что преобразованные
запросы являются «оптимальными», т. е. что они обрабатываются наиболее
эффективно по сравнению со всеми эквивалентными запросами? В общем
случае такой уверенности быть не может. Прежде всего мы не установили
конкретного критерия оценки эффективности обработки данного запроса.
Действительно, в разд. 6.1 было в эскизном виде высказано наше мнение
относительно лучших алгоритмов вычисления отношений, представленных
просто в виде файлов. Однако существуют и другие методы представления,
например методы, упоминаемые в разд. 4.6 и 4.7 в связи с System R и IN-
GRES.
209
Если даже имеется в виду конкретный критерий оценки, проблема на-
хождения запроса с наименьшей оценкой, эквивалентного данному запросу,
является, вероятно, неразрешимой для большинства разумных критериев
оценки. Хотя существуют достаточные основания полагать, что обсуждае-
мые в разд. 6.2 и 6.3 методы успешно реализуются на практике, интересно
рассмотреть, при каких условиях можно обеспечить точную оптимизацию-
Оказывается, существует широкий класс запросов, называемых «конъюнк.
тивными», для которых проблема эквивалентности разрешима (хотя и явля-
ется NP-полной). Для таких запросов можно минимизировать число соеди-
нений и (или) декартовых произведений, необходимых при их обработке.
Будем исходить из предположения о том, что при любом возможном крите-
рии оценки оптимальный запрос содержит минимальное число соединений
и произведений. Тогда становится реальным нахождение оптимального за-
проса, эквивалентного заданному «конъюнктивному запросу», даже если
необходимо осуществлять поиск среди всех запросов с минимальным числом
соединений и произведений. В предположении, что при правдоподобном кри-
терии оценки предпочтительно как можно более раннее выполнение селекции
и проекции, наш поиск к тому же упрощается. При этом следует учитывать
лишь порядок, в котором должны выполняться соединения и произведения.
Таким образом, мы пришли к рассмотрению проблемы эквивалентности
для «конъюнктивных запросов». Ниже приводится алгоритм решения проб-
лемы эквивалентности, а затем показывается, каким образом он позволяет
минимизировать число соединений и (или) произведений. Будет также уста-
новлено, что любое выражение реляционной алгебры, включающее декарто-
во произведение, эквисоединение, пересечение, проекцию и некоторые се-
лекции, может быть представлено в виде конъюнктивного запроса. Следова-
тельно, рассматриваемый класс содержит многие из наиболее часто встре-
чающихся типов запросов, в частности главную конструкцию реляционной
алгебры — «селекция — проекция — соединение».
Конъюнктивные запросы
Конъюнктивным называется запрос, который может быть выражен в
реляционном исчислении с переменными на доменах следующим образом:
{«! ... ап|(н Ьх) ... (а Ьт) (Ф («1.ап, Ьъ .... bm, .сг))},
где а.{ — переменные на доменах или константы, bt — переменные на доме-
нах, Ct — константы, а гр имеет вид Rx (wx) Д ... Д Rk (wh). Здесь Rt яв-
ляются (не обязательно различными) именами отношений, aw —- корте-
жами, составленными из значений at, bt и ct. Тот факт, что ф должно быть
конъюнкцией термов, дает название данному классу запросов.
Рассмотрение класса конъюнктивных запросов является вполне есте-
ственным. Например, композиции отображений в SQUARE представляют
собой конъюнктивные запросы. К этому же классу относятся простые формы
запросов в QBE, обсуждавшиеся в разд. 4.7. Операторы retrieve в QUEL
и SELECT-FROM-WHERE в SEQUEL — это конъюнктивные запросы
всегда, когда предложение where является конъюнкцией (логическим «и»)
термов, каждый из которых есть равенство двух компонентов кортежей или
равенство компонента кортежа и константы.
Пример 6.5. Запрос на рис. 6.4, предусматривающий нахождение читателей,
которые берут книги, опубликованные в городе, где они живут, является конъюнктив-
ным запросом:
{ ... (Я *») (КНИГИ (616263*4) А ИЗДАТЕЛИ (63666в)
Л ВЫДАЧИ (676468) Д ЧИТАТЕЛИ (^63636,))}.
210
Имена и порядок атрибутов упоминаемых здесь четырех отношений можно найти
в примере 6.1.
Запрос «Напечатать названия всех книг, выданных по карточке номер 12345, и
даты их выдачи» выражается в виде
{a^l (Н *1) (аМ (H*s) (КНИГИ (a1blb2b3)\ ВЫДАЧИ ('12345' Ь3а2))].
Отношение «содержится» между запросами
Напомним из разд. 6.2, что мы определили запросы Qr (7?х, .... 7?й) и
Q2 (7?!, ..., Rh) как эквивалентные (записывается Qi я Qa), если какие бы
отношения г1; ..., мы не подставили для аргументов Rlt ..., Rk, результи-
рующие отношения Qx (гъ ..., rk) и Q2 (гг, ..., rk) окажутся равными. Будем
считать также, что Qx «содержится» в Q2, и записывать это как Qj s Qa,
если для каждого гх, ..., rk имеем Qx (гх, .... rk) £= Q2 (г1( ..., rh). Конъюнк-
тивные запросы нетрудно проверить на эквивалентность, дважды прове-
рив справедливость отношения «содержится», с помощью следующего
принципа:
Qx as Q2, если и только если Qt с Q2 и Q2 s Qx.
Пример 6.6. Для получения некоторого представления об отношении «со-
держится» между запросами заметим, что если f| R2 и Q2 = 7?i U Дг> to
Qi c Qa, хотя Qx = и Q2 C Qx ложны. Иными словами, пересечение любых двух
отношений Гх и г2 является подмножеством их объединения, хотя, вообще говоря,
несправедливо, что гх П гг — ri U гг нли ri U гг != ri Л г2- Однако эти соотношения
оказываются справедливыми в специальном случае, когда гх и г2 представляют одно
и то же отношение.
Приведем другие интересные примеры отношения «содержится», не являющиеся
эквивалентностями:
я$ (Д1 П Да) — яз (Д1) Л я5 (Да) •
я5 (Дх) я5 (Да) — ns (Д1 Да)- В
Свертки
Проверка справедливости отношения «содержится» для конъюнктивных
запросов Qx и Q2 основывается на существовании определенного вида ото-
бражения символов, используемых в Q2, в символы, используемые в Qx- По-
скольку соотношение Qx S Qs возможно, только если отношения, определя-
емые Qx и Q2, имеют одну и ту же арность, можно предположить, что
Qx = {ах,..., ап | (З^т) Wi («1...<*„, .....bm, сх;..., cft))},
Q2 = {ai,..., аА|(а&1')... (Э&/) Сф2 а‘п, Ь'т, ci,..., cs'))}.
Сверткой Q2 в Qx называется отображение f символов Q2 в символы Qx,
такое, что
1. f (a’i) = af.
2. f (c'i) = c'i и, следовательно, c\ должно быть с/ при некотором j1.
3. f (b'i) является каким-либо из a;, b} или с,.
4. Если R (w) — какой-либо терм ф2, то R (f (w)) — некоторый терм
фх, где f, примененное к Кортежу w — dx ... d}, определяется равенством
f(dxrf2...d;) = f №)/№),
1 В том случае, когда а\ — константа, правила 1 и 2 предполагают, что aj должна
быть одной и той же константой.
211
Пример 6.7. Пусть
Qi = {oi I (3bi) (зМ (R bi) Л S (62 Оа) ДЯ (62 с))},
Qi = {О3 «4 I (Н*з) (364) (3*з) (36в) (R (63 h) Л R (Оз ь«) Л R (ь4 с) Л S (Ь4 а4))}.
Тогда существует свертка f Q2 в Q1( определяемая следующим образом:
a) f (03) — ах и f (а4) = а2 в соответствии с правилом 1;
б) f (с) = с по правилу 2;
в) f (63) = an f (ft4) = Ьг, f (6S) = bi и f (b9) = b,.
Можно проверить, что каждый терм Q2 становится термом Qlt когда мы заменяем
каждый символ d на f (d). Например, Я (ft3*s) — терм Q2, f (bsb5) = и Я М —
терм Qx. Отсюда следует, что Qx С Q2, т. е. какие бы отношения мы не подставили для
Я и S, результат формулы Qx будет подмножеством результата Q2.
Справедливо также, что Q2 С Q±. Это можно продемонстрировать со сверткой g,
определенной следующим образом:
a) g (а4) = а3 н g (аг) = а4,
б) g (с) = с,
в) g (bi) = bi и g (b2) = b4.
Поскольку Qi 2 Q2 h Q2 2 Qx, имеем Qx = Q2.l
Теперь следует доказать наше утверждение о свертках: свертка Q2
в существует, если и только если Qi S Q2. Доказательство представляет-
ся двумя следующими леммами.
Лемма 6.1. Если существует свертка Q2 в Qx, то Qx = Q2.
Доказательство. Пусть
Qi = fai- ал|(3&1)... (Л&т) Oh ап, \........bm, ck))},
Q2 = {ai'... a;|(H&i)... (н&;)0Ыа1.а'п, b'i.b’r, ci,..., ci))}
и пусть f — свертка Q2 в Qx. Предположим, что в фх и ф2 используются от-
ношения Rv ..., Rj, и если вместо них подставляются отношения гх, ..., rj,
кортеж t принадлежит отношению Qx. Мы должны показать, что t принадле-
жит также Q2, если для Rt сделана та же самая подстановка. Для t, которое
должно принадлежать Qx, должна существовать некоторая оценка v, т. е.
некоторое значение v (d) для каждого символа d из ф, такое, что
1) v (aY... ап) = t и
2) если Rt (пу) — некоторый терм фх, то v (оу) принадлежит rt, где v (dx ... dz)=
— v (di) ... v (di). Но тогда, если используется v’ (d) = v (f (d)) для каж-
дого символа d из ф2, то обнаруживается, что t также принадлежит Q2,
т. е. и' (а\ ... а’п) = v (f (а{ ... а’п)) = и (ах... ап) = t. Более того, для каж-
дого терма Rt (w) в ф2 имеем и' (оу) = v (f (w)). Известно, что Rt (f (w))
есть терм фх, поскольку f — свертка. Но v (f (w)) принадлежит rt. Поэтому
v' (w) принадлежит гг и, следовательно, t принадлежит Q2.
Лемма 6.2. Если Qx s Q2, то существует свертка Q2 в Qx.
Доказательство. Пусть Qx и Q2 определены в соответствии
с условиями леммы 6.1. Будем рассматривать аг, bt и с{ как различные
значения, и пусть гг — отношение {wlRt (w) — терм из фх}. Например, если
Qi такое же, как в примере 6.7 с R = и S = /?2, то гх = {а^, Ьгс) и
г2 = {&2а2}. Заметим, что alt а2, 6Х, &2 и с считаются здесь константами.
Если эти rt подставляются вместо Rt в Qx, то тогда данный кортеж
й1 ... ап будет принадлежать Qx. Поскольку Qx s Q2, этот кортеж должен
принадлежать также отношению Q2, если подставить гг вместо Rt в Q2. Зна-
чит, должна существовать некоторая оценка v символов из Q2, такая, что
a) v (aj ... а'п) = ах... ап и
б) для каждого терма Rt (w) в Q2 и (оу) является элементом Мы утвержда-
ем, что v должно быть сверткой Q2 в Qx, поскольку из п. (а) следует условие
1 определения свертки, а из п. (б) и того факта, что а, Ь, с — различные
«константы», следуют условия 2—4.
212
Теорема 6.1. a) Qj s Q2, если и только если существует некото-
рая свертка Q2 в Qx.
б) Ол = Q2, если и только если существуют свертки Qi в Q2 и Q2 в Qx.
Доказательство непосредственно следует из лемм 6.1 и
6.2.
Минимизация конъюнктивных запросов
Теорему 6.1 можно использовать для определения конъюнктивного
запроса с минимальным числом термов, эквивалентного заданному конъюнк-
тивному запросу Q. Минимизируя число термов, мы минимизируем одно-
временно и число соединений и (или) произведений, которые должны быть
обычным образом вычислены для обработки запроса. Так как они являются
наиболее дорогими операциями в реляционной алгебре, минимизация тер-
мов конъюнктивного запроса
является хорошим первым ша-
гом, хотя за этим шагом долж-
ны были бы следовать и другие
меры по оптимизации, например
более раннее выполнение селек-
ции и проекции, как обсужда-
лось в двух предыдущих раз-
делах.
Возможно, читателю пока-
жется сюрпризом то, что для
каждого конъюнктивного запро-
са Q существует единственный,
с точностью до переименования
символов, конъюнктивный за-
прос Qo, эквивалентный Q. и
имеющий наименьшее возмож-
ное число термов. Иными слова-
ми, любой запрос с минималь-
ным числом термов, эквивалент-
Термы запроса Qj Термы запроса Рг
Рис. 6.11. Свертка как отображение термов
ный Q, должен представлять
собой запрос Qo, возможно, с заменой каких-либо символов другими. Для
доказательства этого необходимо рассматривать свертки как отображения
не между символами, а между термами. Если существует некоторая сверт-
ка fQr в Q2, то f отображает каждый терм R ($) запроса Qx в единственный
терм R (f (w)) запроса Q2.
Пример 6.8. На рис. 6.11 показаны две свертки f н g нз примера 6.7, отобра-
жающие термы в термы.
Другое важное замечание состоит в том, что композиция двух сверток
сама является сверткой. Читатель должен проверить это утверждение в ка-
честве упражнения. ТакиМ образом, композицией свертки f запроса Q2
в Qj и свертки g запроса Qi й Q2 явЛйеТся свертка запроса Q2 в себя. Сверт-
ка gf запроса Q2 в Q2 показывает, что Q2 с удаленным термом R (Ь3Ьа), ко-
торый можно назвать Q3, эквивалентен Q2, поскольку тождественное ото-
бражение, очевидно, является СВерТкой Q3 и Q2. Отметим, между прочим,
что Q3 и Qi являются йзаиМНО-бднбЗначными переименованиями символов
друг друга. Например* аг й Qt Соответствует а3 в Q3 и Ьу в Qj соотнектиуег
Ьъ в Q3. Так как Ь3 и Ьь из Q2 не встречаются в Q3, для них не требуются ю-
С'Т)
ответствующие символы в Qx. Это важно, поскольку в противном случае мы
не могли бы выбрать единственного соответствующего символа для ах и Ьг.
Теперь мы подготовились к доказательству центральной теоремы о конъюнк-
тивных запросах.
Теорема 6.2. Для каждого конъюнктивного запроса Q сущест-
вует эквивалентный ему конъюнктивный запрос Qo с наименьшим возмож-
ным числом термов. Любой другой запрос Q'o, эквивалентный Q, имеющий
минимальное число термов и не содержащий каких-либо неиспользуемых
квантифицированных переменных, является взаимно-однозначным пере-
именованием символов Qo-
Доказательство. Предположим, что для Q существуют два
эквивалентных запроса Q0 и Qo с минимальным числом термов и каждый
из них не имеет каких-либо неиспользуемых квантифицированных перемен-
ных. Тогда по теореме 6.1 существуют свертки fug запроса Qo в Q'o и Q'ob
Qo соответственно. Пусть f отображает два терма из Qo в те же термы Q'o.
Тогда gf является сверткой Qo в себя, которая отображает множество тер-
мов Qo в собственное подмножество этих термов. Поскольку в другом направ-
лении тождественное отображение является сверткой этого подмножества
термов в Qo, мы показали, что Qo не является запросом с минимальным чис-
лом термов, так как существует собственное подмножество Qo, которое эк-
вивалентно Qo.
Таким образом, f представляет собой взаимно-однозначное соответст-
вие между термами Qo и термами Qq. Следовательно, f является также вза-
имно-однозначным соответствием символов, так как если бы два символа
из Qo отображались в один из Q6, f отображало бы две строки Qo в одну Q’o,
поскольку мы предполагаем, что каждый квантифицированный символ Qo
встречается в терме. Отсюда вытекает, что Qo и Qo являются в действитель-
ности взаимно-однозначными переименованиями символов друг друга.
Следствие. Для любого заданного конъюнктивного запроса Q
можно найтн эквивалент с минимальным числом термов путем удаления из
него нуля или более термов и всех кванторов (д &), таких, что b не появ-
ляется больше ни в каком терме.
Доказательство. Пусть Qo — эквивалент Q, имеющий мини-
мальное число термов. Тогда композиция свертки Q в Qo со сверткой Qo в
Q дает свертку Q в некоторое его подмножество. Это подмножество может
включать не большй термов, чем Qo, и должно быть эквивалентно Q.
Пример 6.9. Если начать с Qa из примеров 6.7 и 6.8, то можно обнаружить,
что после удаления R (bs, Ь$), т. е.
{«з ««I (3*4) (H*e) (R (аз Ьл) /\R(btc) AS (bt а4))}
представляет собой минимальный эквивалент Q. Этот запрос был ранее назван Q3.
Проверка того, что данный запрос минимален, — трудная (WP-полная) задача. По су-
ществу, мы должны рассмотреть каждое возможное отображение «символ—символ»
по символам Qe и показать, что ни одно из них не является сверткой Qs в некоторое
помиожество его термов. Однако читатель может проверить наше утверждение на
этом маленьком примере.!
УПРАЖНЕНИЯ
6.1. Проверьте каждое из тождеств в разд. 6.2.
6.2. Покажите, что равенство:
As (El Ег) — ns (Ех) (Е2)
в общем случае не имеет места.
6.3. Вспомним базу данных любителей пива из упражнения 4.6, состоящую нз отно-
шений:
214
ЧАСТО-ПОСЕЩАЕТ (ПЬЯНИЦА, БАР)
ИМЕЕТ (БАР. ПИВО)
ЛЮБИТ (ПЬЯНИЦА, ПИВО)
Напишите выражения реляционной алгебры для следующих запросов И оптими-
зируйте их в соответствии с алгоритмом 6.1.
а) Найтн пьяннц, часто посещающих бар, в котором имеется любимое ими пиво.
б) Найтн пьяннц, которые посещают тот же бар, что и какой-либо любитель пива
«Потгольд».
в) Найти пьяниц, которые посещают тот же бар, что и какой-либо любитель не-
которого сорта пива, имеющегося в этом баре и любимого Чарльзом Чагемагом.
6.4. Используйте алгоритм 6.2 для оптимизации запросов в упражнении 6.3.
6.5. Какие запросы в упражнении 6.3 являются конъюнктивными?
* 6.6. Покажите, что каждое отображение в языке SQUARE определяет конъюнктив-
ный запрос.
* 6.7. Покажите, что любой оператор retrieve языка QUEL является конъюнктивным
запросом, если в нем предусматривается выборка некоторого списка атрибутов (без
каких-либо агрегатных операторов), и where-предложение является конъюнкцией
термов, в которых компоненты кортежей сравниваются друг с другом или с константа-
ми.
* 6.8. Покажите, что QBE-запросы, в которых все элементы являются переменными
или константами и не используется никаких блоков условий, представляют собой конъ-
юнктивные запросы.
* 6.9. Покажите, что каждое выражение реляционной алгебры, использующее опера-
торы селекции (где условиями являются равенства между компонентами И констан-
тами), проекции, декартова произведения, эквисоединеиия и пересечения, представ-
ляет собой конъюнктивный запрос.
6.10. В примере 6.6 утверждалось, что справедливы следующие соотношения:
я$ (Ri Г) R2) S (Rx) П я$ (R») >
nS' (#х) — я3 (Я») — яз (^1—^») •
Докажите это утверждение.
6.11. Имеется четыре следующих конъюнктивных запроса:
1- {ai^al <а*1) (ЭМ (R (сх*1) A R (Ma) A R (Ма))}-
и. {а^\ (а&1) (gL) (я*?) (R R (М2)Л R (ь2ь«) A R (Мз))}.
ш. {aia2| (gfciHak) “й»»)(з₽«) (R A R (М«) A Я (М2) А
A Я (ах^з) A Я A R (ЬдЬ1))1»
IV. {axaj (Эбх) (а*в) (Я (ах»1) А К (М Д R (сЬг) Д R
где с — константа. Найдите все равенства и отношения «содержится» между этими
выражениями.
* * 6.12. Предположим, что Q Qt (J Q2 U U Qk и Я “ Pi U P2 U ••• U Pr< где
Qi и Pt — множества, определенные конъюнктивными запросами. Докажите, что
Q с Р, если и только если для каждого Q< существует некоторое Pj, такое, что Qt С Р}.
* 6.13. Докажите, что крмпоэидкя сверток является сверткой.
* *6.14. Покажите, что определение эквивалентного конъюнктивного запроса с мини-
мальным числом термов является АР-полной задачей.
Библиографические замечания
Целый ряд алгоритмов оптимизации выражений рёляционной алгебры был
предложен Холлом [83J, Мии Кером (119), Печерером [132], Смитом и Чангом [155]. Суть
этих алгоритмов заключается в перенесении операторов селекции, насколько возмож-
но, вниз дерева, хотя существует и множество других полезных манипуляций. Страте-
гию оптимизации, в которой предусматривается, что сначала выполняется селекция,,
связывают с именем Палермо [128]. Готлиб [75] рассматривает возможные способы вы-
числения соединений, а Яо [181] анализирует альтернативы запросов вида «селекция—
проекция—соединение».
Алгоритм декомпозиции для языка QUEL рассматривается Вонгом и Юзефи
[176]. Оптимизация в ISBL обсуждается в работе Холла [83], а оптимизация в
SEQUEL— в работах Астрахана и др. [11] и Гриффитса и др. [80].
Оптимизация конъюнктивных запросов базируется иа работе Чандра и Мер-
лина [34]. Там же предложено решение упражнения 6.14 об АР-полноте задачи мини-
мизации. Ахо, Сейгив и Ульман [4] обобщили эти результаты на оптимизацию, при ко-
торой используются функциональные н многозначные зависимости. Сейгив и Янакей-
киз [146] распространили проверку эквивалентности на объединения конъюнктивных
запросов (упражнение 6.12) и даже на некоторые более общие классы запросов.
21&
ГЛАВА 7
ПРЕДЛОЖЕНИЯ DBTG
Доминирующее влияние на развитие сетевой модели данных и построен-
ных на ее основе систем баз данных оказали предложения Рабочей группы
по базам данных (Data Base Task Group — DBTG) КОДАСИЛ — Ассоциа-
ции по языкам систем обработки данных (the Conference on Data Systems
Languages — CODASYL). Эта организация является разработчиком языка
программирования Кобол и несет ответственность за его стандартизацию1.
Помимо формальной нотации для сетевой модели (язык определения данных —
ЯОД) и связанных с этой моделью некоторых ключевых концепци й манипу-
лирования базами данных, DBTG предложила язык определения данных
подсхемы (ЯОД подсхемы) для определения представлений концептуальной
базы данных2. Сама концептуальная схема определяется при этом с исполь-
зованием ЯОД. Предложен также язык манипулирования данными (ЯМД)
для написания прикладных программ, взаимодействующих с базой данных
в терминах представлений.
Настоящая глава начинается с определения модели данных DBTG
и обзора ряда связанных с нею основных идей. Затем рассматривается пред-
ложенный DBTG язык манипулирования данными. Поскольку на этот язык
оказал значительное воздействие Кобол с его довольно необычным синтак-
сисом, приведенные далее программы записаны не с помощью официального
ЯМД, а на его упрощенной версии, синтаксически приближенной к совре-
менным языкам программирования. Предусматриваются также некоторые
мнемонические средства для читателя в форме избыточных ключевых слов.
Рассматриваемый здесь подход не противоречит духу предложений DBTG,
поскольку в качестве включающих языков для ЯМД допускаются языки,
отличные от языка Кобол. Существующие системы, основанные на концеп-
циях DBTG, часто заимствуют синтаксис включающих языков. Наконец,
после обсуждения языка манипулирования данными мы снова обратимся
к языку определения данных и изучим его более детально3.
1 В КОДАСИЛ существует специальный комитет, задачами которого являются
развитие и сопровождение языка Кобол, но не его стандартизация. Стандарт этого
языка, получивший широкое распространение В международном масштабе, разрабо-
тан и поддерживается Американским институтом национальных стандартов (ANSI). —
Примеч. ред.
2 В оригинале «концептуальной схемы». Автор неоднократно подменяет в настоя-
щей главе понятие базы данных понятиями схемы, подсхемы и представления. — При-
меч. ред.
з К сожалению, обсуждение основных идей СУБД типа КОДАСИЛ в настоящей
главе базируется на материалах Отчета DBTG, опубликованного в 1971 г. К настоя-
щему времени эти предложения претерпели весьма значительные изменения, ознако-
миться с которыми можно в Отчете «Язык описания данных КОДАСИЛ» (Пер. с англ,
под. ред. М. Р. Когаловского и Г.К. Столярова. М., Статистика, 1981), а также в моно-
графии Олле [126]. — Примеч. ред.
216
7.1. ОСНОВНЫЕ КОНЦЕПЦИИ DBTG
В основу предложений DBTG положена рассмотренная в разд. 3.2
сетевая модель данных. Используемый в ней термин «тип логической записи»
заменен в предложениях DBTG термином тип записи. Поля в формате ло-
гической записи называются элементами данных, а логические записи
DBTG — просто записями. Поскольку мы склонны опускать слово «логиче-
ский» всякий раз, когда это не приводит к двусмысленности, здесь будут
применяться термины «запись» и «тип записи». Вместе с тем мы по-преж-
нему сохраним термин «поле» вместо «элемент данных». База данных может,
естественно, содержать много экземпляров записей одного и того же типа.
При этом не обязательно, чтобы экземпляры записей одного типа были раз-
личными, и в действительности возможны типы записей, вообще не имеющие
полей. Они могут использоваться для соединения записей других типов, и в
реализации пустые, казалось бы, экземпляры записей будут содержать один
или несколько указателей.
Наборы DBTG
По неудачному стечению обстоятельств концепция связи, т. е. отобра-
жения вида «многие к одному» одного типа записи в другой, обозначается в
предложениях DBTG термином набор1. Чтобы избежать очевидной пу-
таницы, к которой может привести использование этого термина, был пред-
ложен целый ряд более подходящих названий. Из них наибольшее распро-
странение получил термин набор DBTG, который и применяется в настоящей
работе.
Если т — отображение вида «многие к одному» записей типа Р2 в за-
писи типа 7?!, то с каждой записью г типа можно ассоциировать множест-
во Sr записей s типа /?2 таким образом, что т ($) = г. Так как т является
отображением вида «многие к одному», множества Sr, и 5Г1 не пересекаются
при гх #= г2. Если НАБОР есть имя набора DBTG, представляющего связь
т, то каждое множество Sr вместе с самой записью г называют экземпляром
набора НАБОР. Запись г называется владельцем экземпляра набора, а каж-
дая запись s, такая, что т (s) = г, — членом этого экземпляра набора. Тип
записи называется типом записи-владельца, а тип записи /?2 — типом
записи-члена набора DBTG НАБОР. При этом должно соблюдаться приня-
тое DBTG ограничение, что тип записи-владельца и типы записей-членов на-
бора DBTG должны быть различны2.
Указанное ограничение приводит к некоторым неудобствам. Но оно ока-
зывается необходимым, так как в большинстве операторов ЯМД предпола-
гается, что можно отличить запись-владельца от записей-членов в экземпля-
ре набора3. Обойти это требование можно введением фиктивных типов за-
писи. Например, желательно использовать один и тот же тип записи ЛЮДИ
в качестве типа записи-владельца и типа записей-членов набора DBTG
ЯВЛЯЕТСЯ-МАТЕРЬЮ, где запись-владелец в экземпляре набора тракту-
ется как мать всех ее записей-членов. Для решения этой задачи нужно со-
здать тип записи ФИКТИВНЫЙ и следующие наборы DBTG:
1 Автор ограничивается рассмотрением простейших типов наборов — с единст-
венным типом записей-членов. В предложениях DBTG допускаются вместе с тем типы
наборов с произвольным числом типов записей-членов. — Примеч. ред.
2 Это ограничение снято в более поздней версии ЯОД. — Примеч. ред.
3 На самом деле это требование не является необходимым, так как запись-владель-
ца и записи-члены набора можно различать в реализации не только по их типу, но и
другими способами. Один из таких способов применяется в СУБД SIBAS, разработан-
ной в Норвегии. — Примеч. ред.
217
1. ЕСТЬ с владельцем ФИКТИВНЫЙ и членами ЛЮДИ. Наше наме-
рение состоит в том, чтобы каждая запись ФИКТИВНЫЙ владела некото-
рым экземпляром набора ЕСТЬ, содержащим в точности одну запись ЛЮДИ.
Таким образом, каждая запись ФИКТИВНЫЙ, по существу, отождествля-
ется с личностью, представленной записью ЛЮДИ, которой владеет данная
запись ФИКТИВНЫЙ.
2. ЯВЛЯЕТСЯ_МАТЕРЬЮ с владельцем ЛЮДИ и членами ФИК-
ТИВНЫЙ. Здесь цель заключается в том, чтобы Любая запись г тина ЛЮДИ
владела записями ФИКТИВНЫЙ, а они в свою очередь (в экземпляре на-
бора ЕСТЬ) являются владельцами записей ЛЮДИ, для которых г являет-
ся матерью.
Рассмотрим теперь более сложный пример, демонстрирующий, как мож-
но определить базу данных сетевой структуры, используя язык определения
данных.
Пример 7.1. Вернемся в Счастливую Долину (см. пример 4.12) и посмотрим,
как идут дела в кооперативе после замены его реляционной системы базы данных сис-
темой, основанной на модели DBTG. На рис. 7.1 показаны декларации типов записей
RECORD ПОСТАВЩИКИ
1 НАЗВ_ПОСТ CHAR (20),
1 АДРЕС-ПОСТ CHAR (30);
RECORD ТОВАРЫ
1 НАИМ-ТОВАРА CHAR (15);
RECORD ЦЕНЫ
1 ЦЕНА REAL,
1 НАИМ_ТОВАРА VIRTUAL
SOURCE IS ТОВАРЫ.НАИМ-ТОВАРА OF OWNER OF
ТОВАРЫ-ЦЕНЫ,
1 НАЗВ_ПОСТ VIRTUAL
SOURCE IS ПОСТАВЩИКИ. НАЗВ-ПОСТ OF OWNER OF ПОСТ-ЦЕНЫ;
RECORD ЛЮДИ
1 ФАМИЛИЯ CHAR (20),
1 АДРЕС CHAR (30),
1 БАЛАНС REAL;
RECORD ЗАКАЗЫ
1 НОМЕР-ЗАКАЗА INTEGER,
1 КОЛИЧЕСТВО REAL;
DBTG SET ПОСТ-ЦЕНЫ
OWNER IS ПОСТАВЩИКИ
MEMBER IS ЦЕНЫ;
DBTG SET ТОВАРЫ-ЦЕНЫ
OWNER IS ТОВАРЫ
MEMBER IS ЦЕНЫ;
DBTG SET ТОВАРЫ-ЗАКАЗЫ
OWNER IS ТОВАРЫ
MEMBER IS ЗАКАЗЫ;
DBTG SET ЛЮДИ_ЗАКАЗЫ
OWNER IS ЛЮДИ
MEMBER IS ЗАКАЗЫ;
Рис. 7.1. Описание записей н наборов DBTG средствами ЯОД
и наборов DBTG, необходимых для реализации базы данных, описанной в примере 4.12.
Эти декларации записаны на упрощенном языке, основанном на предложениях DBTG.
Реальный языи манипулирования данными требует, чтобы и некоторые другие элемен-
ты информации, сути иоторых мы пока еще не касались, были включены в эти декла.
рации типов записей и наборов DBTG. В разд. 7.6 будут кратко изложены возможно-
сти полного языка манипулирования данными.
В декларации каждого типа записи перечисляются его поля с указанием типа
данных для инждогр из НИХ. Целое ЧИСЛО 1, Предшествующ^ каждому имени родя,
218
поставщики
ПОСТ-ЦЕНЫ
ЦЕНЫ
товлрьщены
товары
товары-заказы
заказы
л>оди_заказы
люди
Рис. 7.2. Сетевая диаграмма базы
данных кооператива
указывает номер уровня, как и в декларации структуры записи языка ПЛ/1. Допус-
каются номера у ровней до 99, что позволяет структуризовать поля. Типичным при-
мером использования таких структур является объявление внутри поля АДРЕС под-
полей УЛИЦА, ГОРОД и ИНДЕКС на уровне 2.
Если не возникает двусмысленности, поля представляются своими именами. Если
же два типа записи А и В имеют поля с одним и тем же именем F, то, для того Чтобы
различать их, можно использовать обозиачеиия A.F и В.F. В предложениях DBTG в
этом случае используется, однако, F IN А вместо более простого варианта A.F.
На рис. 7.2 представлена сетевая диаграмма базы данных кооператива. В прин-
ципе эта база данных состоит нз двух связей вида «многие ко многим», одна из которых
между товарами и членами кооператива (которые называются здесь «людьми», чтобы
не путать их с «членами набора DBTG»), заказывающими продукцию; вторая связь —
между поставщиками и поставляемыми товарами.
Как уже отмечалось в разд. 3.2, для того чтобы
представить эти два отображения вида «многие
ко многим», необходимо ввести два новых типа
записей— ЦЕНЫ и ЗАКАЗЫ. Запись типа
ЗАКАЗЫ представляет собой пару, состоящую
из одного человека и одного товара, заказанного
этим человеком. Единственной ассоциированной
с записью ЗАКАЗЫ информацией нз первона-
чальной базы данных кооператива является
КОЛИЧЕСТВО. Однако мы хотели бы сделать
записи ЗАКАЗЫ уникальными. Поэтому введен
порядковый номер НОМЕР_ЗАКАЗА, служащий
идентификатором записей ЗАКАЗЫ. Введение
порядкового номера — не единственный способ
достижения уникальности. Другой способ бу-
дет продемонстрирован на примере записей
ЦЕНЫ. На самом деле вовсе не обязательно,
чтобы записи некоторого типа всегда были уни-
кальными.
Запись г типа ЗАКАЗЫ служит не только
для представления количества заказанного то-
вара, нс и для ассоциации человека, владельца
экземпляра набора ЛЮДИ_ЗАКАЗЫ, которому
принадлежит г, с товаром, заказанным этим чело-
веком. Данный товар указывается в записи-вла-
дельце экземпляра набора ТОВАРЫ_ЗАКАЗЫ,
Аналогично запись ЦЕНЫ ассоциирует один товар с одним поставщиком этого
товара. При этом каждая запись ЦЕНЫ становится уникальной благодаря включению
в нее полей НАИМ_ТОВАРА и НАЗВ_ПОСТ. Эти поля объявлены как виртуальные
(VIRTUAL) в том смысле, что хотя на самом деле они не присутствуют в записях ЦЕНЫ
даже как указатели, на них тем не менее можно ссылаться в программах, как если бы
они фактически присутствовали в записи. Предложение
SOURCE IS ТОВАРЫ.НАИМ_ТОВАРА OF OWNER OF ТОВАРЫ-ЦЕНЫ
в декларации поля НАИМ_ТОВАРА записи ЦЕНЫ свидетельствуют о том, что для
нахождения значения этого поля сначала ищется владелец того экземпляра набора
ТОВАРЫ.ЦЕНЫ, которому принадлежит рассматриваемая запись. Владелец дол-
жен быть записью ТОВАРЫ (см. описание набора ТОВАРЫ_ЦЕНЫ), и мы можем
выделить его поле НАИМ_ТОВАРА, которое становится значением виртуального поля
НАИМ_ТОВАРА в записи ЦЕНЫ. Значение виртуального поля НАЗВ_ПОСТ вы-
числяется аналогичным образом с помощью владельца экземпляра набора DBTG
ПОСТ..ЦЕНЫ, которому принадлежит запись ЦЕНЫ.
На рнс. 7.1 представлены также декларации четырех наборов DBTG, соответст-
вующих четырем связям, приведенным на рис. 7.2. Каждая связь между типами запи-
сей-членов и записью-владельца набора DBTG имеет вид «многие к одному». Напри-
мер, один экземпляр набора ТОВАРЫ_ЗАКАЗЫ состоит из владельца, которым яв-
ляется запись ТОВАРЫ, и некоторого числа (возможно, равного нулю) членов, кото-
рыми являются записи ЗАКАЗЫ, представляющие все заказы на этот товар.
Рассмотрим теперь, каким образом базу данных на рис. 4.7 можно было бы пред-
ставить с помощью записей и экземпляров наборов. Например, набор DBTG ЛЮДИ_
ЗАКАЗЫ будет иметь четыре экземпляра, владельцем каждого из которых является
п
запись г.
219
некоторая записьЛ ЮДИ. В нашем примере владельцами являются Брукс, Филд, Ро-
бин н Харт. Каждая из этих записей содержит имя, адрес и (платежный) баланс в виде
Брукс Яблочное шоссе, 7+10.50
Эти четыре экземпляра набора в качестве записей-членов имеют записи ЗАКАЗЫ.
Если предположить, что шести заказам, указанным на рис. 4.7, б, присвоены поряд-
ковые номера от 1 до 6, то записями-членами экземпляра набора, владелец которого —
Брукс, являются (1,5) и (2, 10). Первая из этих записей означает номер заказа 1 с ко-
личеством, равным 5 фунтам. Вторая запись интерпретируется аналогичным образом.
Экземпляр набора, владелец которого — Робин, содержит в качестве записей-членов
(3,3), (5,2) и (6,8). Экземпляр набора для Харта включает в качестве записи-члена
одну запись (4,5), тогда как экземпляр набора для Филда вообще не имеет записей-
членов.
Набор DBTG ТОВАРЫ_ЗАКАЗЫ имеет шесть экземпляров, владельцем каж-
дого нз которых является запись ТОВАР. Например, запись с видом товара «карамель»
служит владельцем экземпляра набора с записями-членами (1,5) и (3,3) типа ЗАКА-
ЗЫ. Владельцами других экземпляров набора являются записи для товаров— мука,
сметана, фасоль, салат и творог. Последний из этих экземпляров набора не имеет запи-
сей-членов в силу отсутствия заказов на творог.
Чтобы определить товары, заказанные Бруксом, нужно осуществить навигацию
через экземпляры наборов ЛЮДИ_ЗАКАЗЫ и ТОВАРЫ_ЗАКАЗЫ, воспользо-
вавшись тем фактом, что каждой записью ЗАКАЗЫ владеют и запись ЛЮДИ, и запись
ТОВАРЫ. Начиная с записи для Брукса находим его экземпляр набора DBTG
ЛЮДИ_ЗАКАЗЫ. Этот экземпляр набора содержит записи-члены (1,5) и (2,10) ти-
па ЗАКАЗЫ. Чтобы найти товары, требуемые в этих заказах, необходимо найти вла-
дельцев их экземпляров наборов DBTG ТОВАРЫ_ЗАКАЗЫ. Владельцем записи
(1,5) ЗАКАЗЫ является запись ТОВАРЫ, соответствующая карамели, а записи
(2,10) — соответствующие муке. Следовательно, именно эти товары заказаны Брук-
сом.
Набор DBTG ПОСТ_ЦЕНЫ имеет три экземпляра, владельцами которых яв-
ляются записи ПОСТАВЩИКИ для трех поставщиков— корпораций «Солнечная
продукция», «Натуральные продукты» и «Вкусные продукты». Например, экземпляр
набора ПОСТ_ЦЕНЫ для компании «Солнечная продукция» содержит следующие
записи-члены типа ЦЕНЫ:
1.29 Карамель Солнечная продукция
0.89 Салат Солнечная продукция
1.09 Фасоль Солнечная продукция
Напомним, что в действительности в этих записях представлены лишь цены, а
наименования товаров и названия поставщиков являются виртуальными полями.
Рассмотрим, наконец, набор DBTG ТОВАРЫ_ЦЕНЫ. Он имеет шесть экземп-
ляров. Владельцем каждого экземпляра является запись для одного из шести товаров.
Так, экземпляр этого набора для салата включает следующие запнсн-члены типа
ЦЕНЫ:
0.89 Салат Солнечная продукция
0.79 Салат Вкусные продукты
Рассмотрим теперь ряд дополнительных концепций, содержащихся в
предложениях DBTG.
Ключи базы данных
Для того чтобы различать записи, каждой из них при создании независи-
мо от ее типа назначается уникальный ключ базы данных. Ключ базы дан-
ных, по существу, определяет место, в котором хранится запись. На запись
можно ссылаться как по ключу базы данных, так и по значениям ее полей.
Способы размещения
Можно представить себе, что для каждого типа записи имеется файл,
состоящий из всех записей данного.типа. Этот файл организуется одним из
нескольких методов, называемых способами размещения. Возможные ва.
220
рианты способов размещения рассматриваются в разд. 7.5. Наиболее важ-
ный из них — CALC. Он специфицируется предложением
LOCATION MODE IS CALC <процедура> USING <список полей>
в декларации типа записи. Так, на рис. 7.1 в декларацию типа записи ПО-
СТАВЩИКИ можно включить информацию о размещении
LOCATION MODE IS CALC ПРОЦ-l USING НАЗВ-ПОСТ, АДРЕС-ПОСТ
Предполагается, что ПРОЦ-1 является именем процедуры, которая по
значениям полей НАЗВ.ПОСТ и АДРЕС_ПОСТ вычисляет «хеширован-
ное значение». Можно представить, что записи ПОСТАВЩИКИ запоминают-
ся в участках файла таким образом, что предусматривается по одному уча-
стку для каждого значения, которое может быть возвращено процедурой
ПРОЦ-1, как указывалось в разд. 2.2. Однако ПРОЦ-1 в действительности
может быть некоторым алгоритмом поиска для какой-либо организации
файла, рассмотренной в разд. 2.2—2.5, и, возможно, для некоторых других.
Решение о том, как хранить файл со способом размещения CALC, в большой
степени возлагается на реализатора СУБД. Тем не менее предполагается, что
можно «легко» найти требуемую запись, если задано значение<процедуры>,
примененной кСсписку полец>. Например, фактическая организация фай-
ла может предусматривать сортировку его записей по значениям, возвра-
щаемым <процедурой>, вместе с разреженным индексом по этим значениям
в соответствии с подходом, изложенным в разд. 2.3.
Несмотря на такую свободу, способ размещения CALC обычно мыслен-
но отождествляют с хешированием, и такое толкование нельзя считать оши-
бочным. В последующих разделах предполагается для простоты, что все
типы записей имеют способ размещения CALC.
Селекция набора
В ряде ситуаций необходимо осуществлять селекцию конкретного эк-
земпляра данного набора DBTG. Наиболее часто встречается ситуация, когда
создается и запоминается новая запись г некоторого типа Т. Предложения
DBTG позволяют просто выполнением оператора «STORE г» автоматически
сделать г членом некоторого экземпляра набора для каждого набора DBTG S,
в котором Т является типом записи-члена. Но в какой экземпляр набора
DBTG S следует включить г? С помощью предложения SET SELECTION
можно ассоциировать с S алгоритм для селекции этого экземпляра набора.
Некоторые общие стратегии селекции набора могут быть объявлены в пред-
ложении SET SELECTION при декларации самого набора DBTG. Мы рас-
смотрим селекцию наборов в разд. 7.4.
Определение представлений
В предложениях DBTG предусмотрен язык определения данных под-
схемы, средствами которого можно определять представления. В отличие от
представлений, описанных в гл. 4 для ISBL и Query-by-Example, представле-
ния в предложениях DBTG являются материализованными в том смысле, что
удаления или модификации в представлениях изменяют лежащую в их ос-
нове концептуальную базу данных.
В представлении допускается использование иных имен для типов за-
писей, полей и наборов DBTG, чем в концептуальной схеме. Из представле-
221
ния могут быть опущены поля, которые имеются в соответствующем типе
записи, можно целиком исключить тип записи или даже набор DBTG.
Так как представления в предложениях DBTG не содержат каких-
либо понятий, не имеющихся в языке определения данных для концептуаль-
ной схемы, в последующих разделах мы будем для простоты писать програм-
мы, которые взаимодействуют непосредственно с концептуальной схемой,
как если бы она была представлением полной концептуальной базы дан-
ных. Таким образом, представления не играют никакой роли в дальней-
шем обсуждении.
7.2. ПРОГРАММНАЯ ОБСТАНОВКА
Программы записываются на каком-либо включающем языке (в предло-
жениях DBTG — на языке Кобол1), расширенном командами ЯМД, таки-
ми, как FIND (определить местоположение требуемой записи), GET (чи-
тать запись из базы данных) и STORE (запомнить запись в базе данных).
Обстановка, в которой выполняется программа, представлена на рис. 7.3.
Рабочее
пространство
Рис. 7.3. Программная обстановка
Имеется рабочее пространство, называемое рабочей областью пользователя,
в котором выделяется место для трех видов данных:
1) переменных, определенных в программе;
2) указателей текущего состояния, которые являются ключами базы
данных некоторых записей в базе данных. Позднее мы детально обсудим ука-
затели текущего состояния;
3) шаблонов для различных типов записей. Шаблон для некоторого ти-
па записи Т содержит пространство для каждого поляFданного типа записи,
и это пространство именуется в программах как T.F (или только F в случае
уникального имени поля). Запись запоминается в базе данных лишь после
сборки ее в шаблоне для соответствующего типа, а содержимое шаблона ко-
пируется в базу данных командой STORE. Аналогично команда GET чи-
тает запись из базы данных в соответствующий шаблон. Шаблон применяет-
ся также для «передачи параметров» некоторым командам, не имеющим иа
первый взгляд параметров. Это относится в особенности к команде FIND.
1 По образцу содержащихся в отчете DBTG языковых спецификаций средств
базы данных для Кобола могут быть сконструированы такие же средства для любого
другого включающего языка. В существующих СУБД типа КОДАСИЛ используются
различные включающие языки — Ассемблер, Фортран, Кобол, ПЛ/1 и др. — Примеч.
ред.
222
Указатели текущего состояния
Во время исполнения программы для нее необходимо определять место-
нахождение различных записей с помощью команды FIND и оперировать
ими с помощью других команд. Для того чтобы отслеживать записи, послед-
ние из тех, к которым осуществлялся доступ, система базы данных автома-
тически поддерживает совокупность указателей текущего состояния, а зна-
чения этих указателей, которые в действительности являются ключами базы
данных таких записей, делаются доступными для программы. Указателями
текущего состояния, с которыми мы имеем дело, являются:
1. Текущая (запись) процесса. В предложениях DBTG термин
«процесс» понимается как программа1. Ключ базы данных самой последней
из записей, к которым осуществлялся доступ, независимо от ее типа, хра-
нится в этом указателе.
2. Текущая (запись) типа записи. Для каждого типа записи Т указа-
тель «текущая запись типа Т» идентифицирует запись этого типа, к которой
в последний раз осуществлялся доступ.
3. Текущая (запись) типа набора. Для каждого набора DBTG S, имею-
щего в качестве типа записи-владельца Тх и типа записи-члена Та, послед-
няя из записей Тг или Тг, к которой осуществлялся доступ, называется те-
кущей (записью) S. Заметим, что иногда текущей S может оказаться запись-
владелец, а иногда — запись-член. Понятно также, что текущая S есть за-
пись, а не экземпляр набора. Иногда удобно говорить об экземпляре набора,
содержащем запись «текущую S» как о «текущем экземпляре S», хотя не
существует такого объекта, как указатель на экземпляр набора.
Пример 7.2. Вернемся к базе данных из примера 7.1. Предположим, что иам
нужно найти товары, заказанные Бруксом. В примере 7.1 было показано, как можно
использовать наборы DBTG ЛЮДИ.ЗАКАЗЫ и ТОВАРЫ_ЗАКАЗЫ для навига-
ции от Брукса к заказанным им товарам— карамели и муке. Как указывалось в
разд. 3.2 при обсуждении мультисписковых структур данных, удобно представлять эк-
земпляр набора в виде замкнутого кольца, состоящего из записей владельца и членов.
Тогда экземпляр набора DBTG ЛЮДИ_ЗАКАЗЫ для Брукса может состоять из
Шаг Текущая
типов записей ^типов наборов процесса
люди ЗАКАЗЫ ТОВАРЫ ЛЮДИ- ЗАКАЗЫ ТОВАРЫ - ЗАКАЗЫ
1. Найти запись для Брукса Брукс — — Брукс — Брукс
2. Найти запись (1,5) типа ЗАКАЗЫ Брукс (1.5) — (1.5) (1,5) (1.5)
3. Найти владельца за- писи (1.5) в наборе DBTG ТОВАРЫ-ЗА- КАЗЫ Брукс (1,5) Карамель (1,5) Карамель Карамель
4. Найти запись (2,10) типа ЗАКАЗЫ Брукс (2,Ю) Карамель (3,10) (2,Ю) (2,10)
5. Найти владельца за- писи (2,10) в наборе ТОВАРЫ-ЗАКАЗЫ Брукс (2,10) Мука (2,10) Мука Мука
Рнс. 7.4. Программа и ее воздействий на указатели текущего состоянии
1 Точнее, «исполняемая программа». — Примеч. ред.
223
записи-владельца (Брукса) и двух записей-членов (1,5) и (2,10) в порядке их следо-
вания по кольцу. Хотя мы еще не обсуждали вопрос о том, как выполняется оператор
FIND, достаточно сказать, что можно, перемещаясь по кольцу от записи-владельца,
находить поочередно каждую запись-член. Кроме того, можно найти владельца экземп-
ляра набора, если задана какая-либо запись-член этого экземпляра. На рис. 7.4 пока-
зана последовательность выполнения шагов программы и обозначены текущие типов
записей ЛЮДИ, ЗАКАЗЫ и ТОВАРЫ, текущие типов наборов DBTG ЛЮДИ_ЗА-
КАЗЫ и ТОВАРЫ_ЗАКАЗЫ, а также текущая процесса после каждого шага.И
7.3. НАВИГАЦИЯ В БАЗЕ ДАННЫХ
Чтение записи из базы данных в рабочее пространство осуществляется
в два этапа. Сначала с использованием последовательности операторов
FIND определяется местоположение требуемой записи, т. е. желаемая за-
пись становится текущей процесса. На этом этапе еще ничего не копируется
в шаблон для данного типа записи. Копирование записи в шаблон в рабочем
пространстве выполняется командой GET. Эта команда всегда копирует
текущую процесса в шаблон вуе зависимости от того, какого типа текущая
запись процесса1. Если желательно скопировать только подмножество по-
лей текущего процесса, то можно указать список требуемых полей после
GET в виде2
GET <тип записи>; <список полей>
Пример 7.3. Если текущей процесса является запись ЦЕНЫ (мы продолжа-
ем пример с базой данных кооператива), то можно читать поля НАИМ_ТОВАРА и
ЦЕНА с помощью оператора
GET ЦЕНЫ; НАИМ-ТОВАРА, ЦЕНА
Поле НАЗВ_ПОСТ в шаблоне для типа записи ЦЕНЫ не затрагивается. За-
метим, что, хотя НАИМ_ТОВАРА является виртуальным полем записи ЦЕНЫ, мож-
но писать программу так, как если бы оно существовало на самом деле, возлагая на
систему получение корректного значения из поля ТОВАРЫ.НАИМ_ТОВАРА вла-
дельца записи ЦЕНЫ в ее экземпляре набора ТОВАРЫ_ЦЕНЫ.Н
Для целей отладки можно указывать тип записи в команде GET, даже
если нужны все поля этой записи. Например, оператор
GET ЦЕНЫ
будет копировать текущую процесса в шаблон типа записи ЦЕНЫ, если
текущая процесса является записью этого типа. В противном случае систе-
ма предупредит пользователя об ошибке во время выполнения оператора
GET ЦЕНЫ. Подчеркнем, что оператор GET нельзя использовать для чте-
ния записи, не являющейся текущей процесса, даже если GET сопровожда-
ется указанием типа такой записи.
Оператор FIND
Команда FIND в предложениях DBTQ представляет на самом деле со-
вокупность команд, различающихся между собой ключевыми словами, сле-
дующими за словом FIND, но объединенных общей целью — установить
местоположение конкретной записи с помощью некоторой указанной стра-
1 'Гем не менее копирование текущей процесса осуществляется в рабочее про-
<. граиство в шаблон для типа записи текущей процесса. — Примеч. ред.
2 Спецификация типа записи в операторе GET является факультативной. ~
Примеч ред.
тегии. Возможности операторов FIND весьма широки. Здесь будет рассмо-
трено только некоторое их полезное подмножество. В частности, операторы
FIND позволяют1:
1. Найти запись по заданному ключу базы данных.
2. Найти запись при заданных значениях полей ее CALC-ключа. Напом-
ним, что для типов записей задаются способы размещения, и часто таким
способом размещения является CALC. При этом имеется «хеш-функция», при-
меняемая к значениям определенных полей (совокупность таких полей назы-
вается CALC-ключом) любой записи данного типа. При заданных значениях
этих полей можно найти некоторую (не обязательно единственную) запись
с такими значениями в указанных полях.
3. Последовательно просматривать файл записей указанного типа и
поочередно находить все записи с заданными значениями поля или полей
CALC-ключа.
4. Последовательно просматривать все записи-члены экземпляра набора.
5. Просматривать те записи-члены экземпляра набора, которые имеют
специфицированные значения в некоторых полях.
6. Найти владельца данной записи в заданном наборе DBTG.
7. Найти текущую какого-либо типа записи или набора DBTG. Этот
оператор на первый взгляд кажется парадоксальным, поскольку если не-
которая запись является «текущей чего-либо», то это в принципе означает,
что она «найдена». Однако мы уже отмечали, что GET оперирует только те-
кущей процесса, а не текущей типа записи или набора. В большинстве дру-
гих команд, которые еще не рассматривались, текущая процесса также яв-
ляется единственным возможным операндом. Таким образом, цель такого
оператора FIND состоит в том, чтобы сделать «текущую чего-либо» текущей
процесса для возможности последующей обработки.
Непосредственный поиск записи
Первые два вида оператора FIND позволяют осуществлять доступ
к записям по «ключу» — либо по ключу базы данных, либо по CALC-ключу.
Чтобы осуществить доступ по ключу базы данных, необходимо написать на
нашем упрощенном языке2
FIND <тип записи>- RECORD BY DATABASE KEY <переменная>-,
где <переменная> является переменной в рабочем пространстве, которой
предварительно было присвоено значение ключа базы данных. Например,
чтобы прочитать текущую типа записи ПРОДУКЦИЯ в шаблон в рабочем
пространстве, можно написать:
XYZ : = CURRENT OF ТОВАРЫ
FIND ТОВАРЫ RECORD BY DATABASE KEY XYZ
GET ТОВАРЫ
Здесь XYZ — имя переменной в рабочем пространстве.
1 Эти семь типов операторов FIND представляют собой не «семь форматов», о
которых упоминается в предложениях DBTG, а скорее некоторые их группировки, рас-
сматриваемые нами как логические единицы.
2 Между нотациями, используемыми здесь и в предложениях DBTG, имеются
некоторые различия. Во-первых, в синтаксисе предложений DBTG предусматривается
много факультативных слов. Мы включали или исключали их с тем, чтобы добиться
полной ясности. Во-вторых, мы ввели RECORD, SET и другие пояснительные слова
в соответствующих местах, где они напоминают читателю о том, что представляют
собой переменные.
8 Зак. 1315
225
Для нахождения записи при заданных значениях полей ее CALC-
ключа мы передаем эти значения оператору FIND, помещая их в соответст-
вующие поля шаблона. После этого можно воспользоваться командой
FIND <тип записи> RECORD BY CALC-KEY
Пусть, например, для записей ЛЮДИ задан способ размещения CALC
с CALC-ключом, состоящим только из поля ФАМИЛИЯ. Тогда платежный
баланс для Брукса можно найти следующим образом:
ЛЮДИ.ФАМИЛИЯ: = «Брукс»
FIND ЛЮДИ RECORD BY CALC-KEY
GET ЛЮДИ; БАЛАНС
Заметим, что ЛЮДИ.ФАМИЛИЯ и ЛЮДИ.БАЛАНС можно было бы
записать просто как ФАМИЛИЯ и БАЛАНС, поскольку при этом не воз-
никает никакой двусмысленности. Следует отметить также, что, хотя поле
ФАМИЛИЯ является CALC-ключом, нет никакой гарантии, что не найдет-
ся двух человек с одной и той же фамилией, и в результате выполнения при-
веденной выше последовательности шагов будет найдена лишь одна запись
с фамилией Брукс, а не все они.
Просмотр типа записи
Чтобы найти все записи некоторого типа с заданным значением CALC
ключа, можно найти первую такую запись описанным выше способом, а
затем искать оставшиеся записи с тем же самым значением CALC-ключа,
выполняя в цикле оператор
FIND DUPLICATE <тип записи> RECORD BY CALC-KEY
Если предположить, что текущая процесса имеет тип <тип записи>
и значения полей ее CALC-ключа равны соответствующим значениям полей
в шаблоне для Стип записи>, то будет найдена следующая запись типа
<тип записн> с теми же значениями полей CALC-ключа.
При выполнении любого вида просмотра следует учитывать возмож-
ность отсутствия записи, соответствующей спецификациям. В предложениях
DBTG для этих целей предусмотрено глобальное слово состояния-ошибки,
которое наряду с другими анормальными условиями указывает случаи, ког-
да оператор FIND не в состоянии найти запись. Предположим здесь для удоб-
ства, что переменная FAIL будет принимать значение «истина» тогда и толь-
ко тогда, когда оператор FIND завершается неудачно при поиске записи.
Пример 7.4. Пусть требуется напечатать всех поставщиков карамели и на-
значенную ими цену. Для удобства предположим также, что в качестве CALC-ключа
для типа записи ЦЕНЫ используется поле НАИМ_ТОВАРА. Тогда требуемая таб-
лица может быть напечатана подпрограммой, приведенной на рис. 7.5.Н
print «ПОСТАВЩИК», «ЦЕНА»/* печать заголовка*/
ЦЕНЫ. НАИМ _ ТОВАРА: = «Карамель»
FIND ЦЕНЫ RECORD BY CALC-KEY
while “’FAIL do
GET ЦЕНЫ; НАЗВ-ПОСТ, ЦЕНА
print ЦЕНЫ; НАЗВ _ ПОСТ, ЦЕНА
FIND DUPLICATE ЦЕНЫ RECORD BY CALC-KEY
end
Рис. 7.5. Напечатать названия поставщиков карамелин цены на нее
226
Просмотр экземпляра набора
Для начала предположим, что имеется текущий экземпляр некоторого
набора DBTG. Напомним, что экземпляр набора может быть представлен
как кольцо, образуемое его владельцем и членами. Если мы достигли вла-
дельца, то, сканируя по кольцу, можно вернуться вновь к владельцу, и в
этом случае переменная FAIL принимает значение «истина». Оператор
FIND вида
FIND OWNER OF CURRENT <имя набора> SET
находит запись-владельца текущего экземпляра набора <имя набора>,
делая ее текущей процесса и, что гораздо важнее, текущей набора <имя
набора>.
Оператор
FIND NEXT <тип записи> RECORD IN
CURRENT <имя набора> SET
продвигается на одну позицию по кольцу от текущей <имя набора>, при-
сваивая переменной FAIL значение «истина»1, если следующая запись имеет
тип, отличный от <тип записи>2. Как правило, <тип записи> является
типом члена набора <имя набора>, поэтому возвращение к владельцу оз-
начает неудачный поиск.
Альтернативный способ просмотра по кольцу реализуется командой
FIND FIRST <тип записи> RECORD IN CURRENT <имя набора> SET
позволяющей получить первую запись-член3 текущего экземпляра набора
DBTG<HMH-Ha6opa>. Если не существует никаких членов в этом наборе,
то переменная FAIL принимает значение «истина». В противном случае
можно продолжать движение по кольцу с помощью цикла, содержащего,
как и ранее, команду FIND NEXT....
Пример 7.5. Напечатаем товары, заказанные Бруксом. Такое задание вы-
полнит программа, представленная на рис. 7.6. Начнем с поиска записи ЛЮДИ для
Брукса. Эта запись является владельцем экземпляра набора ЛЮДИ_ЗАКАЗЫ, ко-
торый требуется просмотреть. Находим первую запись-член этого экземпляра набо-
ра и в цикле проверяем, пройдено ли уже все кольцо. Если кольцо не пройдено, ис-
пользуем команду FIND OWNER для получения записи ТОВАРЫ, владеющей
заказом, и читаем ее, чтобы получить наименование товара. Печатаем наименование
товара, после чего находим следующий член экземпляра набора ЛЮДИ_ЗАКАЗЫ
для Брукса и возвращаемся на начало цикла.
ФАМИЛИЯ: = «Брукс»
FIND ЛЮДИ RECORD BY CALC-KEY
/* CALC-ключом для типа записи ЛЮДИ является ФАМИЛИЯ*/
FIND FIRST ЗАКАЗЫ RECORD IN CURRENT ЛЮДИ _ ЗАКАЗЫ SET
while FAIL do
FIND OWNER OF CURRENT ТОВАРЫ-ЗАКАЗЫ SET
GET ТОВАРЫ/* чтение товара, владеющего текущей записью заказа*/
PRINT ТОВАРЫ.НАИМ_ТОВАРА
FIND NEXT ЗАКАЗЫ RECORD IN CURRENT ЛЮДИ _ ЗАКАЗЫ SET
•;nd
Рис. 7.6. Напечатать наименования товаров, заказанных Бруксом
1 Технически слово состояния-ошибки интерпретирует достижение последнего
члена экземпляра набора иначе, чем неудачу при поиске записи. Но мы надеемся, что
использование переменной для указания всех аномалий не приведет ни к каким кол-
лизиям.
2 Напоминаем читателю, что автор рассматривает только типы набора с одним
типом записи-члеиа. — Примеч. ред.
з Типа <тнп записи>. — Примеч. ред.
8*
227
Сингулярные наборы
Иногда приходится просматривать все записи некоторого типа, напри-
мер, для того, чтобы найти все записи ЛЮДИ с отрицательным балансом.
Непосредственный доступ ко всем записям ЛЮДИ по CALC-ключу или
ключу базы данных осуществить невозможно, если нам неизвестна фамилия
каждого человека, входящего в кооператив, или если неизвестны ключи ба-
зы данных для таких записей. Обе эти ситуации маловероятны. Просмотр
экземпляров наборов для поиска записей ЛЮДИ — также весьма неблаго-
дарная работа, если, конечно, нет какого-либо способа локализации каждо-
го экземпляра рассматриваемых наборов DBTG.
Для заданного типа записи можно определить понятие сингулярного
набора DBTG. Сингулярный набор характеризуется двумя особыми свойст-
вами:
1. Типом записи-владельца такого набора является специальный тип
записи, называемый SYSTEM. Наличие SYSTEM как владельца отличает
сингулярные наборы DBTG.
2. Имеется в точности один экземпляр набора, членами которого яв-
ляются все записи данного типа. Эти записи автоматически становятся чле-
нами набора, не требуя каких-либо специальных указаний от пользователя.
Пример 7.6. Для обеспечения удобного поиска всех записей ЛЮДИ в декла-
рации наборов DBTG на рис. 7.1 можно добавить определение следующего сингуляр-
ного набора:
DBTG SET ВСЕ-ЛЮДИ
OWNER IS SYSTEM
MEMBER IS ЛЮДИ;
Чтобы напечатать фамилии всех людей с отрицательным платежным балансом,
можно тогда воспользоваться программой, приведенной на рис. 7.7.Я
print «ЧЕЛОВЕК», «БАЛАНС»
FIND FIRST ЛЮДИ RECORD IN CURRENT ВСЕ-ЛЮДИ SET
/* единственный экземпляр набора ВСЕ—ЛЮДИ всегда является текущим*/
while —, FAIL do
GET ЛЮДИ
if БАЛАНС < 0 then
print ФАМИЛИЯ, БАЛАНС
FIND NEXT ЛЮДИ RECORD IN CURRENT ВСЕ-ЛЮДИ SET
end
Рис, 7.7. Напечатать фамилии членов кооператива с отрицательным платежным
балансом
Просмотр экземпляра набора для поиска записей
со специфицированными значениями полей
Следующий вид оператора FIND также служит для просмотра членов
экземпляра набора, но он позволяет рассматривать только записи со специ-
фицированными значениями определенных полей. Значения этих полей за-
носятся в шаблон данного типа записи перед использованием оператора
FIND. Чтобы получить первую запись-член текущего экземпляра набора
DBTG chmh наборам*, содержащую требуемые значения, можно записать
FIND<THn записи> RECORD IN CURRENT
<имя набора> SET USING <список полей>
Здесь стип записи>> является членом набора DBTG <имя набора>, а
<список полей> представляет собой перечень полей записи <тип записи>,
228
значения которых, хранимые в шаблоне для данного типа записи, должны со-
ответствовать значениям этих полей в найденной записи. Для получения по-
следующих записей в том же самом экземпляре набора и с теми же самыми
значениями полей, выполняем оператор
FIND DUPLICATE <тип записи> RECORD IN
CURRENT<hmh набора?» SET USING <список полей>
Пример 7.7. Для поиска цены сметаны, назначенной Корпорацией вкусных
продуктов, можно использовать программу, представленную иа рис. 7.8. Пример си-
туации, в которой требуется просматривать несколько записей, соответствующих за-
просу, приведен на рис. 7.9, где используется сингулярный набор ВСЕ_ЛЮДИ из
примера 7.6 для всех членов кооператива с нулевым платежным балансом.
ПОСТАВЩИКИ.НАЗВ_ПОСТ: = «Корп. вкусных продуктов»
FIND ПОСТАВЩИКИ RECORD USING CALC-KEY
/* устанавливает текущий экземпляр набора ПОСТ-ЦЕНЫ*/
ЦЕНЫ. НАИМ_ ТОВАРА: = «сметана»
FIND ЦЕНЫ RECORD IN CURRENT ПОСТ-ЦЕНЫ SET USING
НАИМ-ТОВАРА
GET ЦЕНЫ; ЦЕНА
print ЦЕНА
Рис. 7.8. Найти цену, установленную Корпорацией вкусных продуктов на сметану
БАЛАНС: = О
FIND ЛЮДИ RECORD IN CURRENT ВСЕ-ЛЮДИ SET USING БАЛАНС
while Д FAIL do
GET ЛЮДИ; ФАМИЛИЯ
print ФАМИЛИЯ
FIND DUPLICATE ЛЮДИ RECORD IN
CURRENT BCE-ЛЮДИ SET USING БАЛАНС
end
Рис. 7.9. Найти членов кооператива с. нулевым платежным балансом
Установление текущей записи процесса
Последний рассматриваемый вид оператора FIND служит для того,
чтобы превратить текущую типа записи или типа набора в текущую запись
процесса. Синтаксис такого оператора:
FIND CURRENT OF <имя набора> SET
или
FIND CURRENT OF <тип записи> RECORD
Пример 7.8. Предположим, что требуется узнать, заказал ли Брукс кара-
мель и если заказал, то сколько. Сначала просматриваем экземпляр набора ЛЮДИ-
ЗАКАЗЫ, относящийся к Бруксу. Для каждого заказа, представленного в этом набо-
ре, обращаемся к его владельцу в наборе ТОВАРЫ-ЗАКАЗЫ, чтобы узнать, являет-
ся ли заказанный товар карамелью. Прочитать запись ЗАКАЗЫ можно было бы и до
выяснения ее владельцев, но тогда мы потеряли бы время на чтение заказов на товары,
отличные от карамели. Одно из возможных решений — снова установить запись ЗА-
КАЗЫ в качестве текущей процесса, когда будет обнаружено, что она содержит заказ
на карамель1. Напомним, что, устанавливая запись ТОВАРЫ в качестве текущей про-
цесса, нельзя непосредственно применить оператор GET к любой другой записи. Со-
ответствующая программа приведена на рнс. 7.10.
1 Здесь не обсуждается вопрос о возможности подавить обновление указателей
текущего состояния, что позволяет по-иному решать эту проблему.
229
ФАМИЛИЯ: = «Брукс»
FIND ЛЮДИ RECORD USING CALC-KEY
LOOP: repeat forever
FIND NEXT ЗАКАЗЫ RECORD IN CURRENT ЛЮДИ_ЗАКАЗЫ SET
if FAIL then break LOOP
FIND OWNER OF CURRENT ТОВАРЫ_ЗАКАЗЫ SET
GET ТОВАРЫ; НАИМ_ТОВАРА
if ТОВАРЫ.НАИМ_ТОВАРА — «карамель» then do
FIND CURRENT OF ЗАКАЗЫ RECORD
GET ЗАКАЗЫ; КОЛИЧЕСТВО
print КОЛИЧЕСТВО
break LOOP
end
end LOOP
Рис. 7.10. Найти количество карамели, заказанное Бруксом
7.4. ДРУГИЕ КОМАНДЫ БАЗЫ ДАННЫХ
Помимо операторов FIND и GET, в предложениях DBTG предусматри-
ваются также команды для включения или удаления текущей записи про-
цесса из экземпляров набора и типа записи, а также команды модификации
текущей записи процесса.
Команда STORE
Чтобы запомнить новую запись типа Т в базе данных, необходимо со-
здать запись г в шаблоне для данного типа записи, а.затем воспользоваться
командой
STORE Т
Эта команда добавляет запись г к совокупности записей типа Т и делает
г текущей процесса, текущей типа Т, а также текущей каждого набора DBTG,
в котором Т является типом записи-владельца или члена.
Отметим интересный побочный эффект при выполнении команды STORE.
Если Т является типом записи-члена набора DBTG S, можно организовать
, автоматическое включение г в качестве члена в некоторый конкретный эк-
земпляр набора S во время запоминания ее в файле для типа записи Т. Для
этого необходимо в декларацию набора DBTG S добавить предложение
INSERTION IS AUTOMATIC
В противоположность AUTOMATIC вариант MANUAL означает, что за-
писи-члены набора при запоминании их в базе данных не должны включаться
в какой-либо экземпляр набора S. Включение записей в экземпляр набора
S должно при этом выполняться «вручную» командой INSERT, которая будет
рассматриваться позднее.
Селекция набора
Допустим, что декларируется автоматическое включение записей типа
Т в экземпляры набора S. В этом случае необходим механизм, позволяющий
установить, в какой экземпляр набора S нужно включить новую запись. Са-
ма команда STORE не может специфицировать требуемый экземпляр набора.
Проблема решается, если в декларацию набора DBTG S включить предложе-
ние SET SELECTION (селекция набора). Это предложение указывает, ка-
ким образом вцбрать экземпляр набора S, в который должна быть помеще-
230
на вновь запоминаемая запись-член набора. Существует много различных
способов выбора такого экземпляра набора. Мы здесь сначала опишем два
простых способа, а затем более сложный. Напомним, что каждый из следую-
щих операторов принадлежит декларации набора S, а не является частью
подлежащего исполнению раздела некоторой программы. Заметим также, что
здесь используется упрощенный синтаксис с тем, чтобы смысл предложений
был более очевидным.
1. SET SELECTION IS THRU CURRENTОЕ<имя Ha6opa>SET (Селекция
набора через текущую типа набораСимя набора>.)
Здесь, прежде чем запомнить запись, программа сама должна установить
текущий экземпляр набора «Симя набора> (предполагается, что S — имя
набора). Когда запись запоминается, она становится членом текущего экзем-
пляра набора S.
2. SET SELECTION IS THRU OWNER USING Ссписок полей> (Селек-
ция набора через владельца, для идентификации которого используется
«Ссписок полей>.)
Указанный «Ссписок полей> является CALC-ключом для типа записи-
владельца S, который, следовательно, должен иметь способ размещения
CALC, если используется такой тип предложения SET SELECTION. Теку-
щие значения указанных полей в шаблоне для типа записи-владельца опре-
деляют единственную запись типа записи-владельца S. Запоминаемая за-
пись включается в тот экземпляр набора S, владельцем которого является
указанная запись-владелец набора.
Пример 7.9. Пусть требуется запомнить записи ЗАКАЗЫ и при этом авто-
матически включить их в экземпляры наборов ЛЮДИ_ЗАКАЗЫ и ТОВАРЫ_ЗА-
КАЗЫ. Если ФАМИЛИЯ является CALC-ключом для записей ЛЮДИ, можно исполь-
зовать фамилию человека для селекции экземпляра набора ЛЮДИ_ЗАКАЗЫ, вклю-
чая в декларацию набора ЛЮДИ_ЗАКАЗЫ предложение
SET SELECTION IS THRU OWNER USING ФАМИЛИЯ
Осуществить селекцию экземпляра набора ТОВАРЫ_ЗАКАЗЫ можно через
идентификатор владельца НАИМ_ТОВАРА, однако для разнообразия будем выпол-
нять селекцию экземпляра набора ТОВАРЫ_ЗАКАЗЫ, включая в декларацию этого
набора предложение
SET SELECTION IS THRU CURRENT OF ТОВАРЫ_ЗАКАЗЫ SET
Предложение
INSERTION IS AUTOMATIC
должно входить в декларацию как типа набора ЛЮДИ_ЗАКАЗЫ, так н ТОВАРЫ_
ЗАКАЗЫ. Программа, приведенная на рис. 7.11, читает заказ, запоминает его в фай-
ле ЗАКАЗЫ и автоматически включает его в требуемые экземпляры типов наборов
ЛЮДИ_ЗАКАЗЫ и ТОВАРЫ_ЗАКАЗЫ.в
read N, I, Q /‘фамилия, товар и количество*/
СЛЕД_ЗАКАЗ: = СЛЕД_ЗАКАЗ +1/* дать новый номер заказа*/
ЛЮДИ.ФАМИЛИЯ = N/* подготавливаем селекцию набора ЛЮДИ_ЗАКАЗЫ*/
ТОВАРЫ. НАИМ_ТОВАРА: = I
FIND ТОВАРЫ RECORD USING CALC-KEY
/* подготавливаем селекцию набора ТОВАРЫ„ЗАКАЗЫ*/
ЗАКАЗЫ.НОМЕР_ЗАКАЗА: = СЛЕД,ЗАКАЗ
ЗАКАЗЫ. КОЛИЧЕСТВО: = Q
/* создаем в шаблоне новую запись ЗАКАЗЫ*/
STORE ЗАКАЗЫ /* автоматически помещаем эту запись в экземпляр набора
ЛЮДИ_ЗАКАЗЫ, владельцем которого является N, и в текущий экземпляр набора
ТОВАРЫ _ ЗАКАЗЫ, владелец которого — I*/
Рис, 7.11. Ввести и запомнить новый заказ
231
Существует еще один важный вид селекции набора, в котором мы следу-
ем по цепочке из последовательности наборов DBTG, чтобы найти требуемый
экземпляр последнего в цепочке набора. Этот вид селекции используется
при наличии естественной иерархии типов записей, такой, как ШТАТЫ;
ОКРУГА и ГОРОДА. Каждый штат включает несколько округов, а каждый
округ — множество городов. Очевидно, что названия городов не уникальны,
хотя ни в одном округе нет двух городов с одним и тем же названием. Наз-
вания округов также не уникальны, хотя нет такого штата, в котором два
округа имели бы одинаковые названия. Например, округ Вашингтон есть в
Алабаме, Арканзасе, Колорадо, Флориде, Джорджии и еще 23 других шта-
тах.
Предположим, что имеются декларации типов записей и наборов DBTG,
представленные на рис. 7.12. Пусть при запоминании новой записи ГОРОДА
RECORD ШТАТЫ
1 НАЗВАНИЕ-ШТАТА;
RECORD ОКРУГА
1 НАЗВАНИЕ-ОКРУГА;
RECORD ГОРОДА
1 НАЗВАНИЕ-ГОРОДА;
DBTG SET ОКРУГА _ В _ ШТАТАХ
OWNER IS ШТАТЫ
MEMBER IS ОКРУГА;
DBTG SET ГОРОДА _ В _ ОКРУГАХ
OWNER IS ОКРУГА
MEMBER IS ГОРОДА;
Рис. 7.12. Декларация штатов, округов и городов
нужно включить ее в соответствующий экземпляр набора ГОРОДА_В_ОК-
РУГАХ, что требует знания округа. Но одно название округа еще не опреде-
ляет экземпляр набора. Мы должны знать также название штата, в котором
находится округ, а следовательно, и города. Таким образом, чтобы правильно
выбрать экземпляр набора ГОРОДА_В_ОКРУГАХ, нужно использовать
название штата в качестве CALC-ключа для нахождения требуемого экземп-
ляра набора ОКРУГА_В_ШТАТАХ. Затем с помощью названия округа
можно найти нужную запись ОКРУГА в этом экземпляре набора ОКРУГА,
_В_ШТАТАХ. Найденная запись ОКРУГА в свою очередь является вла-
дельцем требуемого экземпляра набора ГОРОДА, В_ ОКРУГАХ для новой
записи ГОРОДА. Приведенный выше алгоритм может быть выражен с помо-
щью следующего предложения селекции набора для ГОРОДА, В -ОКРУ-
ГАХ:
SET SELECTION IS THRU ОКРУГА _ В _ ШТАТАХ OWNER USING
НАЗВАНИЕ_ШТАТА
THEN THRU ГОРОДА—В—ОКРУГАХ OWNER USING
НАЗВАНИЕ-ОКРУГА
Располагая приведенной выше декларацией селекции набора для набо-
ра DBTG ГОРОДА, В -ОКРУГАХ, можно включить запись для города Мид-
вейл, округ Вашингтон, штат Айдахо (рис. 7.13). Запись автоматически ста-
новится членом экземпляра набора для округа Вашингтон штата Айдахо.
НАЗВАНИЕ-ГОРОДА: = «Мидвейл»
НАЗВАНИЕ—ОКРУГА: = «Вашингтон»
НАЗВАНИЕ-ШТАТА: = «Айдахо»
STORE ГОРОДА
Рис. 7.13. Запоминание записи ГОРОДА для Мидвейла, округ Вашингтон, штат
Айдахо
232
Ручное включение и удаление
Для включения записей в экземпляры наборов вместо селекции наборов
Можно использовать явную команду. Один и тот же тип записи может быть
объявлен как автоматический (AUTOMATIC) член для одних наборов
DBTG, тогда применяется автоматическая селекция набора, и.как ручной
(MANUAL) для некоторых других наборов DBTG. В последнем случае ис-
пользуется спецификация INSERTION IS MANUAL, и запись при ее запо-
минании не становится членом какого-либо экземпляра этого набора DBTG.
Для включения записи г типа Т (уже существующей в базе данных) как
члена набора DBTG S в указанный экземпляр набора S необходимо, во-пер-
вых, сделать данный экземпляр набора текущим S любым из подходящих
для этого способов, а во-вторых, сделать г текущей записью процесса. После
этого можно выполнить команду
INSERT Т INTO S
Заметим, что запись г должна быть не только текущей типа Т, но и теку-
щей записью процесса. Разрешается указывать в команде после INTO спи-
сок наборов DBTG. Если это сделано, то осуществляется включение записи
г в текущий экземпляр каждого из таких наборов.
П р и м е р 7.10. В примере 7.9 мы запоминали запись ЗАКАЗЫ и автоматически
Включали ее в экземпляры наборов ЛЮДИ_ЗАКАЗЫ и ТОВАРЫ_ЗАКАЗЫ. Если
вместо этого объявить ручное включение записи ЗАКАЗЫ в наборы DBTG ЛЮДИ_
ЗАКАЗЫ и ТОВАРЫ_ЗАКАЗЫ, то можно с помощью процедуры, показанной иа
рис. 7.14, осуществлять ее включение в экземпляры этих наборов вручную.
Для исключения записи типа Т, являющейся текущей процесса, из ее
экземпляра набора DBTG S используется команда
REMOVE Т FROM S
Как и в случае включения, S может быть заменено списком наборов
DBTG. Напомним, что исключаемая запись должна быть текущей не только
для типа записи Т, но и текущей процесса. Это соглашение, как и в других
операторах, служит дополнительной проверкой для выявления программных
ошибок. Следует также предупредить читателя, что декларация RETENT-
ION (сохранение) для набора DBTG, которая будет обсуждаться в следую-
щем разделе, позволяет запретить исключение записи из экземпляра набо-
ра S.
read N, I, Q
СЛЕД_ЗАКАЗ: = СЛЕД-ЗАКАЗ +1
ЛЮДИ. ФАМИЛИЯ: = N
FIND ЛЮДИ RECORD USING CALC-KEY
/* устанавливаем текущую набора ЛЮДИ — ЗАКАЗЫ*/
ТОВАР. НАИМ _ ТОВАРА: = I
FIND ТОВАРЫ RECORD USING CALC-KEY
/* устанавливается текущая набора ТОВАРЫ-ЗАКАЗЫ*/
ЗАКАЗЫ. НОМЕР-ЗАКАЗА: = СЛЕД.ЗАкАЗ
ЗАКАЗЫ. КОЛИЧЕСТВО: = Q
STORE ЗАКАЗЫ /* новый заказ является теперь текущей процесса, но не членом
экземпляра набора*/
INSERT ЗАКАЗЫ INTO ЛЮДИ_ЗАКАЗЫ, ТОВАРЫ-ЗАКАЗЫ
Рис. 7.14. Ручное включение новой записи ЗАКАЗЫ
233
Модификация записей
Команда
MODIFY <тип записи>
осуществляет копирование шаблона для типа записи <тип записи> в теку-
щую запись процесса. Если текущая процесса имеет иной тип записи, то это
ошибка. Можно также модифицировать выбранное подмножество полей в
текущей процесса следующим образом:
MODIFY <тип записи>; <список полей>
Если Т является типом записи текущей процесса, значения полей в спи-
ске копируются из шаблона для Т в соответствующие поля текущей записи
процесса. Остальные поля текущей процесса остаются неизменными. Таким
образом, чтобы изменить цену, установленную компанией «Солнечная про-
дукция» на салат, на 0,75, необходимо выполнить программу, приведенную
на рис. 7.15.
ЦЕНЫ.НАИМ.ТОВАРА: = «салат»
ЦЕНЫ.НАЗВ-ПОСТ: = «Солнечная продукция»
FIND ЦЕНЫ RECORD USING CALC-KEY
ЦЕНЫ.ЦЕНА: = .75
MODIFY ЦЕНЫ; ЦЕНА
Рис. 7.15. Установить цену 0,75 и а салат, продаваемый компанией «Солнечная про-
дукция»
Удаление записей из базы данных
Текущая запись процесса, которая к тому же должна быть и текущей спе-
цифицированного типа записи, удаляется из файла записей этого типа коман-
дой
DELETE <тип записи>
Естественно, что если текущая процесса — член каких-либо экземпля-
ров наборов, она исключается из них. В том случае, когда текущая процес-
са является владельцем каких-либо экземпляров наборов, то эти экземпляры
в данный момент не должны иметь записей-членов, иначе фиксируется ошиб-
ка, и удаление не производится.
Предусматривается другая форма оператора DELETE:
DELETE <тип записи> ALL
Она применима даже тогда, когда текущая запись процесса является
владельцем некоторых непустых экземпляров наборов. Оператор DELETE
ALL не только позволяет удалить текущую запись процесса, как это делает
ранее указанный оператор DELETE, но и рекурсивно применяется к любым
членам экземпляров наборов, владельцами которых служит удаляемая за-
пись. Таким образом, возможен случай, когда оператор DELETE ALL раз-
рушает всю базу данных.
Пример 7.11. Чтобы удалить заказ по заданному его номеру, нужно напи-
сать:
read ЗАКАЗЫ.НОМЕР-ЗАКАЗА
FIND ЗАКАЗЫ RECORD USING CALC-KEY
DELETE ЗАКАЗЫ
234
Так как записи ЗАКАЗЫ не являются владельцами каких-либо наборов DBTG,
данный заказ просто удаляется нз файла записей ЗАКАЗЫ и каждого из наборов
DBTG ЛЮДИ_ЗАКАЗЫ и ТОВАРЫ_ЗАКАЗЫ, которым она принадлежит.
В качестве другого примера можно рассмотреть случай выхода из кооператива
Робина. Для удаления сведений о нем из базы данных следует выполнить программу
NAME : = «Робин»
FIND ЛЮДИ RECORD USING CALC-KEY
DELETE ЛЮДИ ALL
В результате такого уничтожения удаляется ие только запись для Робина из фай-
ла ЛЮДИ, но и весь экземпляр набора ЛЮДИ_ЗАКАЗЫ, владельцем которого счи-
тается Робин. Рекурсивно каждый заказ, принадлежащий удаляемому экземпляру
набора, также удаляется из файла ЗАКАЗЫ и экземпляра набора ТОВАРЫ_ЗАКА-
ЗЫ, членом которого он является. Поскольку записи типа ЗАКАЗЫ ие служат вла-
дельцами каких-либо экземпляров наборов, рекурсия и дальнейшие изменения базы
данных на этом завершаются.!
7.5. НЕКОТОРЫЕ ДОПОЛНИТЕЛЬНЫЕ ВОЗМОЖНОСТИ
ПРЕДЛОЖЕНИЙ DBTG
В настоящем разделе дается краткий обзор нескольких наиболее важных
аспектов предложений DBTG, которые не были затронуты ранее в настоящей
главе. Они включают способы размещения записей и организации наборов,
декларации обязательного или необязательного членства в наборе, области,
а также упорядочение членов в экземплярах наборов.
Способы размещения
Способ размещения для типа записи представляет собой описание струк-
туры хранения записей этого типа.
Ранее уже упоминался наиболее важный способ размещения:
LOCATION MODE IS CALC <процедура> USING ссписок полей>
Здесь список полей представляет собой множество полей, которое мы на
звали CALC-ключом. При таком способе размещения предполагается (но не
требуется), что файл для данного типа записи должен храниться в участках:
по одному участку на каждое значение, продуцируемое процедурой «хеши-
рования» с именем<процедура>, применяемой к значениям полей, которые
указываетСсписок полей>. Вполне приемлема альтернатива, когда Спро-
цедура> используется для поиска участка, которому принадлежит запись,
с помощью описанного в разд. 2.3 разреженного индекса или В-дерева, рас-
смотренного в разд. 2.4. Вообще не существует каких-либо принципиальных
ограничений на характер тех действий, которые может исполнять Спроце-
дура>. Однако пользователь имеет право предполагать, что при заданных
значениях дляСсписка полей> определение местоположения некоторой за-
писи (возможно, нескольких записей), обладающей такими значениями, осу-
ществляется эффективно. Система обязана обеспечить Встроенные процеду-
ры, которые способны выполнять такой поиск.
Не следует забывать к тому же, что при необходимости поиска в файле
записей заданного типа с помощью оператора
FIND DUPLICATE <тип запнси> RECORD BY CALC-KEY
следует объявить <тип записи> со способом размещения CALC.
235
Другим способом размещения является DIRECT. Его можно специфи-
цировать с помощью предложения
LOCATION MODE IS DIRECT
В данном случае место хранения записи определяет ключ базы данных,
а не CALC-ключ. В принципе записи этого типа могут храниться в файле в
любом порядке. Доступ к ним будет обеспечиваться предоставлением ключей
базы данных, которые, в сущности, определяют местоположение записей.
Способ размещения VIA (через) для записей типа 7\ объявляется следую-
щим образом:
LOCATION MODE IS VIA <имя набора> SET
При этой декларации предполагается, что записи типа Т1 являются
членами указанного набора DBTG S, и каждая запись типа группи-
руется с владельцем экземпляра набора S, членом которого она являет-
ся. Если Т2 — тип записи-владельца набора S, то файл записей Т2 мо-
жет рассматриваться как файл записей переменной длины с форматом
Т2(ТХ)*. Такой файл может быть реализован с помощью записей фиксирован-
ной длины способом, предложенным в разд. 2.6. Его можно было бы также ре-
ализовать в виде последовательности, упорядоченной «сверху вниз», кото-
рая была предложена в разд. 3.3 для реализации иерархической структуры
данных. Вероятно, другой альтернативой рассмотренным выше способам
является размещение записей Т1 в любом порядке и использование муль-
тисписковых структур, упоминавшихся в разд. 3.2, для связи записей Tt с
их владельцем в кольцо.
Применение способа размещения VIA SET приводит к возникновению
некоторых очень сложных структур. Возможна, например, ситуация, когда
тип записи Т2, заданный декларацией
LOCATION MODE IS VIA R SET
в свою очередь является типом записи-члена набора DBTG, типом владельца
которого является Т3. Тогда записи типов 7\, Тг и Т3 организуются как
файл записей переменной длины с форматом Т3 (Т2 (7\)*)*. Заметим, что
если для записи типа Т используется способ размещения VIA SET, то вклю-
чение ее в набор DBTG должно быть определено как AUTOMATIC, посколь-
ку в противном случае не существует пространства для размещения новой
записи.
Способы организации наборов
Как и для типов записей, для наборов DBTG может декларироваться
различная структура данных. Вместе с тем по сравнению с типами записей
предложения DBTG являются менее конкретными относительно способов
структуризации наборов и предоставляют реализатору свободу действий
при разработке и именовании таких структур. Однако, в любой реализации
требуются следующие два средства:
1. Цепной способ организации наборов. Это — обычная мультисписковая
структура, описанная в разд. 3.2. Предусматривается факультативная воз-
можность наличия указателей в обоих направлениях кольца х.
1 Ранее эта возможность не упоминалась. Фактически оператор FIND может
просматривать наборы DBTG как в прямом, так и в обратном направлении.
236
2. Организация наборов с помощью массивов указателей. В этом случае
каждая запись-член набора содержит указатель на своего владельца. Кро-
ме того, с владельцем ассоциирован массив указателей, содержащий по одно-
му указателю на каждую запись-член данного экземпляра набора.
Классы сохранения членства в наборе
Для того чтобы обеспечить проверку некоторых видов программных оши-
бок, можно, если это необходимо и оправдано, объявить, что сохранение за-
писей-членов в экземпляре набора является обязательным (MANDATORY).
В этом случае любая запись типа Т, которая однажды стала членом некото-
рого экземпляра набора S либо автоматически при ее запоминании, либо
вручную по команде INSERT, должна всегда 1 оставаться членом какого-ли-
бо экземпляра S. Вариантом, противоположным MANDATORY, является
OPTIONAL (факультативный)2.
Спецификация сохранения членства в наборе MANDATORY налагает
некоторые ограничения на способы манипулирования записями типа Т. Так,
нельзя исключить запись типа Т из экземпляра набора S. Однако можно ско-
пировать запись в рабочую область, удалить ее из базы данных, а затем вклю-
чить копию в другой экземпляр набора S.
Области
Область можно рассматривать как абстрактное представление раздела
пространства во внешней памяти3. Несмотря на то что характер области точно
определяется системой, можно тем не менее представить себе область как
имя некоторого цилиндра на диске. Мы не допустим при этом большой
ошибки. Декларация каждого типа записей может предусматривать хранение
записей этого типа в одной или нескольких областях. Вместе с тем в одной
области могут размещаться записи нескольких типов. Для любой используе-
мой области в рабочем пространстве, так же как для записей, наборов и про-
цесса, поддерживается указатель «текущей (записи) области». Хотя большин-
ство областей и является частью постоянной базы данных, можно объявить
область временной (TEMPORARY). В этом случае область создается в на-
чале исполнения прикладной программы, в которой она объявлена, и разру-
шается при завершении программы. Такие области могут быть использова-
ны для хранения временных данных, создаваемых программой.
Концепция области полезна по двум причинам. Во-первых, она позволяет
повысить эффективность системы и, во-вторых, обеспечивает некоторую до-
полнительную степень секретности. Эффективность, например, может быть
повышена, если все записи некоторого типа размещаются в одной области,
которая реализована в виде цилиндра на диске. Поскольку поиск записи на
диске выполняется значительно быстрее, когда головки не перемещаются
между цилиндрами, просмотр записей этого типа более эффективен 4.
Для обеспечения секретности данных представление может объявлять
только некоторое подмножество областей, используемых концептуальной
1 Пока она существует в базе данных. — Примеч. ред.
2 В этом случае запись-член набора может быть свободно исключена из любого
экземпляра набора данного типа. Она может существовать в базе данных независимо
от ее членства в каком-либо экземпляре набора данного типа. — Примеч. ред.
3 Точнее, область следует трактовать как раздел концептуальной базы данных. —
Примеч. ред.
4 При работе системы базы данных в режиме мультипользователя эта идея может
не привести к желаемой цели. — Примеч. ред.
237
схемой. Тогда записи, которыми оперируют программы, базирующиеся на
одном представлении, могут быть сделаны недоступными для программ, ба-
зирующихся на другом представлении, даже если эти записи имеют один
и тот же тип.
Упорядоченные экземпляры наборов
При включении записи в качестве члена в некоторый экземпляр набора
она должна быть размещена где-либо в «кольце», образованном владельцем и
членами экземпляра набора. Предложение ORDER (порядок) в декларации
набора DBTG специфицирует место включения нового члена в кольцо.
Существуют следующие варианты включения записей:
1. ORDER IS FIRST (включить первой). Новая запись-член помещается
непосредственно после владельца данного экземпляра набора. Если при этом
для реализации набора не используется мультисписковая структура, то но-
вый член помещается первым в списке членов, независимо от того, как факти-
чески представляется данный список.
2. ORDER IS LAST (включить последней). Новая запись-член помеща-
ется непосредственно перед владельцем, т. е. последней в списке членов.
3. ORDER IS PRIOR (включить перед текущей). Новая запись помеща-
ется непосредственно перед текущей записью набора DBTG, которая должна
быть членом этого экземпляра набора.
4. ORDER IS NEXT (включить после текущей). Этот вариант анало-
гичен PRIOR, однако новая запись включается в кольцо непосредственно
после текущей записи набора.
5. ORDER IS SORTED (включить в сортированном порядке). Можно
специфицировать, например, ORDER IS SORTED BY DATABASE KEY.
Это означает, что ключи базы данных для записей-членов интерпретируются
как целые числа и что записи с меньшими значениями ключа базы данных
предшествуют записям с большими его значениями. В общем случае мы опре-
деляем одно или более полей записей-членов набора в качестве ключа сор-
тировки. Допускается сортировка по возрастанию или убыванию каждого из
полей ключа сортировки. Например, если Fx и F2 — два поля записей-чле-
нов некоторого набора DBTG, то можно объявить:
ASCENDING KEY IS Flt F2
Тогда записи экземпляра набора сначала сортируются по значениям по-
ля Fj в возрастающем порядке (т. е. в лексикографическом, если значения
Fx являются строками, или в числовом, если значения Ft являются числами).
Далее записи заданного экземпляра набора с одинаковыми значениями Fx
вновь сортируются по значениям поля F2 в возрастающем порядке. В дей-
ствительности ключ сортировки не обязательно должен быть ключом в обыч-
ном смысле. Допускается появление записей с одним и тем же ключом сор-
тировки, если объявлено
DUPLICATES ARE ALLOWED
(дубликаты допускаются). Альтернативным вариантом служит DUPLICA-
TES ARE NOT ALLOWED (дубликаты не допускаются). Результат его оче-
виден.
Резюме
Дадим теперь обзор обязательных и факультативных элементов декла-
раций записей и наборов DBTG. Некоторые из них ранее не упоминались и
238
будут здесь кратко описаны. Для деклараций записей следующие элементы
являются обязательными (или факультативными, если это указывается) и
должны появляться в указанном порядке:
1. RECORD <тип записи>. Декларация имени типа записи.
2. LOCATION MODE IS< вариант способа размещения^». Здесь и в
разд. 7.1 приведены описания вариантов CALC, DIRECT и VIA SET.
Предложение, определяющее способ размещения, является факульта-
тивным *.
3. WITHIN <список областей>. Указывает список областей, в которых
могут размещаться записи данного типа. Описание областей было рассмот-
рено в данном разделе.
4. ON-условия. Факультативные процедуры, которые вызываются
системой перед или после выполнения различных команд, подобных S FORE.
Здесь не обсуждается этот аспект предложений DBTG, однако в разд. 9.1
приведены замечания относительно его использования для проверки целост-
ности данных.
5. PRIVACY-информация. Задает пароль или подобную информацию о
защите данных для различных команд манипулирования определяемым ти-
пом записей. Эта информация является фукультативной и в дальнейшем не
обсуждается.
6. Информация о полях типа записи, их уровнях и типах данных (см.
разд. 7.1).
К основным видам информации в декларации наборов DBTG относятся:
1. DBTG 5ЕТ<имя набора>. Декларация набора DBTG.
2. MODE IS<cnoco6 организации набора>. Способы огранизации на-
боров DBTG были рассмотрены в данном разделе.
3. ORDER 15<вариант упорядочения^. Описание способов упорядо-
чения членов экземпляра набора приведено в настоящем разделе.
4. ON-условия. Как и в случае декларации типов записей, можно объ-
явить, что определенные процедуры должны быть вызваны, когда к набору
DBTG применяется команда, подобная INSERT. Эта информация является
факультативной.
5. PRIVACY-информация. Информация о защите экземпляров наборов,
как и в случае типов записей. Декларации секретности являются факульта-
тивными.
6. OWNER 15<тип записи>. Указывает тип записи-владельца набора
DBTG.
7. MEMBER IS <тип записи>. Указывает тип записи-члена набора
DBTG, способ его включения в набор (AL’TOMATIC/MANUAL) и класс
сохранения членства (MANDATORY/OPTIONAL). Способы включения в
набор обсуждаются в разд. 7.4, а сохранения членства — в этом разделе.
8. KEY-информация. Описывает ключ сортировки набора, если в п. 3
объявлено ORDER IS SORTED. Этот вопрос рассматривался в данном разде-
ле.
9. SEARCH KEY-информация.Термин «поисковый ключ» означает вто-
ричный индекс. Допускается декларация нескольких поисковых ключей
для тина записи-члена с тем, чтобы обеспечить эффективный поиск записей-
членов в экземпляре набора.
10. SET SELECTION-информация. Эта информация описана в разд. 7.4.
1 Если это предложение не специфицировано, СУБД использует способ размеще-
ния, установленный для данного случая ее разработчиком. — Примеч. ред.
239
УПРАЖНЕНИЯ
7.1. Определите, используя язык определения данных, сети для
а) примера 3.6; б) рис. 3.5.
7.2. Предположим, что имеются следующие типы записей:
КОМПАНИЯ (НАЗВАНИЕ-КОМП, АДРЕС_КОМП)
АКЦИЯ (НОМЕР—АКЦИИ, КОЛИЧЕСТВО)
ЧЕЛОВЕК (ИМЯ-ЧЕЛОВЕКА, АДРЕС-ЧЕЛОВЕКА)
Пусть имеются также следующие наборы DBTG:
1. СЛУЖАЩИЕ, указывающий служащих компании. Запнсью-владелЬЦём яв*
ляется КОМПАНИЯ, а записями-членами— ЧЕЛОВЕК.
2. ВЛАДЕЕТ с записью-владельцем ЧЕЛОВЕК и записями-членами АКЦИЯ.
Этот набор указывает держателей акций и какими акциями они владеют.
3. КОМП_АКЦИИ с записью-владельцем КОМПАНИЯ и записями-членами
АКЦИЯ, указывающий, к какой компании относится каждая акция.
Предполагается, что для всех типов записей используется способ размещения
CALC с ключевыми полями НАЗВАНИЕ_КОМП, НОМЕР_АКЦИИ и ИМЯ-ЧЕЛО-
ВЕКА соответственно. Напишите на упрощенном языке манипулирования данными,
рассмотренном в данной главе, программы, которые выполняют следующие действия:
а) читает номер акции и печатает имя и адрес человека, владеющего этой акцией;
б) печатает список всех людей, владеющих акциями ИВМ; разрешается при этом
дважды напечатать имя человека, владеющего двумя сертификатами;
в) печатает список всех людей, имеющих акции компании, в которой они рабо-
тают (предполагается, что существует сингулярный набор DBTG, записями-членами
которого являются записи ЧЕЛОВЕК);
г) определяет общее количество акций ИБМ, которыми владеют ее служащие.
7.3. Предположим, что требуется ввести новые акции в базу данных из упраж-
нения 7.2. При этом необходимо каждую новую акцию при ее запоминании в базе дан-
ных включать в соответствующие экземпляры наборов ВЛАДЕЕТ и КОМП_АКЦИИ.
а) Напишите предложения селекции наборов, которые допускают автоматичес-
кое включение записи АКЦИЯ в экземпляры указанных, наборов.
б) Напишите программу, которая читает необходимые данные и правильно за-
поминает запись о новой акции.
в) Предположим, что мы хотим использовать ручное включение вместо автомати-
ческого. Напишите программу, которая запоминает записи АКЦИЯ и включает их
вручную в соответствующие экземпляры наборов ВЛАДЕЕТ и КОМП_АКЦИИ.
*7.4. Обсудите преимущества и недостатки различных способов размещения
записей и способов организации наборов, определенных в предложениях DBTG. При
каких видах запросов одну структуру данных можно предпочесть другой?
*7.5. Отношение может быть представлено типом записи в смысле DBTG. Это
удобно, если для данного типа записи предполагается существование некоторого син-
гулярного набора.
а) Покажите, каким образом можно выполнить каждую операцию реляционной
алгебры с помощью языка манипулирования данными DBTG.
б) Объясните, каким образом существование фиктивного типа записи и наборов
DBTG, связывающих ее с записями типов и S, может быть использовано для реали-
зации операции соединения между и S.
Библиографические замечания
Предложения DBTG содержатся в документе КОДАСИЛ [39]. Периодически вно-
симые изменения можно найти в Журнале развития языка Кобол1 [40]. Книга Олле [126]
представляет собой учебное пособие по сетевой модели.
Система TOTAL [38] является главной коммерческой СУБД, основанной на се-
тевой модели. Системы IDMS [50] и ADABAS [158] представляют собой другие важные
реализации некоторых из этих идей2. Каждая из этих систем описана в книге Цикрит-
зиса и Лоховского [170]. Систему TOTAL описывает также Карденас [30]. Вайдер-
хольд [175] перечисляет многие коммерческие системы, основанные на идеях DBTG.
1 В указанном издании можно найти только сведения о языковых средствах базы
данных для Кобола. Детально познакомиться с языком определения данных схемы, а
также с языком определения хранимых данных по материалам Отчета Комитета по
языку определения данных КОДАСИЛ (см. примеч. к с. 216). — Примеч. ред.
2 Системы TOTAL и ADABAS нельзя отнести к классу СУБД типа КОДАСИЛ
как по используемым в них языковым спецификациям, так и с точки зрения поддер-
живаемой этими системами структуры данных. — Примеч. ред.
240
ГЛАВА 8
IMS: ИЕРАРХИЧЕСКАЯ СИСТЕМА
Система управления информацией IMS (Information Management Sys-
tem), разработанная фирмой ИБМ, представляет собой одну из наиболее ши-
роко применяемых коммерческих систем. Именно с этой системой в значи-
тельной степени связана популярность иерархической модели данных, на
которой она базируется. Поэтому необходимо рассмотреть наиболее важные
особенности системы IMS. Такое рассмотрение будет полезным также для ил-
люстрации иерархического подхода в целом. Следует отметить, что практи-
чески все сетевые системы используют «позаписное»1 манипулирование дан-
ными, положенное в основу предложений DBTG, рассмотренных в предыду-
щей главе. Такая же технология манипулирования данными реализована и в
IMS, хотя она не является характерной чертой всех иерархических систем,
8.1. ОБЗОР СИСТЕМЫ
На рис. 8.1 показано, каким образом база данных становится доступной
прикладной программе и как программа может использовать или изменять
данные. При этом предполагается (нижняя часть рисунка), что данные струк-
туризованы с помощью описаний физических баз данных (DBD — Data
Base Description). Схема физической базы данных является единственным де-
ревом типов логических записей, называемых в терминологии IMS сегмен-
тами. Описание физической базы данных включает имена сегментов и их по-
лей, информацию об образуемой сегментами иерархической структуре, а
также спецификации физической организации базы данных. Может быть вы-
бран один из четырех способов физической организации, которые будут об-
суждаться в разд. 8.4.
«Физическая база данных» по терминологии IMS не адекватна физичес-
кой базе данных, рассмотренной в гл. 1, хотя эти концепции аналогичны.
Прежде всего полная база данных может храниться во многих физических
базах данных IMS. С другой стороны, физическая база данных IMS олицет-
воряет собой концептуальную модель, иерархию данных, в то время как в
гл. 1 физическая база данных рассматривалась как организация файлов,
не зависящая от их концептуального смысла на более высоких уровнях аб-
стракции.
Логические базы данных, подобно физическим, представляют собой иерар-
хии сегментов. Каждая логическая база данных конструируется из одной
или нескольких физических баз данных с помощью описания, аналогичного
по форме описанию физических баз данных. Сегменты логической базы дан-
ных в действительности не существуют. Они обозначают один или в некото-
1 Технология манипулирования данными, при которой СУБД рассматривает
отдельную запись как единицу обмена данными между прикладной программой и базой
данных. — Примеч. ред.
241
рых случаях несколько сегментов физической базы данных. В логической ба-
зе данных могут использоваться указатели, помещенные специально для
этой цели в сегменты физической базы данных, для создания иерархии, со-
вершенно отличной от той, которая положена в основу физической базы дан-
ных (физических баз данных). Так, в разд. 8.3 показывается, как средствами
Рис. 8.1. Связь между программой и данными
логических баз данных можно осуществить имитацию сетей или отображе-
ний «многие ко многим». Совокупность логических баз данных, созданная на
основе некоторой совокупности физических баз данных, хорошо аппроксими-
рует введенную в гл. 1 концептуальную базу данных.
Описание базы данных
Язык определения данных, используемый для изображения описаний фи-
зических или логических баз данных, представляет собой в действительности
совокупность макрокоманд языка Ассемблера.
1. DBD. Является первым предложением в определении базы данных
и имеет среди прочих параметры NAME =<имя базы данных> и ACCESS=
<метод>. Параметр NAME (имя) задает имя базы данных, а параметр
ACCESS (доступ) — метод доступа. При этом <метод> может специфициро-
вать HSAM, HISAM, HDAM или HI DAM и указывать таким образом один
из четырех способов организации хранения данных. Указанные методы до-
ступа, разработанные для системы IMS, подробно рассматриваются в разд.
8.4. Другим значением параметра<метод> может быть также слово LOGI-
CAL, указывающее, что определяется логическая база данных.
2. DATASET. Эта макрокоманда и ее параметры специфицируют до-
полнительную информацию об организации хранения и используемых запо-
минающих устройствах. Она здесь подробно не обсуждается.
3. SEGM. Вводит определение некоторого сегмента. К его параметрам
относятся NAME, задающий имя определяемого сегмента, и PARENT, ука-
242
зывающий исходный сегмент в определяемой иерархии. Другие параметры
задают число байт, используемых сегментом, оценку числа экземпляров это-
го типа сегмента, порожденных каждым экземпляром его исходного типа
сегмента в базе данных, а также информацию о наличии некоторых полей
указателей (они будут рассмотрены позже ) в сегменте.
4. FIELD. Специфицирует поле сегмента. Его параметр NAME задает
имя поля. В остальных параметрах сообщаются число байт, используемое
полем, смещение поля (число байт, использованных предыдущими полями
данного сегмента), а также тип данных этого поля. Одно и только одно поле
сегмента может быть объявлено полем упорядочения. Экземпляры типа сег-
мента, порожденные для одного экземпляра исходного типа сегмента, появ-
Рис. 8.2. Схема базы данных о недвижимости
ляются в базе данных в порядке возрастания значений их полей упорядоче-
ния (например, в лексикографическом, если тип поля упорядочения опре-
делен как строка литер). Экземпляры корневого типа сегмента аналогичным
образом упорядочиваются по их полям упорядочения. Например, параметр
NAME = (ZAP, SEQ, U) определяет поле ZAP в качестве поля упорядочения
этого типа, сегмента. Буква U (Unique — единственный) означает, что ни
один экземпляр исходного типа сегмента не может иметь два порожденных
сегмента с одним и тем же значением поля упорядочения. Использование
вместо U буквы М означает, что может быть несколько порожденных сег-
ментов для одного исходного с одним и тем же значением поля упорядочения.
Это поле часто называется «ключом», хотя даже при спецификации варианта
U могут появиться два экземпляра сегмента с одним и тем же значением поля
упорядочения, поскольку они будут порожденными для различных экземп-
ляров исходного сегмента в базе данных.
5. DBDGEN, FINISH и END в перечисленном порядке завершают оп-
ределение базы данных.
В последующем изложении мы будем опускать все макрокоманды, кро-
ме DBD, SEGM и FIELD, а также все параметры, кроме NAME и PARENT.
Пример 8.1. База данных кооператива в Счастливой долине не обеспечивает
интересной иерархии. Поэтому рассмотрим базу данных Национального агентства по
недвижимости, схема1 которой приведена на рис. 8.2. Обратившись к разд. 3.3, чита-
1 Во избежание путаницы с понятием «схема базы данных» в терминах языка
определения данных здесь, как и в ряде других случаев в настоящей главе, было бы
уместнее использовать термин «диаграмма». — Примеч. ред.
243
тель может вспомнить, что фактическая. база данных, представленная этой схемой,
состоит из последовательности деревьев, называемых на жаргоне IMS записями базы
данных — по одной для каждого экземпляра корневого типа сегмента. Корневым сег-
ментом любого дерева является сегмент РАЙОНЫ, а его порожденными сегментами —
КОНТОРЫ — по одному для всех контор в районе. Порожденными для сегмента
Рис. 8.3. Начальный фрагмент базы данных, схема которой приве-
дена на рис. 8.2
КОНТОРЫ являются АГЕНТЫ, СЛУЖАЩИЕ и ОПИСЬ (продаваемой недвижимо-
сти) в указанном порядке, а сегменты АГЕНТЫ в качестве порожденных имеют сег-
менты КЛИЕНТЫ. Никакие иные сегменты не имеют порожденных. На рис. 8.3 по-
казан начальный фрагмент возможной базы данных со схемой, приведенной на рис. 8.2.
Здесь гг, г2, ... представляют сегменты РАЙОНЫ, ог, о2, ... — сегменты КОНТОРЫ,
а2, а2, ... — сегменты АГЕНТЫ, elt е2, ... — сегменты СЛУЖАЩИЕ, Ij> —
сегменты ОПИСЬ, ci, c2, ... — сегменты КЛИЕНТЫ.
DBD NAME = НЕДВИЖИМОСТЬ
SEGM NAME = РАЙОНЫ
FIELD NAME == (НАЗВАНИЕ_РАЙОНА, SEQ, U)
SEGM NAME = КОНТОРЫ, PARENT = РАЙОНЫ
FIELD NAME = (ГОРОД, SEQ, U)
FIELD NAME = АДРЕС_КОНТОРЫ
SEGM NAME = АГЕНТЫ, PARENT = КОНТОРЫ
FIELD NAME = (ИМЯ-АГЕНТА, SEQ, U)
FIELD NAME = СДЕЛКИ
SEGM NAME = СЛУЖАЩИЕ, PARENT = КОНТОРЫ
FIELD NAME = (ТАБ_НОМЕР, SEQ, U)
FIELD NAME = ИМЯ-СЛУЖАЩЕГО
FIELD NAME = АДРЕС-СЛУЖАЩЕГО
FIELD NAME = ЗАРПЛАТА
SEGM NAME = ОПИСИ, PARENT = КОНТОРЫ
FIELD NAME = (АДРЕС-НЕДВИЖИМОСТИ, SEQ, U)
FIELD NAME = ЦЕНА
SEGM NAME = КЛИЕНТЫ, PARENT = АГЕНТЫ
FIELD NAME = (ИМЯ-КЛИЕНТА, SEQ, U)
FIELD NAME = АДРЕС-КЛИЕНТА
Рис. 8.4. Эскизный вариант определения базы данных о недвижимости
На рис. 8.4 эскизно представлено определение базы данных, соответствующей
приведенной схеме (см. рис. 8.2). Это, по всей вероятности, — определение физической
базы данных, реализованной с помощью одного из четырех способов организации хра-
нения данных системы IMS. Однако после некоторых модификаций предложений SEGM
и FIELD мы могли бы получить определение логической базы данных, как описано в
разд. 8.3.И
244
Прикладные программы и представления
Каждая программа определяет свои собственные представления мно-
жества физических и логических баз данных, которыми она оперирует. Пред-
ставление отдельной базы данных (дерева типов сегментов) определяется пос-
ледовательностью макросов, называемой блоком связи программы (РСВ—
Program Communication Block). Совокупность блоков связи программы — по
одному блоку для каждой базы данных, к которой она осуществляет доступ,—
называется блоком спецификации программы (PSB — Program Specifi-
cation Block).
Представление физической или логической базы данных состоит из под-
множества ее сегментов. При этом сегмент может быть включен в представ-
ление только вместе с его исходным сегментом1. Следовательно, корневой
сегмент базы данных всегда включается в любое представление.
РСВ DBDNAME = НЕДВИЖИМОСТЬ
SENSEG NAME = РАЙОНЫ, PROCOPT = К
SENSEG NAME = КОНТОРЫ, PARENT = РАЙОНЫ, PROCOPT = G
SENSEG NAME = СЛУЖАЩИЕ, PARENT = КОНТОРЫ, PROCOPT = G
Рис. 8.5. Блок спецификации программы
Для формирования блока спецификации программы используются сле-
дующие макрокоманды: ,
1. РСВ. Начинает блок связи программы. Ее параметр DBDNAME за-
дает имя основной базы данных, представлением которой является этот блок
связи. Существуют и другие параметры, но они здесь не обсуждаются.
2. SENSEG. Специфицирует чувствительный сегмент, т. е. сегмент, ко-
торый включается в представление. Параметр NAME указывает имя такого
сегмента в основной физической или логической базе данных, а параметр
PARENT сообщает имя исходного для него сегмента. Параметр PROCOPT=
= Ссписок букв> устанавливает виды обработки, т. е. допустимые операции
над этим сегментом. Основными видами обработки являются G (get) —
читать (дать), I (insert) — включать, D (delete) — удалять и R (replace)—
заменять (модифицировать). Вид обработки К (key) указывается для сег-
мента с чувствительностью ключа. Такой сегмент не является в действитель-
ности частью представления. Тем не менее он должен быть указан, так как
в представление включаются некоторые из его порожденных сегментов, а
для каждого сегмента в представлении необходимо, чтобы и его исходный
сегмент также входил в это представление.
3. PSBGEN и END завершают блок спецификации программы, пред-
ставляющий собой перечень блоков связи для программы. В примерах эти
макрокоманды опускаются.
Пример 8.2. Предположим, что отдел зарплаты агентства недвижимости име-
ет программу, которая формирует платежные чеки и рассылает их в соответствующие
конторы. Этой программе необходимы лишь сегментыКОНТОРЫ и СЛУЖАЩИЕ (см.
рис. 8.2). Но поскольку ей требуется сегмент КОНТОРЫ, в блок связи программы
должен быть включен исходный сегмент РАЙОНЫ. На рис. 8.5 приведен примерный
вариант соответствующего блока спецификации программы. В нашем случае исполь-
зуется только один блок связи программы. Напомним, однако, что в общем случае их
может быть несколько в одном блоке спецификацйи программы, если этой программе
требуется доступ к нескольким физическим или логическим базам данных.
1 Технически можно избежать включения исходного сегмента благодаря специ-
фикации для него «чувствительности ключа». Эта концепция будет кратко рассмотрена
в дальнейшем.
245
Значение параметра PROCOPT для сегмента РАЙОНЫ устанавливает вид об-
работки К, означающий, что ои является сегментом с чувствительностью ключа. Этот
сегмент присутствует в представлении только формально и является недоступным.
Для двух остальных сегментов — КОНТОРЫ и СЛУЖАЩИЕ — параметр PROCOPT
устанавливает вид обработки G, означающий, что программа может только читать их.
В общем случае значение параметра PROCOPT может быть последовательностью из не-
скольких букв. В такую последовательность не должна включаться буква К. Напри-
мер, PROCOPT=GI позволяет только читать или вставлять сегменты в базу данных.
Заметим, что если для программы разрешены такие виды обработки, как I, D и R, то
изменения в данном представлении отражаются в основной физической базе данных,
также как в предложениях DBTG, рассмотренных в предыдущей главе, и в отличие от
представлений для ISBL и Query-by-Example, обсуждаемых
в гл. 4.
На рис. 8.6 показана подсхема1, определенная блоком
спецификации программы (см. рис. 8.5). Заметим, что сегмент
РАЙОНЫ не является частью данной подсхемы, поскольку он
был определен только с чувствительностью ключа. Напом-
ним также, что подсхема, вообще говоря, может быть слож-
ным деревом, а не просто одним путем.
В результате ассемблирования блок связи про-
граммы уже мало похож на рис. 8.5. Он становится
блоком данных, доступным одновременно как для
программы, так и для системы IMS. Программа, напи-
Рис. 8.6. Подсхема
санная во включающем языке, вызывает специальную
процедуру, предоставляемую IMS, для манипулирования базой данных.
После каждого вызова процедура возвращает разнообразную информацию.
Наиболее важными ее компонентами являются:
1. Полный сцепленный ключ запрашиваемого сегмента. Полный сцеплен-
ный ключ представляет собой конкатенацию значений полей упорядочения
всех сегментов вдоль пути от корневого до целевого, включая и встречающие-
ся сегменты с чувствительностью ключа. Предположим, что програм-
ма, использующая подсхему рис. 8'6, запрашивает запись служащего,
ТАБ_НОМЕР которого равен 12345, и этот служащий работает в Принстон-
ской конторе Северо-восточного района. Тогда полный сцепленный ключ име-
ет вид:
Северо-восточный, Принстон, 12345.
При этом каждое из трех значений ключей занимает столько байт, сколько
объявлено для него в определении соответствующей базы данных.
2. Информация о состоянии, определяющая успех или неудачу запроса
на поиск специфицированного сегмента. Здесь мы имеем аналогию с перемен-
ной FAIL, введенной нами при рассмотрении предложений DBTG.
Блок связи программы содержит также информацию для вызванной
процедуры IMS. Ее основные компоненты:
а) имя логической или физической базы данных, к которой необходимо
осуществить доступ (берется из макрокоманды РСВ);
б) информация о видах обработки, полученная из параметров PROCOPT
предложения SENSEG, указывающая IMS допустимые операции над различ-
ными сегментами.
8.2. ЯЗЫК МАНИПУЛИРОВАНИЯ ДАННЫМИ
Система IMS предусматривает возможность работы с прикладными
программами, написанными на одном из трех включающих языков: Кобол,
ПЛ/1 и Ассемблер. Выполнение команд манипулирования данными осуще-
1 См. примечание на с. 243. — Примеч. ред.
246
ствляется путем вызова с помощью оператора CALL единственной для каж-
дого языка процедуры. Например, если включающим языком является ПЛ/1,
вызывается процедура PL1TDL1 (PL/1 to DL/1). Процедура CBLTDL1 ис-
пользуется для Кобола, a ASMTDL1 — для Ассемблера. Аргументами вызо-
ва (параметрами процедуры), по существу, служат литерные строки, обра-
зующие команды языка манипулирования данными системы IMS — языка
DL/1 (Data Language One — Язык Данных-1). Введем сначала упрощенную
версию языка DL/1, а затем покажем, что команды действительно выглядят
как аргументы вызова процедуры.
Указатели текущего состояния
Для каждого из представлений, которым оперирует программа, суще-
ствует так называемый текущий (сегмент) представления, т. е. самый по-
следний экземпляр сегмента, к которому осуществлялся доступ. Этот экземп-
ляр сегмента идентифицируется полным сцепленным ключом, помещенным в
блок связи программы для данного представления. В некоторых командах
участвует также исходный для текущего, являющийся чаще всего исходным
сегментом текущего сегмента представления. В действительности, используя
специальные «коды модификации команд», являющиеся модификаторами ос-
новных команд, можно получить текущий сегмент для любого типа сегмента.
Следует подчеркнуть, что введенная DBTG концепция текущей записи не
поддерживается явным образом в языке DL/1. Она лишь помогает мысленно
представлять позиции в базе данных, обозначенные средствами языка DL/1.
Команда GET
Основная поисковая команда языка DL/1, называемая GET UNIQUE
(ДАТЬ УНИКАЛЬНЫЙ), специфицирует путь от экземпляра корневого
сегмента до целевого (искомого) сегмента некоторого типа, который необяза-
тельно является листом в структуре базы данных. Несмотря на слово УНИ-
КАЛЬНЫЙ, целевой сегмент может оказаться не единственным. В этом слу-
чае IMS выберет самый левый сегмент в последовательности деревьев базы
данных (как показано на рис. 8.3) таким образом, чтобы он и предшествую-
щие ему сегменты на пути от корня удовлетворяли условиям, налагаемым
на них в команде GET UNIQUE. Найденный сегмент помещается в область
ввода-вывода, которая представляет собой структуру данных, принадлежа-
щую прикладной программе. Адрес этой области передается DL/1 из прог-
раммы как параметр вызова процедуры.
В упрощенном языке DL/1 мы будем использовать следующий синтаксис
команды GET UNIQUE:
GET UNIQUE <имя сегмента> WHERE <список аргументов поиска сегмента>
Здесь Ссписок аргументов поиска сегмента> состоит из последователь-
ности условий вида
<имя сегмеита>.<имя поля> 0 <констаита>,
возможно, соединенных связками «И», «ИЛИ». Указанное <имя поля> яв-
ляется полем сегмента, имя которого специфицировано как <имя сег-
мента>, а 9 — один из арифметических операторов сравнения ==, <, и т. д.
При этом<имя сегмента> может быть опущено, если оно однозначно оп-
ределяется именем поля.
247
Пример 8.3. Предположим, что иерархия, приведенная на рис. 8.2, являет-
ся представлением, используемым нашей программой. Тот факт, что эта иерархия бы-
ла первоначально названа физической базой данных, не имеет значения, так как мо-
дель данных, используемая для представлений логических и физических баз данных,—
одна и та же. Команда языка
GET UNIQUE АГЕНТЫ WHERE СДЕЛКИ > 1000000
находит первого (самого левого в списке деревьев) агента, объем сделок которого пре-
вышает 1 000 000 дол1. Это реализуется просмотром базы данных в прямом порядке
(сверху вниз, слева—направо)2. При этом по существу проверяется каждый сегмент
АГЕНТЫ, начиная с самого левого, до тех пор, пока не будет найден сегмент, объем
сделок для которого превышает 1 000 000 дол. Если такой сегмент найден, он возвра-
щается прикладной программе в область ввода—вывода, которая доступна как интер-
претатору DL/I, так и прикладной программе.
Предположим теперь, что требуется найти агента Принстонской конторы, объем
сделок которого превышает 1 000 000 дол. Этот запрос можно записать так:
GET UNIQUE АГЕНТЫ
WHERE
ГОРОД = «ПРИНСТОН»,
СДЕЛКИ > 1000000
Если агентство имеет конторы и в Принстоне, штат Нью-Джерси, и в Принстоне,
штат Техас, запрос можно специфицировать следующим образом:
GET UNIQUE АГЕНТЫ
WHERE
НАЗВАНИЕ—РАЙОНА = «северо-восточный»
ГОРОД = «Принстон»
СДЕЛКИ > 1000000
имея в виду, что Нью-Джерси находится в Северо-восточном районе, а Техас — нет.
В аргументах поиска сегмента допускается также использование переменных,
хотя формально значение справа от знака «=» должно быть константой. Каким обра-
зом это делается, будет показано позднее при детальном рассмотрении обращений к
DL/1. В этой связи вполне корректна приведенная иа рис. 8.7 программа, написанная
с использованием упрощенного языка. Программа вводит район и город и находит
среди агентов конторы этого города агента, объем сделок которого превышает
1 000 000 дол.И
read РАЙОН, КОНТОРА
GET UNIQUE АГЕНТЫ
WHERE НАЗВАНИЕ—РАЙОНА= РАЙОН
ГОРОД = КОНТОРА
СДЕЛКИ > 1 000 000
Рис. 8.7. Использование переменных в аргументах поиска сегмента
Другой вариант команды GET имеет вид GET NEXT (ДАТЬ СЛЕДУЮ-
ЩИЙ). Он дает возможность просмотреть всю базу данных для поиска сег-
ментов, удовлетворяющих некоторым условиям. Использование слова NEXT
вместо UNIQUE позволяет осуществлять просмотр вправо от последнего
сегмента, к которому был произведен доступ (т. е. от текущего сегмента пред-
ставления), до тех пор, пока не встретится сегмент того же типа, удовлетво-
1 Технически команда GET UNIQUE, а не другие команды должна специфици-
ровать полную последовательность типов сегментов от корня до искомого типа сегмен-
та включительно, даже если с некоторыми из них не связаны какие-либо условия. В
этом примере имеем путь: РАЙОНЫ, КОНТОРЫ, АГЕНТЫ. В нашем упрощенном
языке мы будем опускать эту избыточную информацию.
2 Удобно предположить, что все сегменты РАЙОНЫ являются порожденными
фиктивного корневого сегмента (см. разд. 3.3).
248
ряющий специфицированным в команде GET NEXT условиям. Эти условия
могут отличаться от условий, установивших текущий сегмент представле-
ния, но на практике они обычно одни и те же.
Пример 8.4. Предположим, что требуется найти всех агентов, сделки кото-
рых превышают 1 000 000 дол. Для выполнения этой задачи можно использовать про-
грамму, приведенную на рис. 8.8. Из рисунка видно, что язык DL/1 встраивается во
включающий язык таким же образом, как язык манипулирования данными встраива-
ется в Кобол в предложениях DBTG. Читатель должен помнить, что здесь применяет-
ся упрощенный язык DL/1. На практике же операторы DL/1 обычно передаются как
совокупность аргументов вызова специальной процедуры, например PLITDL1, если
в качестве включающего языка выбран ПЛ/1.
GET UNIQUE АГЕНТЫ
WHERE СДЕЛКИ > 1000000
while —> FAIL do
print АГЕНТЫ.ИМЯ—АГЕНТА/* в действительности
печатается часть области ввода-вывода, где находится найденный сегмент АГЕНТЫ*/
GET NEXT АГЕНТЫ
WHERE СДЕЛКИ > 1000000
end
Рис. 8.8. Печать всех агентов с объемом сделок свыше миллиона
Должно быть также ясно, что в программе, представленной на рис. 8.8, перемен-
ная FAIL обозначает ту часть блока связи, которая используется для индикации успе-
ха или неудачи обращения к DL/1. Переменная FAIL принимает значение «истина»
всякий раз, когда не может быть найден сегмент, удовлетворяющий требуемым усло-
виям. В последнем примере команда GET UNIQUE будет вызывать присваивание пе-
ременной FAIL значения «истина», если нет агентов, имеющих объем сделок свыше
1 000 000 дол. С другой стороны, FAIL принимает значение «истина» при выполнении
команды GET NEXT непосредственно после того, как был найден самый правый агент
с объемом сделок, превышающим 1 000 000 дол.
Третий формат команды GET, имеющий вид GET NEXT WITHIN PAR-
ENT (ДАТЬ СЛЕДУЮЩИЙ ПОД ИСХОДНЫМ), позволяет просмотреть
в актуальной базе данных все порожденные сегменты для некоторого экзем-
пляра сегмента. Здесь используется неформальная концепция текущего ис-
ходного, означающая самый последний экземпляр сегмента, к которому осу-
ществлялся доступ с помощью какой-либо команды GET, отличной от ко-
манды GET NEXT WITHIN PARENT. Тип сегмента, полученный с помощью
последней команды, необязательно должен быть порожденным типом сег-
мента по отношению к текущему исходному. Он может быть его потомком.
Важным различием между GET NEXT и GET NEXT WITHIN PARENT
является то, что вторая команда завершается безуспешно, если просмотрены
все потомки текущего исходного сегмента. В то же время первая команда про-
должает осуществлять поиск вправо, пока не будет найден такой экземпляр
сегмента, что он и все его предки удовлетворяют заданным условиям.
Пример 8.5. На рис. 8.9 приведена программа, которая печатает всех кли-
ентов агента по имени Сэм Ловкач, работающего в Принстонской конторе (предполо-
жим, что эта информация однозначно идентифицирует агента). Если вместо этого тре-
буется напечатать всех клиентов Принстонской конторы (предполагая, что существу-
ет единственная контора, для которой ГОРОД=«Принстон»), можно просто изменить
оператор GET UNIQUE (рис. 8.9) следующим образом:
GET UNIQUE КОНТОРЫ
WHERE ГОРОД = «Принстон»
Заметим, что в этом случае «под исходным» в действительности означает «под ис-
ходным более высокого уровня», и все клиенты агентов Принстонской конторы будут
напечатаны.
249
GET UNIQUE АГЕНТЫ
WHERE ИМЯ-АГЕНТА == «Сэм Ловкач»
/* устанавливает текущий исходный*/
GET NEXT WITHIN PARENT КЛИЕНТЫ
/* дает первого клиента Сэма */
while — FAIL do
print КЛИЕНТЫ. ИМЯ-КЛИЕНТА/* из области ввода — вывода*/
GET NEXT WITHIN PARENT КЛИЕНТЫ
end
Рис. 8.9. Напечатать всех клиентов Сэма Ловкача
Включение сегментов
Команда INSERT (ВКЛЮЧИТЬ), запись которой будет осуществляться
с помощью того же упрощенного синтаксиса, что и для различных форматов
команды GET, позволяет включить сегмент типа S, предварительно создан-
ный в области ввода-вывода, в качестве порожденного по отношению к ука-
занному экземпляру сегмента, исходного для типа S. Команда INSERT си-
стемы IMS располагает также возможностями, подобными автоматическому
включению с использованием селекции набора в предложениях DBTG. Если
«текущий сегмент представления» является исходным типом для S или лю-
бым потомком исходного типа, то запись
INSERT S
сделает сегмент типа S из области ввода-вывода порожденным того экземпля-
ра сегмента исходного типа, который служит текущим сегментом представ
ления или его предком. В любом случае включаемому сегменту назначается
свое место среди порожденных его исходного, определенное значением поля
упорядочения. Напомним, что все порожденные экземпляра сегмента сорти-
руются по этому полю.
Пример 8.6. Предположим, что Джо Неудачник соглашается стать клиен-
том Сэма Ловкача. Мы можем ввести сегмент Джо Неудачника как порожденный сег-
мента Сэма Ловкача, выполнив программу, приведенную на рис. 8.10. Если сегмент
Сэма Ловкача уже является текущим сегментом представления либо даже если сег-
мент некоторого клиента Ловкача был бы текущим сегментом представления, можно
было бы включить сегмент для Джо Неудачника, помещая известные значения полей
этого сегмента в область ввода-вывода (рис. 8.10) и выполняя команду
INSERT КЛИЕНТЫ.И
КЛИЕНТЫ.ИМЯ-КЛИЕНТА: = «Джо Неудачник»
КЛИЕНТЫ.АДРЕС: = «Семейная дорога, 74»
/* Предполагается при этом, что область ввода-вывода для этой команды является
структурой с именем КЛИЕНТЫ и полями, соответствующими полям сегмента
КЛИЕНТЫ. Адрес области ввода-вывода передается при обращении к DL/1*/
INSERT КЛИЕНТЫ
WHERE
ГОРОД = «Принстон»
ИМЯ—АГЕНТА — «Сэм Ловкач»
Рис. 8.10. Неудачник становится клиентом Ловкача
Удаление и модификация сегментов
Чтобы удалить или модифицировать сегмент, необходимо сначала «удер-
жать» его с помощью одной из разновидностей команды GET, которая сде-
лает требуемый сегмент текущим представления. После GET в этой команде
нужно добавить слово HOLD (удержать). Необходимость удержания сег-
250
мента перед его удалением или модификацией мотивируется возможностью
параллельной обработки базы данных двумя или более прикладными про-
граммами. При выполнении команды GET HOLD (ДАТЬ и УДЕРЖАТЬ) ни
для какой другой программы не допускается доступ к данному сегменту.
Вопрос о необходимости «удержания» сегмента перед его модификацией об-
суждается в гл. 10. Здесь термин «удержать» соответствует «блокировке»
или «блокировке для записи», рассматриваемыми в гл. 10.
Для удаления сегмента после его нахождения и удержания достаточно
выполнить команду DL/1
DELETE (УДАЛИТЬ)
Эта команда удаляет сегмент, который является текущим представления, а
также все его порожденные из основной базы данных1. Заметим, что не все
удаленные сегменты обязательно являются чувствительными, т. е. некото-
рые удаленные сегменты не являются частью представления. Таким образом,
команда удаления может воздействовать на сегменты, о существовании кото-
рых программист ничего не знал.
Для модификации найденного и удерживаемого сегмента обновляем
сначала копию соответствующего сегмента, находящуюся в области ввода-
вывода. При этом не разрешается обновление поля упорядочения, так как
сегменты не перемещаются в базе данных при модификации, а порожден-
ные сегменты должны быть отсортированы по значениям их полей упорядо-
чения. Когда мы подаем команду
REPLACE (ЗАМЕНИТЬ)
вариант текущего сегмента в области ввода-вывода заменяет соответствую-
щий сегмент в базе данных. Заметим, что в обращении к DL/1, представлен-
ном в нашем случае упрощенным оператором REPLACE, область ввода-вы-
вода подразумевается.
Пример 8.7. Предположим, что агент Сэм Ловкач продает необитаемый тро-
пический остров за 100 тыс. дол. Можно добавить эту сумму к объему его сделок с по-
мощью программы, приведенной иа рис. 8.11.
GET HOLD UNIQUE АГЕНТЫ
WHERE
ГОРОД = «Принстон»
ИМЯ—АГЕНТА = «Сэм Ловкач»
АГЕНТЫ.СДЕЛКИ: = АГЕНТЫ. СДЕЛКИ + 100 000
/* эта операция выполняется в области ввода-вывода, которая, по предположению,
должна быть структурой записи с именем АГЕНТЫ*/
REPLACE
Рис. 8.11. Добавление 100 000 дол. к объему сделок Сэма Ловкача
Однако, к несчастью, тропический остров вскоре бесследно исчезает. Бесспорно,
Сэм Ловкач должен «прогореть», что и делается с помощью следующих команд:
GET HOLD UNIQUE АГЕНТЫ
WHERE
ГОРОД = «Принстон»
ИМЯ—АГЕНТА = «Сэм Ловкач»
DELETE
1 В том случае, когда представление строится на логической, а ие на физичес-
кой базе данных, влияние удаления иа физическую базу данных, лежащую в основе
логической базы данных, должно быть специфицировано вместе с последней. Тем не
менее порожденные удаляемого сегмента в логической базе данных обычно удаляются
из нее.
251
Заметим, что команда DELETE удаляет не только сегмент Сэма Ловкача, но и
сегменты всех его клиентов. Возможно, их нужно было сначала передать другому аген-
ту.
Некоторые детали обращений к DL/1
Напомним, что для описания команд DL/1 мы применяем упрощенный
вариант синтаксиса этого языка. Команды в действительности не встраива-
ются в программу, а выполняются благодаря Обращениям к конкретной про-
цедуре, имя которой зависит от используемого включающего языка. Пред-
положим, что в качестве включающего языка выбран ПЛ/1. Тогда имя ука-
занной процедуры — РЫТОЫ.Эта процедура имеет следующие параметры
в порядке их спецификации:
1. Число параметров в вызове процедуры, не считая данного.
2. Собственно команда. Этот параметр представляет собой строку литер,
длина которой равна 4. Кодами команд (дополненными при необходимости
пробелами) являются: GU (ДАТЬ УНИКАЛЬНЫЙ), GN (ДАТЬ СЛЕДУЮ-
ЩИЙ), GNP (ДАТЬ СЛЕДУЮЩИЙ ПОД ИСХОДНЫМ), GHU, GHN,
GHNP (то же самое, только с добавлением HOLD — УДЕРЖАТЬ), ISRT
(ВКЛЮЧИТЬ), DLET (УДАЛИТЬ) и REPL (ЗАМЕНИТЬ).
3. Имя блока связи программы для представления, к которому осуществ-
ляется доступ с помощью данной команды. Фактически блок связи не явля-
ется частью данных прикладной программы. Скорее, он является внешним по
отношению к ней. Система IMS при первой передаче управления прикладной
программе передает ей и указатель на блок связи программы. В программе
объявляется имя данных, идентифицируемых этим указателем. Поэтому к
ним можно обращаться, например, для того, чтобы проверить, удачно ли
завершилась команда GET при поиске некоторого сегмента.
4. Имя области ввода-вывода — строки литер, имеющие длину, доста-
точную для хранения сегмента того типа, который указан в команде.
5. Список аргументов поиска сегмента. Команда GET UNIQUE тре-
бует аргумента поиска сегмента для каждого типа сегмента вдоль пути от кор-
невого до целевого типа сегмента, но в других командах они факультативны.
Аргумент поиска сегмента представляет собой, по существу, строку ли-
тер вида
<имя сегмента> <код модификации команды> (<имя поля> = <зиачение>)
Здесь <код модификации командьО — факультативный. В том слу-
чае, когда он присутствует, он представляется знаком * с последующей бук-
вой. Коды модификации команд мы обсуждать не будем. Достаточно лишь от-
метить, что они модифицируют действие команды. Так, они помогают полу-
чить сегменты, которые представляют собой порожденные текущего исход-
ного, но не являются сегментами того же типа, что и текущий представления.
Они позволяют изменять тип сегмента текущего исходного, а также полу-
чать, включать или заменять весь путь от корневого сегмента до сегмента
некоторого типа, считающегося его потомком. Заключенное в круглые скобки
равенство <имя поля> — <значение> также является факультативным.
Напомним, что для команды GET UNIQUE путь до искомого типа сегмента
должен быть специфицирован с помощью аргументов поиска сегмента.
Поскольку компилятор ПЛ/1 не может знать во время компиляции при-
кладной программы типов данных параметров процедуры PL1TDL1 (так,
счетчик аргументов имеет тип FIXED BINARY (31); собственно команда —
CHAR (4)), необходимо объявить переменные требуемого типа, инициализи-
252
ровать их корректными значениями и передать процедуре PL1TDL1 в ка-
честве параметров их имена, а не сами значения. Такая организация облада-
ет существенными преимуществами. Если использовать переменную, напри-
мер SSA, в качестве аргумента поиска конкретного сегмента для определенно-
го вызова, то прежде чем осуществить вызов, можно модифицировать часть
значения SSA справа от знака «=» и получить все, что мы желаем.
Пример 8.8. На рис. 8.7 была приведена программа, которая вводит пере-
менные РАЙОН и КОНТОРА, а затем использует их в аргументе поиска сегмента.
Вспомнив эту программу, мы увидим, как прикладная программа в действительности
оперирует указанными переменными. Пусть имеются две переменные SSA1 и SSA2,
служащие аргументами поиска сегмента, с начальными значениями
SSA1 = 'РАЙОНЫ (НАЗВАНИЕ_РАЙОНА = ХХХХХХХХХХ)'
SSA2 = 'КОНТОРЫ (ГОРОД = YYYYYYYYYY)'
Прежде чем применить их в качестве первых двух аргументов поиска сегмента в
вызове
CALL PL1TDL1 (#6, GU, AGENCYPCB, IOAREA, SSA1, SSA2, SSA3)
можно заменить позиции X значением переменной РАЙОН, а позиции Y — значением
переменной КОНТОРА. В данном случае # 6 является переменной, объявленной как
FIXED BINARY (31) и имеющей начальное значение 6. Переменная GU объявлена
как CHAR (4). Ей присваивается начальное значение ’GU’. AGENCYPCB является
именем блока связи прикладной программы, IOAREA— переменной, длина которой
в литерах эквивалентна длине сегмента АГЕНТЫ. Что касается переменной SSA3, то
для этой команды ей присвоено значение аргумента поиска сегмента АГЕНТЫ, т. е.
АГЕНТЫ (СДЕЛКИ >1 000 000)
8.3. ЛОГИЧЕСКИЕ БАЗЫ ДАННЫХ
Вернемся к рассмотрению базы данных кооператива из примера 4.12.
Для простоты сосредоточим внимание на связях между членами кооператива,
товарами и заказами, забыв на время о поставщиках и их связях с товарами.
Один из возможных способов реализации этой части рассматриваемой базы
данных средствами IMS представлен на рис. 8.12. Каждый экземпляр сег-
Рис. 8.12. Часть (плохая реализация) базы данных кооператива
мента ТОВАРЫ имеет в качестве порожденных заказы на соответствующий
товар, включающие фамилию, адрес и баланс каждого члена кооператива, за-
казывающего этот товар. Хотя, по существу, наша схема содержит всю ин-
формацию об отношениях ЧЛЕНЫ и ЗАКАЗЫ из примера 4.12, возникают
большие затруднения из-за того, что эти отношения находятся не в третьей
нормальной форме. Так, адрес и баланс каждого члена кооператива повторя-
ются для каждого заказа. Кроме того, если когда-либо член кооператива
ничего не закажет, то связь между его адресом и балансом будет потеряна.
Одним из решений данной проблемы является создание двух физичес-
ких баз данных таким образом, как показано на рис. 8.13, Одна из них со-
держит только корневой тип сегмента, каждый экземпляр которого представ-
253
ляет члена кооператива. Другая база данных имеет в качестве корневого сег-
мента ТОВАРЫ, как и на рис. 8.12, а в качестве порожденного сегмента —
ЗАКАЗЫ с полем КОЛИЧЕСТВО. Вместо полной информации о членах
кооператива, делающих заказы, подставляются указатели на соответствую-
Рис. 8.13. Две физические базы данных
щие экземпляры сегмента ЧЛЕНЫ. Такой подход устраняет указанные вы-
ше трудности. Адрес и баланс каждого члена кооператива хранятся всегда
в точности один раз, независимо от того, сколько он делает заказов.
Логически исходные и порожденные
Использованный выше сегмент ЗАКАЗЫ представляет собой связь
вида «многие ко многим» между сегментами ЧЛЕНЫ и ТОВАРЫ.
Эти сегменты можно связать с помощью декларации сегмента ЧЛЕНЫ и
сегмента ТОВАРЫ как исходных по отношению к сегменту ЗАКАЗЫ. Если
определяются две физические базы данных (см. рис. 8.13), можно объявить
существование поля указателя в сегментах ЗАКАЗЫ. Каждый из таких ука-
зателей идентифицирует некоторый экземпляр сегмента ЧЛЕНЫ. Хотя на
первый взгляд могло бы показаться, что мы сделали фактически сегмент
ЧЛЕНЫ порожденным по отношению к сегменту ЗАКАЗЫ, в терминологии
IMS все обстоит наоборот. Сегмент ЧЛЕНЫ называется логически исходным
для сегмента ЗАКАЗЫ, а сегмент ЗАКАЗЫ является логически порожден-
ным по отношению к сегменту ЧЛЕНЫ. Введенные указатели направлены
от логически порожденного к логически исходному и называются указателя-
ми на логически исходные \ При декларации этих двух баз данных в опреде-
лении сегмента ЧЛЕНЫ используется макрокоманда LCHILD, отражаю-
щая тот факт, что указанный сегмент имеет логически порожденный сегмент
ЗАКАЗЫ. Далее, когда объявляется сегмент ЗАКАЗЫ, параметр PARENT
указывает два исходных. Синтаксис спецификации этого параметра имеет
вид:
PARENT = ((<физически исходный;?), (<логически исходный>, <база данных>))
Пара (Слогически исходный^?, Сбаза данных>)1 2 указывает имя логи-
чески исходного сегмента и физическую базу данных, которой он принадле-
жит.
Пример 8.9. На рис. 8.14 эскизно представлены (опущены некоторые макро-
команды и параметры) описания двух физических баз данных, показанных на рис. 8.13.
Заметим, что имеются различия между способами декларации логически исходных и
указателей. Макрокоманда LCHILD в сегменте ЧЛЕНЫ указывает, что сегмент ЗАКА-
ЗЫ — логически порожденный для сегмента ЧЛЕНЫ. В определении сегмента ЗА-
1 Чтобы это было легче запомнить, заметим, что логически порожденный может
«наследовать» поля данных его логически исходного. Это будет показано в дальнейшем
при конструировании логических баз данных.
2 На самом деле используются три компонента, но средний из них и его роль рас-
сматриваться здесь не будут.
254
КАЗН существование указателя на логически исходный декларируется с помощью
параметра POINTER. В то же время параметр PARENT указывает, что сегмент ЧЛЕ-
НЫ является логически исходным.
DBD NAME = БД—ЧЛЕНЫ
SEGM NAME = ЧЛЕНЫ
LCHILD NAME = (ЗАКАЗЫ, БД_ТОВАРЫ)
FIELD NAME = (ИМЯ-ЧЛЕНА, SEQ, U)
FIELD NAME = АДРЕС
FIELD NAME = БАЛАНС
DBD NAME = БД-ТОВАРЫ
SEGM NAME = ТОВАРЫ
FIELD NAME = (НАИМ-ТОВАРА, SEQ, U)
SEQM NAME = ЗАКАЗЫ, POINTER = LPARENT
PARENT = ((ТОВАРЫ), (ЧЛЕНЫ, БД_ЧЛЕНЫ))
FIELD NAME = (HOMEP-3AKA3A, SEQ, U)
FIELD NAME = КОЛИЧЕСТВО
Рис. 8.14. Определение баз данных, представленных на рис. 8.13
I
Определение логических баз данных
Читатель может заметить, что в обсуждаемом здесь описании DL/1 не
рассматриваются какие-либо способы следования по указателям, таким, как
указатель на логически исходный из сегмента ЗАКАЗЫ на сегмент ЧЛЕНЫ.
Поэтому возникает естественный вопрос: как используются такие указате-
ли? Мы можем сразу ответить на этот вопрос: они помогают конструировать
логические базы данных, где имеется возможность комбинирования в одном
сегменте логически или физически исходных и порожденных. Таким образом,
можно поддерживать подразумеваемую связь между двумя исходными с по-
мощью общего порожденного сегмента. Это позволяет нам писать прикладные
программы для работы с логической базой данных (в действительности с не-
которым представлением этой базы данных), как если бы не было никаких
указателей. При этом мы полностью полагаемся на реализацию, обеспечива-
ющую использование указателя всякий раз, когда данные, фактически су-
ществующие в сегменте ЧЛЕНЫ, будут запрашиваться из комбинирован-
ного сегмента в логической базе данных.
В определении логической базы данных не объявляются поля сегмента.
Они определяются из соответствующей физической базы данных. Для каж-
дого сегмента логической базы данных все же указывается источник (или
источники). Используемый для этого параметр
SOURCE = (<имя_сегмента>, <база данных>) (8.1)
объявляет, что данный сегмент логической базы данных в действительности
является сегментом<имя_сегмента> в базе данных<база данных > х. В том
случае, когда логический сегмент представляет собой комбинацию физичес-
кого сегмента и его логически или физически исходного, источником служит
пара, состоящая из обоих сегментов.
Если создается логический сегмент из физического сегмента S и его ло-
гически исходного Р, то этот логический сегмент, по-видимому, должен со-
держать не только поля сегментов S и Р, но и поля полного сцепленного
ключа Р. Поэтому поле упорядочения сегмента Р появляется фактически
дважды: с одной стороны, как часть сегмента Р, а с другой — как компо-
1 Третий (средний) параметр в SOURCE чаще всего опускается. Поэтому в (8.1)
следует специфицировать две запятые. Мы не будем обсуждать здесь этот вопрос.
255
нент полного сцепленного ключа. Эта информация может быть частично опу-
щена, но соответствующие механизмы здесь обсуждаться не будут. Термин
данные пересечения часто используется как обозначение для копии сегмен-
та S в логическом сегменте, поскольку обычно они содержат некоторую ин-
формацию о связи между объектами, представленными логически исходным
Р и физически исходным S. Таким образом, если обозначить на рис. 8.13
сегменты ЗАКАЗЫ и ЧЛЕНЫ соответственно через S и Р, то данными пере-
сечения, относящимися к конкретной паре ЧЛЕНЫ—ТОВАРЫ, являются
(НОМЕР-3 А КАЗА, КОЛИЧЕСТВО).
Аналогичным образом можно создать сегмент в логической базе данных,
содержащей порожденный сегмент С и его физически исходный, если декла-
рировать для С указатель на его физически исходный. Этот комбинированный
сегмент логической базы данных является порожденным логически исход-
ного для С.
Логическая база данных состоит из совокупности сегментов, организо-
ванных в виде иерархии, как и физическая база данных. Источники этих
сегментов могут относиться к нескольким физическим базам данных, и, как
уже упоминалось, один сегмент логической базы данных может формиро-
ваться из некоторого сегмента и его физически или логически исходных. Сег-
мент С логической базы данных может быть порожденным сегмента Р, если
существует некоторый указатель, позволяющий следовать от источника Р
к источнику С. Таким указателем может служить обычный указатель от фи-
зически исходного к физически порождённому, от логически порожденного к
логически исходному или от физически порожденного к физически исходно-
му при условии, что эти указатели объявляются в предложении SEGM.
Следовательно, связь исходный — порожденный в логической базе данных
может оказаться связью порожденный — исходный в одной из используе-
мых физических баз данных.
Напомним два дополнительных правила, касающихся конструирования
логических баз данных:
1. Корневой сегмент логической базы данных должен быть корневым
сегментом какой-либо физической базы данных.
2. Если связь исходный—порожденный в логической базе данных явля-
ется связью исходный—порожденный в физической базе данных, то такой фи-
зически исходный нельзя снова использовать в8’логической базе данных.
Пусть, например, Р — исходный для Сив логической, и в физической базах
данных. Тогда Р не может быть порожденным для С в логической базе дан-
ных, даже если имеется указатель на исходный в сегментах С.
Таким образом, две физические базы данных, представленные на
рис. 8.15, а, с указателем на логически исходный, обозначенный пунктирной
линией, могли бы порождать логические базы данных, показанные на рис.
8.15, б, в. На рис. 8.15, б сегмент С скомбинирован с его логически ис-
ходным сегментом G, тогда как на рис. 8.15, в тот же самый сегмент С ском-
бинирован с его физически исходным сегментом Д.
Рассмотрим теперь пример определения логической базы данных:
Пример 8.10. Если заданы две физические базы данных, показанные на
рис. 8.13, можно построить логическую базу данных (рис. 8.16, б), которая аналогична
представленной иа рис. 8.12. Эскизный вариант определения этой логической базы
данных приведен на рис. 8.16, а. Сегмент ЗАКАЗЫ—ЧЛЕНЫ является комбинацией
сегмента ЗАКАЗЫ физической базы данных БД_ТОВАРЫ н сегмента ЧЛЕНЫ из
базы данных БД-ЧЛЕНЫ. Следует напомнить, что в действительности сегменты
ЗАКАЗЫ—ЧЛЕНЫ не существуют. Если у системы IMS запрашивают выборку сег-
мента этого типа, она осуществляет поиск лежащих в основе экземпляров сегментов
ЗАКАЗЫ-ЧЛЕНЫ (ассемблированная версия описания логической базы данных,
приведенного на рис. 8-16, а, информирует систему, Каким образом их найти) И осу-
256
Рис. 8.15. Физические
базы данных и некото-
рые сконструированные
из них логические базы
данных
ществляет выборку требуемых шести полей. Первое из них — ФАМИЛИЯ — пред-
ставляет собой полный сцепленный ключ экземпляра сегмента ЧЛЕНЫ. Поскольку
сегмент ЧЛЕНЫ является корневым сегментом базы данных БД-ЧЛЕНЫ, полный
сцепленный ключ содержит только одно поле, но в общем случае он будет содержать
по одному полю (полю упорядочения) из каждого сегмента вдоль пути от корня до
логически исходного сегмента, используемого в данной комбинации.
DBD NAME = ЛОГ_ТОВАРЫ, ACCESS = LOGICAL
SEGM NAME = ТОВАРЫ, SOURCE = (НАИМ-ТОВАРА, БД-ТОВАРЫ)
SEGM NAME = ЗАКАЗЫ-ЧЛЕНЫ, PARENT = ТОВАРЫ,
SOURCE = ((ЗАКАЗЫ, БД-ТОВАРЫ), (ЧЛЕНЫ, БД_ЧЛЕНЫ))
а)
\ТОВАРЫ (НАИМ ТОВАРА)\
ЗЯКЯЗЫ_ЧЛЕНЫ (ФАМИЛИЯ, НОМЕР.ЗАКЯЗА, КОЛИЧЕСТВО,
_____________ФАМИЛИЯ, ЯДРЕ С, БАЛЛИС)_______________
-
Рис. 8.16. Определение логической базы данных:
а) эскизный вариант; б) схема
Следующие два поля— НОМЕР—ЗАКАЗА и КОЛИЧЕСТВО—принадлежат
сегменту ЗАКАЗЫ. Эти поля образуют данные пересечения. Остальные три поля —
ФАМИЛИЯ, АДРЕС и БАЛАНС—принадлежат сегменту ЧЛЕНЫ. Заметим, что
поле ФАМИЛИЯ появляется дважды. Но фактически никакой избыточности нет, так
как сегменты ЗАКАЗЫ—ЧЛЕНЫ существуют только тогда, когда осуществляется
их выборка. Дополнительные затраты времени и пространства, используемые для соз-
дания двух копий поля ФАМИЛИЯ, весьма незначительны.
Представление связей «многие ко многим»
Логические базы данных в системе IMS обладают довольно широкими
возможностями. Так, их можно использовать для представления связи
«многие ко многим» между двумя наборами объектов А и В. Общая идея по-
казана на рис. 8.17, где представлены две физические базы данных. Первая
9 Зак. 1315
257
из них содержит сегмент Л, поля которого являются атрибутами набора объ-
ектов А. Сегмент А имеет порожденный сегмент РТВ, состоящий только из
указателя на логически исходный — на сегмент В. В свою очередь сегмент В,
представляющий набор объектов В, имеет порожденный сегмент с указате-
лем на А. Например, если связь состоит из пар (а1( Ьх), (аъ д2), (а2, Ьг) и
(а3, dj), актуальное состояние физических баз данных может быть таким,
как показано на рис. 8.18.
Рис. 8.18. Актуальное состояние физической базы
данных
Рис. 8.17. Представление
отображения «многие ко
многим»
На основе этих физических баз данных можно сконструировать с помо-
щью только что описанных методов каждую из представленных на рис. 8.19
логических баз данных. Прикладная программа может оперировать представ-
лениями этих логических баз данных одним и тем же образом. При этом для
a) б)
Рис, 8.19. Две логические ба-
зы данных, поддерживаемые
физической базой данных
(рнс. 8.18)
поиска экземпляров сегмента В, ассоциированных с А, применяется схема,
приведенная на рис. 8.19, а. Аналогично схема на рис. 8.19,6 используется
для нахождения экземпляров сегмента А, ассоциированных с В. Заметим,
что иерархическая природа IMS не позволяет достаточно эффективно пред-
ставлять связи в обоих направлениях.
Представление наборов DBTG
Набор DBTG, представляющий отображение вида «многие к одному»,
является специальным случаем отображения «многие ко многим». В этой свя-
зи не окажется сюрпризом представление набора DBTG с записью-владель-
цем типа А и записью-членом типа В двумя логическими базами данных, при-
веденными на рис. 8.19. Поскольку для каждого сегмента В существует не бо-
258
лее одного сегмента-владельца типа А (в актуальном состоянии базы данных,
схема которой показана на рис. 8.19, а), каждый экземпляр В будет иметь
не более одного порожденного сегмента. Однако программе может все же
потребоваться не только база данных рис. 8.19, а, но и база данных рис.
8.19, б, так как первая не позволяет удобным образом находить владельца
экземпляра В.
Из изложенного должно быть ясно, что любая сеть может быть представ-
лена совокупностью логических баз данных IMS с небольшой потерей эффек-
тивности. Справедливо и обратное утверждение: так как иерархия является
специальным случаем сети, база данных IMS может быть преобразована без
большой потери эффективности в базу данных DBTG. Таким образом, сете-
вая и иерархическая модели эквивалентны в этом строгом смысле, по крайней
мере, если иерархически ориентированная система обладает возможностями
системы IMS.
8.4. ОРГАНИЗАЦИЯ ХРАНЕНИЯ ДАННЫХ
Как уже упоминалось выше, существует четыре способа организации
хранения для физических баз данных: HSAM, HISAM, HIDAM и HDAM.
Расшифруем эти акронимы с помощью следующего ключа:
AM (access method) — метод доступа
Н (hierarhical) — иерархический
I (indexed) — индексный
S (sequential) — последовательный
D (direct) — прямой (т. е. через указатели)
Например, HISAM обозначает «иерархический индексно-последователь-
ный метод доступа». Цель такого выбора способов организации хранения, так
же как и способов размещения или организации наборов в предложениях
DBTG, заключается в том, чтобы предоставить проектировщику базы дан-
ных гибкие средства, позволяющие ему добиться эффективного функциони-
рования системы при определенной комбинации манипулятивных операций
над базой данных. В частности, мы увидим, что возможно более быстрое ис-
полнение, если использовать больше пространства. В одних случаях соз-
даются благоприятные условия для последовательного поиска в базе дан-
ных, в других — для поиска «случайно» специфицированных сегментов.
Основная терминология
При каждом из этих четырех способов организации хранения предприни-
мается попытка хранить вместе экземпляр корневого сегмента и экземпляры
всех его сегментов-потомков. Такая совокупность сегментов называется
записью базы данных. Пространство памяти разбивается на блоки фикси-
рованной длины, которые в IMS называют «записями». Мы сохраним
здесь, однако, понятие «блоки» для обеспечения согласованности с термино-
логией гл. 2. Записи базы данных часто занимают несколько блоков, но ии
один сегмент не может размещаться более чем в одном блоке. Блоки груп-
пируются в одну или несколько областей памяти, называемых наборами дан-
ных. Значениями всех указателей, и указателей на логически исходные, и
указателей, используемых методами доступа, являются фактически смеще-
ния от начала набора данных.
9*
259
Организация HSAM
В случае организации хранения HSAM для записей базы данных уста-
навливается сортированный порядок, соответствующий значениям поля
упорядочения каждого корневого сегмента. При этом сегменты входят в за-
пись базы данных в порядке сверху вниз. Для выполнения команды GET не-
обходимо просмотреть всю базу данных с самого начала, либо перемещаясь
вправо от текущего сегмента при GET NEXT. Команды включения, удале-
ния и замены не допускаются.
Организация HSAM хорошо подходит для базы данных, хранимой на
магнитной ленте, которая читается последовательно. Можно сделать новую
копию базы данных и провести в ней все обновления, собранные за длитель-
ный период времени. Полезно также создавать копии базы данных, имеющие
организацию HSAM для целей восстановления, даже если оригинальная база
данных имеет какую-либо другую организацию, так как HSAM использует
минимально возможное пространство памяти.
Организация HISAM
При организации HISAM записи базы данных хранятся в цепочках бло-
ков, так как сегменты одной записи базы данных обычно не соразмерны с
одним блоком. Из соображений эффективности целесообразно выбирать раз-
мер блока достаточно малым так, чтобы записи базы данных обычно превы-
шали длину блока. В противном случае в конце блока окажется большое не-
используемое пространство.
Организация HISAM предполагает использование разреженного индек-
са по полю упорядочения корневого типа сегмента, подобного описанному в
разд. 2.3. Однако в отличие от индекса, описанного ранее, данный индекс со-
держит указатели не на каждый блок, а на каждую группу из k записей ба-
зы данных. Параметр k, подобно длине блока, выбирается в процессе опре-
деления структуры среды хранения физической базы данных, и можно, конеч-
но, выбрать k = 1.
Блоки, применяемые для хранения данных, группируются в две области —
первичную и область переполнения. Каждая запись базы данных начи-
нается в одном блоке первичной области (первичном блоке) и, если требуется,
занимает любое число дополнительных блоков из области переполнения.
Первоначально база данных создается из первичных Данных, представлен-
ных в прямом (сверху вниз) порядке. Для этой цели в IMS предусмотрена спе-
циальная обслуживающая программа. При появлении записи базы данных
ей выделяются следующий доступный в первичной области блок и необхо-
димое число блоков переполнения. Таким образом, первичные блоки запол-
няются в порядке значений полей упорядочения корневых сегментов, и соз-
дание индекса, содержащего указатель на каждый k-й первичный блок вместе
со значением поля упорядочения корневого сегмента для этого блока, не со-
ставляет трудностей.
Пример 8.11. Предположим, что имеется база данных с простой схемой, при-
веденной на рис. 8.20, а. База данных, соответствующая этой схеме, представлена на
рис. 8.20, б. На рис. 8.21 показано, как записи базы данных рис. 8.20, б могут быть раз-
мещены в первичных блоках и блоках переполнения при некоторых не оговорен-
ных предположениях об относительных размерах сегментов различных типов. По-
казан также индекс, построенный в предположении, что k = 1 и что значением поля
упорядочения сегмента сц является само Z. Если было бы выбрано k > 1, то указатели
индекса ссылались бы на первые блоки из групп по k первичных блоков, в то время как
значения ключей соответствовали бы последним корневым сегментам в этих группах.
260
Заметим, что первичные блоки находятся в последовательной памяти, и поэтому вся
группа легко доступна через ее первый блок. Кроме того, указатели, соединяющие бло-
ки одной записи базы данных, показаны в конце, а пространство для указателя на на-
чало остается пустым. Последние указатели будут далее кратко рассмотрены.
Рис. 8.20. Пример базы
данных и ее схемы:
а) схема; б) база данных
Включение и удаление сегментов
при использовании HISAM
Методы включения и удаления сегментоа несколько различаются в за-
висимости от того, какая из двух поддерживающих базисных организаций
хранения используется. Эти базисные организации называются ISAM/OSAM
и VSAM. Чтобы доставить удовольствие любителям акронимов, укажем, что
О (overflow) — это переполнение, а V (virtual! — виртуальный. В дальней-
шем для определенности мы будем предполагать ISAM/OSAM. Для включе-
ния сегмента, отличного от корневого, нужно цросто поместить его в надле-
жащую позицию (в соответствии с прямым порядком) записи базы данных.
Сегменты этой записи, следующие за включаемым, передвигаются вправо.
Они перемещаются при необходимости в следующий блок цепочки. Если
это требуется, можно также добавлять новые блоки в цепочку х.
Стратегия включения нового корневого сегмента аналогична стратегии,
предложенной в разд. 2.3 для закрепленных записей. Включаемым корне-
1 Читателя может заинтересовать, как сделать перемещение сегментов при вклю-
чении некорневого сегмента безопасным. Этот вопрос важен, поскольку созданная
база данных может иметь указатели, такие, как указатели на логически исходные,
рассмотренные в разд. 8.3. Ответ заключается в следующем. Если используется орга-
низация HISAM, указатели представлены полным сцепленным ключом, в то время
как в HIDAM и HDAM, которые будут обсуждаться позднее, для этих и некоторых
других целей применяются настоящие указатели. Поэтому в случае HIDAM и HDAM
никакие перемещения сегментов не допускаются.
261
вым сегментам выделяется блок в области переполнения, и из каждого блока
первичной области указатель в его заголовке начинает цепочку блоков пере-
полнения, используемых для включаемых корневых сегментов. Все включае-
мые. в цепочку корневые сегменты имеют значения полей упорядочения, пред-
шествующие значению поля упорядочения корневого сегмента в первичной
области \ Порядок включения в цепочку корневых сегментов соответствует
возрастающей последовательности значений их полей упорядочения. Хотя
на первый взгляд это может показаться странным, такая организация име-
ет смысл. Чтобы просмотреть корневые сегменты в порядке возрастания зна-
чений полей упорядочения, нужно обратиться к очередному первичному
блоку, просмотреть сначала его цепочку включенных корневых сегментов,
а затем осуществить просмотр данного первичного блока.
Индекс Первичная область
Вторичная область
10
* °ю
го
зо
• ctfs Ье b7
Рис. 8.22. База данных HISAM после нескольких включений н уда-
лений
Удаление любого сегмента осуществляется путем установки в нем «бита
удаления». Удаляемый сегмент остается при этом на своем месте. Избавиться
от него можно единственным образом: нужно сделать копию базы данных и
затем повторно инициализировать ее, используя для этого специальную об-
служивающую программу системы IMS.
Пример 8.12. Пусть в базу данных, приведенную на рис. 8.21, включается
сегмент bt как порожденный сегмента а80. Исходя из наших предположений относитель-
но размера сегмента необходимо переслать с, в блок, занятый cs, сдвигая в то же время
cs, св и <8 вправо. Если затем удаляется св, то в этом сегменте просто устанавливается
бит удаления. Никакие перемещения сегментов при этом не производятся.
Теперь представим, что добавляется корневой сегмент а12 с порожденными сег-
ментами Ьь и ct, а затем — корневой сегмент а18 с порожденными be, b7 и Ь8. При этом
используются три блока переполнения. Первый содержит сегменты (а12, be, с8), вто-
рой — сегменты (ще, be, Ь,), а последний — только Ь8. Блоки с сегментами а12 н а18 сое-
диняются в цепочку, начинающуюся в заголовке первичного блока, содержащего а20.
Блок, включающий сегмент Ь8, связан с концом блока, в котором содержится сегмент
а18. Все эти изменения показаны на рнс. 8.22.
Организация H1DAM
Формирование базы данных HIDAM нужно начинать с создания началь-
ной базы данных, сегменты которой хранятся в прямом порядке и которая
заполняет последовательность блоков точно так же, как и при организации
HSAM. Следует далее добавить для ускорения доступа два средства. Первое
средство — это плотный индекс (см. разд. 2.5), содержащий пары вида (щр),
1 В противоположность организации, описанной в разд. 2.3, где зиаченне первого
ключа в цепочке предшествует всем остальным.
262
где v — значение ноля упорядочения экземпляра корневого сегмента, ар —
указатель на этот сегмент. Такой индекс организуется подобно базе данных
HISAM, содержащей только экземпляры корневого сегмента. Этими экземп-
лярами являются упомянутые выше пары (и, р), причем первое поле служит
полем упорядочения индексных сегментов (а также корневых сегментов базы
данных HID AM).
Второе средство представляет собой совокупность указателей, связываю-
щих сегменты записи базы данных. Здесь допускаются два варианта:
1. Цепочки, связывающие сегменты в прямом порядке (называемые в тер-
минологии IMS иерархическими указателями). Каждый сегмент имеет указа-
тель на следующий сегмент в последовательности, соответствующей прямо-
му порядку экземпляров сегментов х.
Рис. 8.23. Иерархические
указатели (а) н указате-
ли вида порожденный/
подобный (б)
2. Указатели от самого левого порожденного к правому подобному (в тер-
минологии IMS — указатели вида порожденный/подобный). Каждый экземп-
ляр сегмента имеет указатель на самый левый (т. е. первый в последова-
тельности, соответствующей прямому порядку) экземпляр порожденного
сегмента, если он существует, а также указатель на следующий экземпляр
сегмента подтем же исходным при его наличии. Заметим, что правый подоб-
ный может быть сегментом другого типа. Кроме того, для любого экземп-
ляра сегмента существует только один указатель на самый левый порожден-
ный, независимо от числа различных типов сегментов, находящихся среди
его порожденных.
Пример 8.13. Вспомним рнс. 8.3, где приведен пример полной записи базы
данных агентства по продаже недвижимости. На рис. 8.23, а показана запись базы дан-
ных с иерархическими указателями, а на рис. 8.23, б— та же запись с указателями
вида порожденный/подобный. Указатели на самый левый порожденный изображены
сплошными линиями, а на правый подобный — пунктирными.
Существует факультативная возможность делать двунаправленными и
иерархические указатели, и указатели вида порожденный/подобный. Кроме
того, можно также факультативно связать экземпляры корневого сегмента
двунаправленными указателями в порядке возрастания значений их полей
упорядочения. Независимо от наличия этих указателей индекс позволяет
1 В такой последовательности сегменты размещаются в начальной базе данных.
Сегменты, включаемые позднее, могут быть разбросаны по различным блокам без
какого-либо определенного порядка.
263
эффективно просматривать корневые сегменты по возрастанию значений их
полей упорядочения. Наконец, имеется возможность факультативно ис-
пользовать иерархические указатели для одних сегментов и указатели вида
порожденный/подобный для других.
Рис. 8.24. База данных
HIDAM
Пример 8.14. Для того чтобы связать концепции HIDAM воедино, на рис. 8.24
представлена база данных рис. 8.21, организованная как база данных HIDAM с иерар-
хическими указателями. Мы не показали, однако, организацию HISAM базы данных
для индекса.
Включение и удаление сегментов в HIDAM
Пространство, занимаемое удаляемыми сегментами, делается доступным
для повторного использования. Иерархические указатели или указатели
вида порожденный/подобный обновляются с тем, чтобы отразить удаление
сегмента. Алгоритм манипулирования этими указателями мы оставляем чи-
тателю в качестве упражнения. Включаемые сегменты, в том числе и новые
корневые, размещаются как можно ближе к их предшественникам в смысле
прямого порядка сегментов х. Соответствующим образом обновляются и ука-
затели. В базу данных индекса включение осуществляется при включении
корневого сегмента.
Организация HDAM
Иерархически прямая организация, как и HIDAM, предусматривает
соединение сегментов записи базы данных иерархическими указателями ли-
бо указателями вида порожденный/подобный по выбору пользователя. Су-
щественное различие между HIDAM и HDAM заключается в том, что в
HDAM индекс, обеспечивающий доступ к корневым сегментам, заменяется
на хеш-функцию. Пространство памяти для базы данных HDAM подразделя-
ется на первичную и вторичную области. Для каждого возможного значения,
возвращаемого хеш-функцией, существует один первичный блок и столько
блоков переполнения, сколько затребовал проектировщик. Блоки перепол-
нения имеются в распоряжении для участков, соответствующих любому
хеш-значению.
Начальная загрузка сегментов в базу данных HDAM осуществляется
в любом порядке, в отличие от баз данных HSAM, HISAM или HIDAM, где
она должна выполняться в последовательности, соответствующей прямому
порядку. Корневые сегменты размещаются в первичном блоке, соответствую-
1 Это требование мотивируется предположением, что легче осуществить доступ
к блоку, если только что осуществлялся доступ к соседнему блоку. Например, соседние
блоки могут находиться на одном и том же цилиндре диска, и тем самым исключается
необходимость перемещения головок.
264
щем значению хеш-функции, в качестве аргумента которой используется
значение поля упорядочения сегмента. Если в данном блоке больше нет сво-
бодного пространства, HDAM выбирает другой первичный блок, располо-
женный физически как можно ближе к текущему. Эта стратегия минимизи-
рует общее время, необходимое для поиска заданного корневого сегмента.
Например, если невозможно разместить все корневые сегменты с данным
хеш-значением в одном блоке, то желательно, чтобы они находились на одном
цилиндре диска. Все корневые сегменты с одним и тем же хеш-значением
связываются в цепочку в порядке возрастания значений их полей упорядо-
чения. Поэтому если эти сегменты размещены физически близко, то вся це-
почка может быть просмотрена достаточно быстро. Однако корневые сегмен-
ты вообще не соединяются в порядке возрастания значений их полей упоря-
дочения. И на самом деле команда GET NEXT, примененная к корневым
сегментам базы данных HDAM, не обязательно будет возвращать сегменты
в надлежащем порядке.
Некорневые сегменты загружаются в тот же самый первичный блок, что
и их корневой сегмент, если в нем есть место, либо в физически ближайший
незаполненный первичный блок — в противном случае. Однако с помощью
параметра организации HDAM можно ограничить объем первичного про-
странства, отводимого для сегментов любой записи базы данных. При пре-
вышении этого лимита добавляемые сегменты размещаются в области пере-
полнения. Заметим, что иерархические указатели, а также указатели вида по-
рожденный/подобный, используемые при организации HDAM, предохраня-
ют сегменты от потери, куда бы они ни были помещены. Ограничение на ис-
пользование первичной области позволяет гарантировать, что, по крайней
мере, корневые сегменты будут иметь тенденцию размещаться в том блоке,
в котором они должны находиться в соответствии с хеш-функцией.
Включение и удаление сегментов в HDAM
Если сегменты удаляются, то их пространство может быть в дальнейшем
повторно использовано. Включения выполняются в основном во время на-
чальной загрузки базы данных. При этом везде, где возможно, использует-
ся пространство удаленных сегментов. Если вся первичная область запол-
нена, то корневые' сегменты могут быть включены в область переполнения.
Конечно, после каждого включения или удаления иерархические указатели
и указатели вида порожденный/подобный должны корректироваться.
Вторичные индексы
Можно дополнить базу данных, использующую организацию HISAM,
HIDAM или HDAM, одним или несколькими вторичными индексами, кото-
рые сами по себе являются базами данных с организацией HISAM. Не оста-
навливаясь подробно на этом вопросе, отметим лишь, что можно создать вто-
ричный индекс по любому списку, включающему не более пяти полей из од-
ного типа сегмента. Вторичный индекс может ассоциироваться со значения-
ми этих полей, или с экземплярами сегментов, имеющими эти значения в
указанных полях, или, наконец, с предками специфицированного типа сег-
ментов для каждого из этих экземпляров. Например, для схемы базы данных,
приведенной на рис. 8.2, можно создать вторичный индекс по полю ЦЕНА,
который будет ассоциировать с каждой ценой опись недвижимости, имеющей
данную цену. Можно также ассоциировать с ценой те конторы, которые име-
ют опись недвижимости, продаваемой по данной цене.
265
Сравнение способов организации
хранения данных в системе IMS
Прежде всего дадим сравнительную оценку иерархическим указателям
и указателям вида порожденный/подобный, используемым в HIDAM и
HDAM. Во-первых, иерархические указатели занимают меньше места, по-
скольку каждый сегмент требует точно одного указателя. В то же время для
указателей вида порожденный/подобный необходимо выделять пространство
не только для указателя на самый левый порожденный сегмент, но и для указа-
теля на правый подобный. Интересно отметить, что в любой момент времени
каждая конкретная запись базы данных содержит одно и то же число указа-
телей, не имеющих неопределенного значения, независимо от того, исполь-
зуются ли иерархические указатели либо указатели типа порожденный/
подобный. Однако в последнем случае около половины пространства для
указателей не будет использовано (соответствующие указатели имеют неоп-
а
г <_________—— Рис. 8.25. Дерево, пока-
Vf ~ * I зывающее преимущест-
I I I во указателей вида по-
111 рожденный/подобный
C^<S110
ределенное значение). Резервирования пространства в сегменте для двух ука-
зателей избежать, к сожалению, не удается, так как они могут по мере вклю-
чения и удаления сегментов то использоваться, то принимать неопределен-
ное значение.
Таким образом, может показаться, что иерархические указатели всегда
оказываются более предпочтительными. На самом деле это не так. Справед-
ливо, что в случае дерева с единственным корнем и его порожденными сег-
ментами иерархические указатели и указатели вида порожденный/ по-
добный являются, по существу, одними и теми же. Поэтому мы могли бы
предпочесть первые по соображениям экономии используемого пространства.
Однако при глубине дерева более чем два, каждый сегмент которого имеет
много порожденных, команда GET, специфицирующая путь к листу, нахо-
дящемуся в дереве далеко вправо, выполняется значительно быстрее, если
используются указатели вида порожденный/подобный.
Пример 8.16. На рис. 8.25 представлено дерево базы данных, в котором каж-
дый экземпляр сегмента имеет десять порожденных. Пусть специфицирован некоторый
путь в дереве заданием значений полей, которые идентифицируют а, Ь10 н с10.10. Тогда
с помощью указателей на правый подобный, показанных на рисунке, мы можем идти
от а к 6Х н &10, следуя через одни указатель на порожденный и девять указателей на по-
добные, а затем — от сюд к Сю-др. следуя через другой указатель на порожденный и де-
вять указателей на подобные. Таким образом, потребуется проследовать только через
20 указателей. Если же вместо этого использовать иерархические указатели, необхо-
димо было бы пройти Ci.i, ..., «т.н,, чтобы перейти от bt к Ь2 н т. д., т. е. проследовать
через ПО указателей, чтобы получить Сю.ад.
Сравним теперь собственно четыре метода доступа HSAM, HISAM,
HIDAM и HDAM. При сравнении могут быть использованы различные кри-
терии. Необходимо, чтобы проектировщик базы данных принял во внимание
при выборе того или иного метода наиболее важные факторы.
1. Использование пространства памяти. Метод доступа HSAM ис-
пользует минимально возможный объем памяти. Это, вероятно, единствен-
266
ное оправдание для применения HSAM — чрезвычайно ограниченного мето-
да. Он не допускает, в частности, включения или удаления сегментов в базе
данных. Следующим по компактности является HISAM, поскольку он тре-
бует памяти только для индекса, но не требует ее ни для каких указателей,
как HDAM и HIDAM. Из прямых методов доступа HIDAM требует прост-
ранства для базы данных индекса, a HDAM — нет. Метод доступа HISAM не
допускает повторного использования пространства памяти после удаления
сегментов (за исключением случая, когда используется метод VSAM) в отличие
от прямых методов. Поэтому объем пространства памяти, используемого ти-
пичной базой данных HISAM, возрастает гораздо быстрее, чем для HDAM
и HIDAM. Однако если такая база данных часто копируется и перезагружа-
ется или если удаления осуществляются редко, этот фактор может быть не
столь важным.
2. Скорость поиска. Поиск случайного сегмента в базе данных HSAM тре-
бует в среднем просмотра половины базы данных. Поэтому метод HSAM не-
практичен, если доступ к сегментам должен осуществляться в порядке, ко-
торый не очень близок к прямому. Так как записи базы данных для методов
HISAM и HIDAM хранятся целиком, эти методы могут быть несколько бо-
лее быстрыми, чем метод HDAM, когда производится поиск больших записей
в базе данных. Однако метод HDAM обеспечивает возможность поиска кор-
невого сегмента с помощью хеширования. Поэтому он более эффективен при
поиске корневых сегментов, чем индексные методы. Как было показано в
примере 8.15, для записей базы данных по крайней мере с тремя уровнями
прямые методы, использующие указатели вида порожденный/подобный, пре-
восходят HISAM (в скорости поиска), который требует выполнять поиск за-
писей в базе данных в прямом порядке.
3. Скорость включения сегментов. Включение сегментов в методе HISAM
связано со сдвигом других сегментов и поэтому выполняется медленнее, чем
в прямых методах. Кроме того, для HSAM включение вовсе невозможно.
4. Следование по указателям. В методах доступа HIDAM и HDAM ис-
пользуются реальные указатели. Следовательно, доступ к логической базе
данных может быть более эффективным, если и для соответствующей физи-
ческой базы данных будет использоваться один из прямых методов. В мето-
де HISAM указатели имитируются полным сцепленным ключом. Для следо-
вания по такому указателю требуется дополнительное время.
УПРАЖНЕНИЯ
8.1. Постройте описание базы данных IMS для бейсбольной базы данных, ис-
пользованной в качестве сквозного примера в гл. 3.
*8.2. В упражнении 4.6 была рассмотрена база данных любителей пива. Попытка
представить ее в виде иерархии — непростая задача. Для удобства получения сведений
о любителях пива, часто посещаемых нмн барах и любимых сортах пива необходимы
три логические базы данных, показанные на рис. 8.26. Дайте описания этих логических
баз данных и соответствующих нм физических баз данных.
*8.3. Предположим, что требуется написать программу, которая вводит имя лю-
бителя пива и определяет бары, где подают пиво, которое ему нравится, независимо
оттого, является ли он завсегдатаем этого бара. (Заметим, что сегменты ВАР на
рнс. 8.26, а не содержат эту информацию, так каконн представляют только часто по-
сещаемые бары.)
а) Выберите представления, необходимые для этой программы, и напишите их
определения (блоки связи программы) в терминах логических баз данных, проведен-
ных на рис. 8.26.
б) Напишите программу на упрощенном языке DL/1.
8.4. На рис. 8.27 показана база данных IMS (физическая нли логическая), пред-
ставляющая военно-морские силы (ВМС) различных стран. Дайте определение такого
представления этой базы данных, которое позволяет рассматривать только подводные
267
лодки, принадлежащие каждой стране, и которое разрешает только чтение сегментов
СТРАНЫ, но при этом позволяет выполнять любые операции над сегментами ПОД-
ЛОДКИ.
8.5. На рнс. 8.28 представлена запись базы данных. Покажите для этой записи:
а) иерархические указатели;
б) указатели вида порожденный/подобный.
ЛЮБИТЕЛЬ
ПИВЛ
БЛР ПИВО
а)
ЛЮБИТЕЛЬ БЛР
ПИВЛ
Ч)
пиво
Рнс. 8.26. Три логические базы данных
*8.6. Разработайте алгоритм обновления:
а) иерархических указателей;
б) указателей вида порожденный/подобный
мента.
при включении илн удалении сег-
СТРЛНЫ
Рис. 8.27. База данных ВМС
8.7. Предположим, что имеется база данных HISAM, каждый блок которой со-
держит 1000 байт данных. База данных состоит из трех типов сегментов (А, В и С) с
длиной соответственно 300, 200 и 400 байт. На рис. 8.29, а показаны записи начальной
Рнс. 8.28. Запись базы
данных
базы данных, где значениями поля упорядочения корневых сегментов А являются ин-
дексы i в символах at, представляющих экземпляры сегмента.
а) Покажите первоначальное распределение экземпляров сегментов в первичных
н вторичных блоках.
268
б) Предположим, что добавлены сегменты с9 как первый порожденный bt и с10
как первый порожденный bt. Покажите изменения в размещении экземпляров сегмен-
тов.
в) Предположим, что в базу данных добавляются записи, приведенные на
рис. 8.29, б. Покажите результирующее размещение экземпляров сегментов.
С; С? с3
is
Рис. 8.29. Создание базы дан-
ных HISAM:
а) записи начальной базы данных;
б) записи, добавляемые в базу
данных
с6 c7 c8
C13 с14 Cl5
Библиографические замечания
В настоящее время доступно несколько версий системы IMS. Эта глава базирова-
лась на IMS/VS версии I, описанной во множестве руководств, подготовленных ИБМ
[93]. Более детально IMS рассматривается в книге Дейта [51].
System 2000, разработанная MRI [122], является другой важной иерархичес-
кой системой. Описания этой системы можно также найти в книгах Цикритзиса н Ло-
ховского [70], а также Карденаса [30].
ГЛАВА 9
ЗАЩИТА БАЗЫ ДАННЫХ
В любой функционально полной СУБД имеются средства, позволяющие
предотвратить запоминание некорректных данных в базе данных, а также
доступ к данным лиц, не имеющих на это права. Существуют два источника
некорректных данных: случайности, такие, как ошибки ввода или програм-
мирования, и преднамеренное использование базы данных. Можно разде-
лить проблему защиты данных в базе данных на две подпроблемы:
1. Сохранение целостности данных. Этот аспект проблемы касается не-
преднамеренных ошибок и их предотвращения. Так, естественно ожидать,
что СУБД обеспечивает возможности декларации ограничений, требующих,
например, чтобы значение поля ВОЗРАСТ было менее 150. СУБД может
также помочь выявить некоторые ошибки программирования, например, в
процедуре, которая пытается включить запись с тем же значением ключевого
поля, что и у записи, уже существующей в базе данных (в предположении,
что мы можем сообщить системе о недопустимости такого включения). В этом
случае программу следует переписать так, чтобы сначала можно было бы
проверить, существует ли уже такая запись в базе данных.
2. Секретность (или управление доступом). Здесь мы имеем дело главным
образом с тем, что для определенных пользователей право доступа и(или)
модификации ограничивается лишь некоторым подмножеством базы данных.
Может показаться, что любая попытка со стороны пользователей получить
доступ к недозволенной для них части базы данных является предумышлен-
ной, но в действительности с таким же успехом аналогичные действия может
вызвать ошибка программирования.
В настоящей главе рассматриваются аспекты СУБД, связанные как с
целостностью, так и с секретностью данных. Значительное внимание уделя-
ется некоторым сложным проблемам секретности для статистических баз
данных, например базы данных переписи населения. Проблема при этом
заключается не в ограничении доступа пользователей к какой-либо части
базы данных, а скорее в предотвращении возможности вывода детализиро-
ванных данных, таких, как доход конкретного человека, из статистической
информации, например из средней зарплаты нескольких больших групп
людей.
9.1. ЦЕЛОСТНОСТЬ ДАННЫХ
Имеются два существенно различных вида ограничений, которые жела-
тельно поддерживать механизмами СУБД. Как мы уже знаем из гл. 5, к пер-
вому виду относятся структурные ограничения, имеющие только форму ра-
венства значений в базе данных. Несомненно, наиболее распространенными
примерами таких ограничений являются так называемые функциональные
270
зависимости. Многие (но не все) функциональные зависимости могут быть
выражены, если СУБД позволяет пользователю объявить, что некоторое мно-
жество полей или атрибутов образует ключ типа записи или отношения. Ясно,
что необходимость выражать функциональные зависимости не ограничивате-
ся только реляционными системами. (Вместе с тем не все реляционные сис-
темы обладают такими возможностями). Например, в гл. 8 отмечалось, что
система IMS позволяет объявить, что поле упорядочения некоторого сегмен-
та Должно быть «уникальным» х. Таким образом, поле упорядочения кор-
невого сегмента может выполнять функцию ключа для этого типа сегмента,
хотя для некорневых типов сегментов поле упорядочения будет уникальным
только среди порожденных одного сегмента исходного типа. Заметим, одна-
ко, что если поля упорядочения всех типов сегментов объявлены уникаль-
ными, то полный сцепленный ключ служит «ключом» для сегментов любого
типа, хотя в действительности некоторые поля полного сцепленного ключа
могут и не принадлежать этому сегменту.
Второй вид ограничений целостности касается реальных значений, хра-
нимых в базе данных. Обычно такие ограничения требуют, чтобы значение
поля принадлежало некоторому диапазону, или выражают некоторое ариф-
метическое соотношение между различными полями. Можно, например,
предполагать для кредитного объединения, что сумма значений поля
БАЛАНС, взятая по всем членам этого объединения, эквивалентна его чисто-
му активу. В качестве другого примера можно рассмотреть запись, содержа-
щую информацию об учебном курсе. Если поля этой записи Е%, Н% и L%
указывают процент оценок за экзамены, домашние задания и лабораторные
работы, то для каждого экземпляра записи сумма значений этих полей долж-
на быть равна 100.
Языки запросов как языки для декларации
ограничений целостности
Принципиальная идея относительно ограничений целостности заключа-
ется в том, что можно использовать язык манипулирования данными как
средство выражения этих ограничений. Декларация ограничений целостно-
сти содержит две части. В первой из них должно быть выражено само ограни-
чение. Для этой цели язык манипулирования данными обычно вполне при-
годен. Во второй части описывается, когда данное ограничение должно про-
веряться. Обычно стремятся реализовать ограничения целостности как
«прерывания» высокого уровня, подобные ON-условиям в языке ПЛ/1. На-
пример, предложения DBTG допускают в декларации наборов DBTG и ти-
пов записей произвольное число предложений ON вида
ON <список команд> CALL <процедура>
Для набора DBTG Ссписок команд> может включать любую из команд
INSERT, REMOVE и FIND. Процедура представляет собой произвольную
программу, написанную в языке манипулирования данными, который явля-
ется расширением Кобола и поэтому обладает не только полными вычисли-
1 Т. е. оно не должно иметь дубликатов значений. — Примеч. ред.
271
тельными возможностями, но и возможностями доступа к любой части базы
данных х. Например, если для набора DBTG 5 декларируется
ON INSERT CALL Pl,
то процедура Pl может проверять, представлены ли уже определенные поля
текущей записи процесса, т. е. включаемой записи, в селектированном эк-
земпляре набора. Таким образом, обеспечивается поддержка функциональ-
ных зависимостей этих полей от полей тина записи-владельца набора 5.
В декларации типа записи Ссписок команд> предложение ON может
включать любую из трех перечисленных выше команд, а также четырех ос-
тавшихся: STORE, DELETE, MODIFY и GET. Процедура, специфициро-
ванная в предложении ON, запускается всякий раз, когда исполняется ко-
манда, указанная в списке, и текущая процесса является записью данного
типа.
9.2. ОГРАНИЧЕНИЯ ЦЕЛОСТНОСТИ ДАННЫХ В ЯЗЫКЕ
QUERY-BY-EXAMPLE
Чтобы продемонстрировать, каким образом идеи, изложенные в предше-
ствующем разделе, могут быть реализованы на практике, подробно рассмот-
рим проблему целостности данных в системе Query-by-Example (QBE).
Во-первых, если вернуться к разд. 4.7, можно заметить, что при декларации
отношения разрешается специфицировать для каждого поля, ключевое оно
или неключевое. При этом система поддерживает функциональную зависи-
мость всякого неключевого поля от множества совместно взятых ключевых
полей. Такая проверка целостности осуществляется при каждом включении
или модификации кортежа отношения. Операции, которые могут нарушить
зависимость, не выполняются, и печатается предупреждение. Позднее мы
обсудим, каким образом обеспечивается поддержка ограничений, представ-
ляющих собой функциональные зависимости иного вида, чем ключ -> не
ключ.
В системе QBE для каждого отношения поддерживается таблица огра-
ничений. Чтобы установить какое-либо ограничение для отношения R,
нужно вызвать форму таблицы R и записать в нее одну или несколько строк,
представляющих это ограничение.‘Ниже имени отношения в форму заносит-
ся конструкция вида1 2
I. CONSTR (ссписок условий>). I.
Как всегда, первое I. относится к самому содержимому данной графы,
а второе I. — к ограничению в остальной части строки. ССписок условий>
может содержать какой-либо или все символы операторов I. (Insert — вклю-
чить), D. (Delete — удалить), U. (Update — обновить), а также идентифи-
каторы, представляющие определяемые пользователем условия, которые бу-
дут описаны впоследствии. Термы, входящие в Ссписок условий>, указы-
вают, когда должно проверяться данное ограничение целостности. Напри-
1 Строго говоря, спецификации языка определения 'данных КОДАСИЛ пред-
усматривают, что язык программирования, используемый для написания таких про-
цедур, называемых процедурами базы данных, а также предъявляемые к ним требова-
ния определяются разработчиком конкретной СУБД типа КОДАСИЛ. — Примеч.
ред.
2 Здесь CONSTR—сокращение слова constraint (ограничение).— Примеч.
ред.
272
мер, если специфицировано CONSTR (I., U.)., то это означает, что проверка
ограничения должна выполняться при каждой операции включения или мо-
дификации кортежей соответствующего отношения. Для случая CONSTR
(I., U., D.). в QBE предусматривается краткая запись — CONSTR..
Содержимое последующей части строки представляет элементы для неко-
торых или всех атрибутов. Элемент может быть константой. Это означает,
что во включаемом, удаляемом или модифицируемом кортеже значение дан-
ного атрибута должно быть равно данной константе. Элемент может иметь
вид 9с, где с является константой, а 6 — арифметическим сравнением.
В этом случае данный атрибут кортежа должен находиться в отношении 0 с с.
Если элемент представляет собой пробел или имя переменной, начинающееся
знаком подчеркивания, то кортеж может иметь произвольное значение для
такого атрибута. Кроме того, могут быть помещены дополнительные строки
в форму отношения R или другие формы. В эти строки помещают дополни-
тельные ограничения на значения, которые могут появиться в кортеже при
включении, удалении или модификации в соответствии с семантикой языка
QBE.
Пример 9.1. Вернемся еще раз к базе данных кооператива из примера 4.12.
Для наложения ограничения на атрибут «баланс», которое утверждает, что задолжен-
ность не должна превышать 100 дол., мы можем вызвать форму отношения ЧЛЕНЫ
и поместить в нее следующую строку:
ЧЛЕНЫ ФАМИЛИЯ АДРЕС БАЛАНС
I. CONSTR (I., U.). I. > = — 100
Чтобы запретить появление заказа на товар, для которого не существует постав-
щика, можно вызвать формы отношений ЗАКАЗЫ и ПОСТАВЩИКИ и поместить
в них информацию, показанную на рис. 9.1. Это ограничение указывает, что для вклю-
чаемого кортежа отношения ЗАКАЗЫ, определяющего значение переменной „бутер-
брод, равное значению атрибута ТОВАР, в отношении ПОСТАВЩИКИ должен сущест-
вовать некоторый кортеж с тем же самым значением атрибута ТОВАР.
ЗАКАЗЫ ФАМИЛИЯ ТОВАР .КОЛИЧЕСТВО
I. CONSTR (I.). I. „бутерброд
ПОСТАВЩИКИ НАЗВ_ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
„бутерброд
Рис. 9.1. Ограничение, запрещающее появление заказа на непоставляемый
товар
Определенные Триггеры для проверки целостности
В языке QBE существует возможность определения некоторого условия,
такого, что если оно удовлетворяется включаемым или модифицируемым
кортежем, требуется выполнить связанную с этим условием проверку (или
273
проверки) целостности для данного кортежа. Как уже упоминалось выше,
список условий в фразе CONSTR (Ссписок условий>). может включать
произвольные строки литер, а также I., D., и U.. Эти строки литер, называе-
мые определенными триггерами, являются именами условий, представлен-
ных в виде строк в языке QBE.
Пример 9.2. Предположим, что задолженность Брукса не может достигать
более чем 100 дол. Требуется определить в QBE соответствующее ограничение. Мы
можем записать его следующим образом:
ЧЛЕНЫ ФАМИЛИЯ АДРЕС БАЛАНС
BL 1. CONSTR (BL). I. Брукс > — 100
Первая строка указывает, что существует определенный триггер с именем BL,
который «запускается» каждый раз, когда выполняется модификация или включение
кортежа для Брукса. Во второй строке записано, что если включается или модифици-
руется кортеж для Брукса отношения ЧЛЕНЫ, то выполняется проверка, не мень-
ше ли его новый баланс, чем — 99.99 дол. Кортежи для других членов кооператива
не затрагиваются этим ограничением.
Ограничения вида «старый — новый»
Иногда требуется ограничить обновления таким образом, чтобы для оп-
ределенных атрибутов имело место некоторое соотношение между их ста-
рыми и новыми значениями. Для этого включим в спецификацию ограниче-
ний строку, представляющую старый кортеж, а также ограничения иа
сам кортеж. В большинстве случаев язык QBE позволяет выразить соотно-
шения между старыми и новыми кортежами с помощью самих кортежей.
Если, однако, это не удается, можно воспользоваться блоком условий.
Пример 9.3. Для того чтобы установить ограничение, запрещающее подни-
мать цену на карамель, запишем в форму отношения:
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
I. CONSTR (U.). I. I. „поставщик —поставщик карамель карамель А 1 И •° 1 *тэ
Строка с ключевым словом CONSTR представляет новое значение, а следующая
строка — старое. Присутствие I. в последней строке отличает ограничения вида
«старый—новый» от ограничений общего вида, для выражения которых требуется бо-
лее чем одна строка, как и во второй части примера 9.1. Наличие переменной „постав-
щик в обеих строках необходимо. В противном случае будет только проверяться, пре-
вышает ли новая цена для поставщика, участвующего в изменении, цену на карамель,
установленную хотя бы одним ее поставщиком.
Выбор времени для проверки ограничений
Система QBE позволяет вводить все записанные на экране команды еди-
новременно, и эта совокупность команд может предусматривать несколько
включений, удалений или обновлений кортежей. Важно отметить, что огра-
ничения целостности проверяются не при выполнении каждой команды та-
кой совокупности, а только после того, как будут выполнены все команды.
274
Это предоставляет определенную свободу в порядке спецификации команд,
которые вводятся вместе.
Так, в примере 9.1 в результате введения ограничения на базу данных
кооператива в нее нельзя было поместить заказ на товар, который никто не
поставляет. Если с дисплея как единая транзакция вводится несколько за-
казов на овсяные хлопья, а также сведения о том, что в настоящее время
корпорация вкусных продуктов торгует овсяными хлопьями, то мы не на-
рушаем этого ограничения. Однако если бы система ввела заказы и провери-
ла ограничения целостности до поступления новой информации о поставщи-
ках, имело бы место нарушение ограничения целостности.
Таблица ограничений
Все объявленные ограничения целостности доступны пользователю.
Можно напечатать ограничения, связанные с отношением R, если поместить
Р. CONSTR Р.
под именем отношения в форме отношения R. Можно также напечатать толь-
ко ограничения заданного типа. Например, в случае
Р. CONSTR (I.). Р.
печатаются лишь ограничения, связанные с командой включения кортежей.
Мы можем удалить ограничение, наложенное на отношение R, если запи-
сать под именем R в форме этого отношения
D. CONSTR (Ссписок условий>).,
помещая вслед за этим описание ограничения в столбцах для атрибутов. За-
метим, что в конце такого элемента не требуется снова указывать D., в от-
личие от второго I. или Р., которые необходимы при включении или печати
ограничений.
9.3. СЕКРЕТНОСТЬ
Проблематика секретности базы данных, защиты ее от несанкциониро-
ванного использования имеет много различных аспектов и подходов. Преж-
де всего необходима защита как от нежелательной модификации или раз-
рушения данных, так и от несанкционированного их чтения. Многие из про-
блем, связанных с секретностью, не являются специфическими для систем
баз данных. С ними может встретиться, например, и разработчик операци-
онной системы. Поэтому рассмотрим сначала вкратце некоторые механизмы,
общие для обеспечения секретности систем баз данных и более общих систем,
а затем вернемся к специфическим проблемам и механизмам, имеющим отно-
шение к существующим системам баз данных.
1. Идентификация пользователя. Вообще говоря, различным пользова-
телям предоставляются не одинаковые права по отношению к различным ба-
зам данных или частям базы данных, таким, как отношения или атрибуты.
Эти права могут включать чтение части базы данных, а также включение, уда-
ление или модификацию данных. Наиболее часто для идентификации поль-
зователя применяется пароль, известный только системе и конкретному ли-
цу. По-видимому, система должна защищать пароли, по меньшей мере, так
275
же, как и данные, хотя с реалистической точки зрения гарантии или доказа-
тельств секретности не существует.
2. Физическая защита. Полностью надежный метод защиты должен при-
нимать во внимание возможность физических «атак» на базу данных — от
насильственного раскрытия пароля до кражи физических запоминающих
устройств. В последнем случае можно довольно хорошо защититься с помо-
щью кодирования данных. Система с высокой степенью секретности данных
нуждается в лучшем механизме идентификации, чем пароль. Можно ввести,
например, индивидуальное опознание пользователя охраной. Читателя не
должно удивить то, что мы не обсуждаем этот вопрос в нашей книге.
3. Поддержка и передача прав. Система должна поддерживать перечень
прав, предоставленных любому пользователю для каждой защищенной час-
ти базы данных. Одним из таких прав может быть право передачи своих
прав другому лицу. Например, как уже упоминалось в разд. 7.4, предложе-
ния DBTG предусматривают защиту наборов DBTG, областей и типов запи-
сей. Механизмом защиты может служить пароль для каждого защищаемого
объекта. При этом не предусматривается какой-либо таблицы прав пользо-
вателей для защищаемых объектов, и передача прав может осуществляться
вне системы, например путем сообщения паролей пользователям. Рассмот-
ренная в разд. 4.5 СУБД System R, а также система Query-by-Example,
которую мы будем обсуждать в разд. 9.4, поддерживают таблицу прав и до-
пускают передачу их другим лицам.
Вернемся теперь к рассмотрению двух механизмов защиты, специально
разработанных для использования в системах баз данных.
Представления как механизмы защиты
Представления, помимо того, что они существенно облегчают написание
прикладных программ благодаря возможности некоторого переопределения
концептуальной базы данных и поддерживают логическую независимость
данных, служат во многих случаях и удобным средством защиты. Существу-
ют два различных вида представлений. Первый из них мы уже изучали в свя-
зи с языками ISBL и Query-by-Example (разд. 4.4 й 4.7). Представления
этого вида не допускают модификации. Назовем их представлениями толь-
ко для чтения. Известно много ситуаций, когда владелец базы данных (или
какого-либо защищаемого объекта) желает предоставить всем пользовате-
лям право читать его данные, но сохранить за собой или за ограниченным
кругом своих коллег привилегию модификации базы данных. Представле-
ние только для чтения идеально подходит для этой цели.
Например, в языках ISBL или QBE можно определить представление,
эквивалентное текущему значению данного отношения и разрешить к нему
открытый доступ (только в режиме чтения). Имеется также возможность соз-
дания представления, содержащего лишь часть информации из одного или
нескольких отношений. Таким образом, определенные атрибуты или корте-
жи «экранируются» от открытого доступа.
Для представлений другого вида разрешается не только чтение, но и
запись объектов, которые являются частью представления. При этом модифи-
кации в представлении отражаются в концептуальной базе данных. Такие
представления допускаются, например, в предложениях DBTG, а также в
System R и IMS. Очевидно, что это — значительно более гибкое средство в
отношении разработки прикладных программ по сравнению с представлени-
ями только для чтения. В системе IMS по меньшей мере параметр PROCOPT,
ассоциированный с каждым сегментом представления, может разрешать
276
или запрещать операции включения, удаления или модификации. Поэтому
возможности представлений системы IMS обеспечивают в некотором смысле
более общую защиту, чем представления только для чтения х.
Использование языков запросов
для определения прав пользователей
Вторая важная идея, касающаяся секретности в системах баз данных, за-
ключается в том, что язык манипулирования данными может быть использо-
ван для определения привилегий, которыми обладает каждый пользователь
при доступе к базе данных, почти таким же образом, как и для определения
ограничений целостности. Каждая из четырех реляционных систем, описан-
ных в гл. 4, следует этому общему подходу. В разд. 9.4 мы подробно обсу-
дим механизмы секретности Query-by-Example. В качестве «замка секретно-
сти» для защищаемого объекта в предложениях DBTG допускается произ-
вольная процедура. Поэтому здесь также можно выполнять любые провер-
ки, выраженные в языке манипулирования данными DBTG, для того, чтобы
допустить либо отвергнуть запрос к защищенному объекту 1 2.
9.4. СЕКРЕТНОСТЬ В СИСТЕМЕ QUERY-BY-EXAMPLE
Система QBE признает права на включение (I.), удаление (D.), обновле-
ние (U.), и чтение (печать—Р.). Чтобы наделить некоторое лицо (группу лиц)
правом (правами) на отношение R, владелец этого отношения записывает
специальный кортеж в форму R. Под именем отношения R он помещает3:
I
I.AUTR (<список>). <имя> I.
Здесь<список> содержит одно или несколько прав I., D., U. и Р., а
<имя> является либо именем человека, которому предоставляются права,
либо переменной, представляющей произвольное лицо. Если (<список>)
опущен, то это означает предоставление всех четырех прав. В том случае,
когда мы желаем предоставить некоторое множество прав всем пользовате-
лям, можно опустить также <Симя>.
Чтобы завершить строку с ключевым словом AUTR., в некоторые (или
во все) столбцы для атрибутов записываем переменные либо константы. Пере-
менная указывает, что специфицированное право применяется к данному
столбцу. Константа означает, что специфицированное право предоставляет-
ся только для кортежей, содержащих в данном столбце значение, равное
указанной константе. Наконец, пробел означает, что доступ к столбцу запре-
щен. Заметим, что последнее отличается от обычных правил QBE, в которых
пробел является синонимом переменной, упоминаемой только один раз. Для
выделения множества кортежей.отношения R, к которым применяется дан-
ное право, можно использовать все возможности языка QBE. Например, с
помощью блоков условий можно налагать ограничения на значения пере-
1 В системе IMS существует проблема, заключающаяся в том, что при удалении
сегмента, когда оно допускается, удаляются также все его потомки. Это имеет место
"Ь в случае, если они не являются частью представления, и, таким образом, пежслатель-
но даже их чтение.
2 Автор допускает неточность. Подход DBTG предусматривает декларации, ир.и,
доступа пользователей к различным объектам данных в языке определен и , /юипы
а не в языке манипулирования данными. — Примеч. ред.
з Здесь ключевое слово AUTR — сокращение от AUTHORIZATION (раз[>• шеии<.
предоставление права). — Примеч. ред.
менных. Для этой же цели можно вводить дополнительные строки, ограничи-
вающие значения переменных.
Пример 9.4. Обратимся вновь к базе данных кооператива. Чтобы предоста-
вить пользователю Бруксу право чтения отношения ЗАКАЗЫ, следует записать:
ЗАКАЗЫ ФАМИЛИЯ ТОВАР КОЛИЧЕСТВО
I. AUTR (Р.). Брукс I. _п —1 —q
Для предоставления Бруксу всех четырех прав доступа запишем: к отношению ЗАКАЗЫ
ЗАКАЗЫ ФАМИЛИЯ ТОВАР КОЛИЧЕСТВО
I. AUTR. Брукс I. __ и -1 -q
Предоставим любому пользователю право чтения фамилий и балансов (но не адре-
сов) из отношения ЧЛЕНЫ, обеспечивая при этом неотрицательность баланса. С этой
целью укажем:
ЧЛЕНЫ ФАМИЛИЯ АДРЕС БАЛАНС
I. AUTR (Р.). _Ларк1. _п >0
И наконец, чтобы разрешить кому-либо доступ для чтения заказов на товары, по-
ставляемые компанией «Солнечная продукция», можно написать команды, приведен-
ные на рис. 9.2.
ЗАКАЗЫ ФАМИЛИЯ товар КОЛИЧЕСТВО
I. AUTR (Р.). -Ларк I. _п —1 -q
ПОСТАВЩИКИ НАЗВ-ПОСТ АДРЕС-ПОСТ ТОВАР ЦЕНА
Солнечная продукция _i
Рис. 9.2. Каждый может прочитать заказы на товары, поставляемые компанией
«Солнечная продукция»
Ограничения на имя получателя прав
До сих пор мы рассматривали два вида предоставления прав: любому
или какому-либо определенному лицу. Можно использовать язык QBE для
идентификации подмножества множества пользователей. Более того, мы мо-
жем предусмотреть, чтобы множества доступных кортежей для разных поль-
зователей были различными. Для этого нужно взять переменную в качестве
278
параметра<имя> в записи AUTR. и применить тоже самое имя в кортеже
или кортежах, описывающих права, предоставляемые каждому индивиду-
альному пользователю. Система дает возможность связать имя пользовате-
ля с представлением его имени, когда оно появляется в базе данных.
Пример 9.5. Можно предоставить каждому члену кооператива право чтения
только его собственного баланса:
ЧЛЕНЫ ФАМИЛИЯ АДРЕС БАЛАНС
I. AUTR (Р.).-Ларк I. -Ларк _Ь
Таблица предоставляемых прав
Все операторы AUTR., как и ограничения целостности, помещаются в
таблицу. Из этой таблицы можно напечатать права, предоставленные кон-
кретному лицу на некоторое отношение, или все права, предоставленные
применительно к данному отношению. Это делается аналогично тому, как
печатаются ограничения целостности. Подобным же образом владелец от-
ношения может удалить права из таблицы, касающейся данного отношения.
9.5. СЕКРЕТНОСТЬ В СТАТИСТИЧЕСКИХ БАЗАХ ДАННЫХ
База данных, позволяющая получать агрегированную информацию о
больших подмножествах некоторого множества объектов, называется ста-
тистической. Примерами могут служить база данных переписи населения
или (для определенных приложений) файл служащих, налоговых деклара-
ций либо пациентов госпиталя. Кроме обычных проблем предотвращения
несанкционированного доступа к базе данных или осуществления ее модифи-
кации, в статистической базе данных существуют довольно сложные пробле-
мы, связанные с тем, что допускаются запросы вида «Напечатать средний до-
ход всех жителей штата Нью-Джерси» и в то же время запрещается доступ
к данным о доходах конкретного человека, например Джона Джонса.
Не так просто запретить запросы, которые требуют информации, отно-
сящейся к единственной записи. Например, Фред Смит может запросить сред-
ний доход для множества {Фред Смит, Джон Джонс), из которого, зная
свой собственный доход, он в состоянии вычислить доход Джойса. Не реша-
ет проблему также и требование, чтобы агрегированная информация запра-
шивалась относительно множества, состоящего, по крайней мере, из т чело-
век, для достаточно большого т, устанавливаемого механизмом секретно-
сти базы данных. Действительно, в этом случае Смит мог бы взять множе-
ство 5 из т — 1 или более человек, доходы которых ему не нужно узнавать,
и запросить средний доход этих людей вместе с Джонсом. Затем он получил
бы средний доход для множества, включающего его самого и людей из мно-
жества S. Зная свой собственный доход, он смог бы теперь легко определить
доход Джонса на основе двух ответов системы.
Проблема в приведенном примере связана вовсе не с тем, что допускают-
ся запросы относительно небольших множеств. Число т может быть сколь-
угодно большим. Речь идет здесь скорее о способности запрашивающего
сделать два запроса, мало чем отличающихся друг от друга. Возможность
подобного рода наводит на мысль о необходимости наложения ограничений
279
не только на размер множеств, относительно которых можно получать стати-
стику, но и на размер пересечения двух таких множеств. В дальнейшем бу-
дет показано, что указанное ограничение помогает решить эту проблему.
Мы не можем предотвратить раскрытие индивидуальных данных, но в наших
силах сделать это достаточно трудным делом.
Модель статистической базы данных
Будем считать для простоты, что статистическая база данных содержит
единственный файл записей. Каждая запись состоит из нескольких полей.
Запрос специфицирует значения каких-либо полей и продуцирует некото-
рую агрегированную информацию, такую, как среднее или сумма значений
одного поля, взятых по всем записям, удовлетворяющим условиям запроса.
Например, если запись состоит из имени, профессии и зарплаты, можно за-
просить среднюю зарплату всех лиц с именем Смит или суммарную зарпла-
ту всех юристов.
Предполагается, что существует механизм защиты, который, помимо вы-
полнения обычных функций обеспечения секретности, рассмотренных в разд.
9.3, контролирует все запросы каждого пользователя, запоминая большое
число сделанных им ранее запросов. Этот механизм защиты может придер-
живаться стратегии, при которой система отказывается отвечать на запросы,
затрагивающие менее чем заранее установленное минимальное число записей,
а также на запросы, имеющие слишком большое пересечение с предыдущими
запросами-
Вообще говоря,применение последнего правила может потребовать, что-
бы система в течение длительного периода времени запоминала для каждого
запроса битовый вектор, представляющий множество запрашиваемых запи-
сей. Поэтому указанное правило может оказаться практически нереализуе-
мым. Необходимо наложить некоторые ограничения на то, что следует за-
поминать. Например, можно хранить информацию лишь об ограниченном
числе запросов или разбить записи на группы и запоминать только инфор-
мацию о тех группах, в которых содержатся записи, удовлетворяющие данно-
му запросу. Первый из этих методов позволяет получить ответ на запрос, на
который система не должна была бы отвечать. В то же время при втором ме-
тоде может быть отвергнут запрос, на который система могла бы дать ответ
без всякого риска.
Линейные запросы
Рассмотрим базу данных, содержащую «записей. Пусть v—(t»!, v2.vn)
— вектор значений некоторого неключевого поля этих записей. Тогда
п
линейным запросом называется линейная сумма гДе ci — произволь-
ные действительные числа. Наиболее важными случаями линейных запросов
являются суммы по множеству 5, где Ct = 1, если запись i принадлежит S,
и а = 0, если это условие не выполняется, а также средние, где с{ = 1/р,
если запись i принадлежит S, и нулю — при невыполнении этого условия;
р — число записей в 5. Однако то, что мы называем нашей способностью
компрометировать базу данных (вычислять значения отдельного и;), вооб-
ще говоря, будет зависеть от допустимого числа ненулевых Ct, а не от их
точных значений или равенства некоторых ненулевых сг.
280
Предположим, что имеется множество из q запросов, где i-й запрос по-
п
лучает из базы данных rt = 2 cavi- Результаты этих запросов могут быть
выражены в-матричном виде как
rT = Alvr,
где М — матрица размерности q на п, элементом которой в строке i и столбце
j является ctj, a v и г — векторы соответственно (t^,..., vn) и (Гх,..., rq). Верх-
ний индекс Т означает транспонирование, преобразующее вектор-строку,
такой, как г или V, в вектор-столбец. Если необходимо скомпрометировать
базу данных, нужно вычислить некоторую функцию/ (ri,..,., rg), равную од-
ному из vj. Не теряя общности, будем считать, например, что значение функ-
ции должно быть равно ох. В следующей лемме формулируется важное утвер-
ждение.
Л е м м а 9.1. Если в терминах введенных выше обозначений существу-
ет некоторая функция /, такая, что f (t\.rq) = Oj, то существует и линей-
ная функция, обладающая таким свойством.
Доказательство. Доказательство требует некоторых знаний
линейной алгебры и функций многих переменных. Поэтому мы опускаем его
здесь, но в упражнениях дадим некоторые рекомендации, тем кто желает
доказать эту лемму.
Предположим теперь, что f — линейная функция. Тогда существует
q
некоторый вектор d = dq), такой, что f (rx........ rq) = ^jdirt = vt.
/=i
Тогда, подставляя MvT вместо гт, имеем
drr — — t»x.
Отсюда следует, что dA4 представляет собой вектор (1,0...0) длины п.
Тогда в терминах статистических баз данных справедливо следующее утвер-
ждение. Для того чтобы скомпрометировать базу данных, что эквивалентно
для нас без потери общности возможности вычисления элемента vlt нужно
найти совокупность q запросов, формирующих матрицу М, для которой су-
ществует некоторый вектор d, удовлетворяющий условию: dAf —(1,0,...,0).
Если налагаются ограничения на запросы (это означает введение ограниче-
ний на строки матрицы М), то можно доказать, что М должна иметь много
строк, т. е. если существует такой вектор d, необходимо большое число за-
просов. В частности, рассмотрим два следующих ограничения на М:
1. Каждая строка должна иметь по крайней мере m ненулевых элемен-
тов. Это означает, что при каждом запросе должно затрагиваться минимум
пг значений.
2. Никакие две строки не должны иметь более Л столбцов, в которых обе
они имеют ненулевые элементы. Перефразируем это требование в терминах
баз данных: пересечение множеств элементов, участвующих в двух запросах,
не должно превышать k.
Пример 9.6. Рассмотрим базу данных из семи элементов ох.vt и исполь-
зуем следующие пять запросов:
Г1 = + V3 +
r2 = он +
r3 = V1 + V2 + Об
Гз = V1 + VS + ve
Ъ = 1»1 + + и,
281
Тогда — (r3 + rt + rt — rr — r2)/3. Заметим, что каждый запрос вовлекает
не менее трех значений, и никакие два запроса не имеют пересечения, состоящего более
чем из одного элемента, т. е. т — 3 и k = 1. В матричных терминах запросы вычис-
ляют произведение матрицы на вектор (рис. 9.3). Вектор d равен (—1/3, —1/3, 1/3, 1/3,
1/3). Заметим, что произведение вектора на матрицу, представленную на рис. 9.3, дает
(1, 0, 0, 0, 0, 0, 0).
Гг
г3
0
0
1
1
1
1
0
1
0
0
1
0
0
1
О
1 о о
О 1 1
О 1 о
О О 1
1 о о
о
1
о
о
1
01
02
оз
04
vt
ов
VI
Рис. 9.3. Запрос, выраженный в виде произведе-
ния матрицы на вектор
Найдем теперь верхнюю и нижнюю оценки числа запросов, необходи-
мых для того, чтобы скомпрометировать базу данных. При этом будем пред-
полагать, что каждый запрос вовлекает по меньшей мерет элементов, и ника
кие два запроса не используют более k общих элементов. Можно предполо
жить также, что р значений уже известны, и для компрометации базы данных
необходимо определить пока еще неизвестный элемент.
Теорема 9.1. Пусть допускаются только запросы, продуцирующие
линейную функцию по меньшей мере от т элементов, и никакие два запроса
не могут иметь более k общих элементов. Предположим далее, что р элемен
тов уже известны. Тогда для вычисления некоторого еще неизвестного эле
мента необходимо сделать не менее 1+ (т— 1 — p)/k запросов.
Доказательство. Рассмотрим первый запрос, который про-
дуцирует сумму по меньшей мере т элементов множества S. Пусть vt явля-
ется элементом S. Если vt нет среди р уже известных элементов и цг не вы-
числяется как элемент произведения матрицы М на вектор v (здесь исполь-
зуются введенные ранее обозначения), то доджен существовать некоторый
другой запрос, который вовлекает vt. Можно предположить, что М имеет
наименьшее возможное число строк, т. е. что мы делаем запросов не более
чем необходимо для компрометации базы данных. Другими словами, мы
предполагаем, что вектор d не имеет нулевых компонентов. В этом случае
если только один запрос вовлекает vt, произведение d/И должно иметь нену-
левой i-й компонент. Так как никакой запрос не может дать пересечение со
множеством S, состоящее более чем из k элементов, и, вообще, как мини-
мум т — р — 1 элементов S должно появляться в другом запросе, то до-
полнительно к первому запросу должно быть не менее (т — р — 1)/& запро-
сов, что и доказывает теорему.
Теорема 9.1 имеет важное следствие. В предположении, что р — число
предварительно известных элементов — мало по сравнению с т, требуется
примерно mlk запросов для компрометации базы данных. Поскольку т и k
являются параметрами стратегии защиты, мы должны выбрать их таким об-
разом, чтобы их отношение было большим, например равным 1000. Тогда
можно быть уверенным в том, что потребуются значительные усилия для
компрометации базы данных. Однако заметим, что большое т и малое k мо-
гут быть обременительными для пользователя, заинтересованного во вполне
законной статистической информации. Кроме того, запоминание последних
1000 запросов для каждого пользователя может быстро привести к перепол-
нению пространства памяти системы. Поэтому возможность применения ме-
тода ограничения размера и пересечения запросов весьма сомнительна,
252
Возникает вопрос, не слишком ли пессимистична теорема 9.1? Может
быть, в действительности требуется существенно больше, чем tnlk запросов,
для компрометации базы данных? К сожалению, оказывается, что это не так.
Пусть р — 0, k ~= 1 и л = 1 + m(m+ 1)/2. Рассмотрим матрицу М раз-
мерности (т + 1) на (1 + т (т + 1)/2), где первый столбец содержит всего
одну 1, а остальные — нули. Каждый из оставшихся столбцов имеет по два
ненулевых элемента, и никакие два из этих столбцов не имеют двух одинако-
вых ненулевых строк. Это возможно, так как существует т (т + 1)/2 спо-
собов выбора двух строк из m 4- 1. В любом из столбцов, от второго до
tn (т 4- 1)/2, имеется одна 1 и одна —1. Таким образом, сумма всех строк
матрицы М равна (1,0,0,...О,) и позволяет нам компрометировать базу дан-
ных путем вычисления vt. Поскольку никакие два столбца не идентичны и
каждый из них имеет не более двух ненулевых элементов, не может быть
двух строк, в которых одновременно содержатся нули более чем в одном
столбце *. На рис. 9.4 показана матрица М. для случая т = 3.
0 1110 0 0
0—100110
О 0—1 0—1 О 1
.1 О 0—1 0—1 —1.
Рис. 9.4. Матрица М, доказывающая
быструю компрометацию
Заменяя каждый столбец (за исключением самого левого) k идентич-
ными столбцами, можно обобщить рассмотренную выше стратегию с тем, что-
бы скомпрометировать базу данных с помощью l+m/k запросов, что очень
близко к нижней оценке из теоремы 9.1. Доказательство оставляется читате-
лю для упражнения.
Возможно, что линейные запросы общего вида допускают быструю ком-
прометацию. Тем не менее если мы ограничимся запросами только сумм или
средних, что, по нашему предположению, должен обеспечивать язык запро-
сов, то можно улучшить нижнюю оценку теоремы 9.1. Результат кажется не-
сколько сомнительным, однако можно показать, что при k = 1 достаточно
2т — 1 запросов сумм для компрометации базы данных. Предположим, что
п = 14- т (т— 1). Первый запрос требует сумму элементов от 2-го до
(т 4- 1)-го, второй — от (т 4- 2)-го до (2m 4- 1)-го, третий — от (2т 4~2)-го
до (3 т 4- 1)-го и т. д. Последние т запросов требуют суммы, каждая из ко-
торых включает первый элемент. Запрос т также включает элементы 2,
т 4- 2, 2т 4- 2,..., запрос т 4- 1 — элементы 3, т 4- 3, 2т 4- 3, ... и т. д.
Матрица для случая т — 3 показана на рис. 9.3. Обобщение приведенных ар-
гументов и указанный рисунок позволяют показать, что при произвольных
т и k достаточно 2mlk — 1 запросов для того, чтобы скомпрометировать
базу данных.
Ограничения на структуру запросов
До сих пор предполагалось, что запросы специфицируют произвольные
подмножества записей в базе данных с ограничением лишь на нижнюю гра-
ницу размера подмножеств. Как было установлено выше, компрометация
базы данных с использованием таких запросов отнюдь не невозможна, одна-
ко требует значительного времени, если будет ограничено пересечение мно-
1 Не считая первого. — Примеч. ред.
283
жеств, определенных двумя запросами. Вероятно, если запретить все «боль-
шие» запросы, то, действительно, мы в состоянии гарантировать невозмож-
ность компрометации базы данных.
Один из известных подходов основан на предположении, что ключ запи-
сей состоит из k бит и что для каждого или почти каждого значения ключа
фактически имеется запись. Допускаются запросы, где специфицируется не
более s бит ключа и требуется найти сумму элементов данных из всех записей,
значения ключей которых в специфицированных битах совпадают со значе-
ниями для этих бит, заданными в запросе. Например, если k = 3 из =2,
можно специфицировать, что первый бит равен 1, адретий — 0. Тогда ре-
зультатом запроса будет сумма данных в записях с ключами 100 и ПО.
Заметим, что при этом фактически выполняется поиск по частичному со-
ответствию, рассмотренный в разд. 2.8. Как и ранее, мы не ограничиваемся
двоичными значениями ключей. Можно предположить, что ключ состоит из
некоторого числа полей, каждое из которых принимает значения из опреде-
ленного «малого» множества значений. В отличие от разд. 2.8, здесь предпо-
лагается также, что результат представляет собой не полное множество со-
ответствующих записей, а сумму содержимого конкретного поля («данных»
в записи) во всех этих записях.
Пример 9.7. Допустим, что наша статистическая база данных состоит из
данных переписи населения США. Каждая запись при этом содержит сумму доходов
всех лиц, «характеристики» которых соответствуют битам значения ключа для этой за-
писи. Предположим, что 6 бит ключа представляют штат, в котором проживает кон-
кретный человек, 8 бнт означают местность в штате (возможно, округ или город), 1 бит
указывает пол, 6 бит — профессию (профессии произвольным образом разделены на
64 категории) и 5 бит — марку его автомобиля (при этом только одна марка автомо-
биля для одного человека заносится в базу данных). Тогда k = 6 -8 + 1 + 6 +
+ 5 = 26. Так как 2ft приблизительно равно 67 млн., каждая запись в среднем пред-
ставляет доход небольшого числа лиц.
Положим s = 15. Тогда можно узнать с помощыЗ одного запроса сумму доходов
всех мужчин, проживающих в округе Вашингтон, штат Айдахо (эти характеристики
специфицируются в 15 битах), или сумму доходов всех каменщиков, владеющих авто-
мобилями марки «Плимут» (что специфицируется,в 11 битах). Однако мы не можем за-
просить сумму доходов каменщиков штата Айдахо, владеющих автомобилями марки
«Плимут» (для спецификации этих характеристик требуется 17 бит). В принципе мож-
но специфицировать до 15 бит, которые включают некоторые (но не все) биты штата,
некоторые биты профессии и т. д.
Оказывается, что в предложенной выше модели не существует совокуп-
ности допустимых запросов, с помощью которой можно было бы получить
данные из отдельной записи, при условии, что s < k, т. е. прн условии, что
не допускается спецификация в запросе всех бит ключа. В действительности
мы можем доказать значительно более сильное утверждение. Из ответов на
запросы, в которых специфицируются не более s ключевых бит из k, нельзя
вычислить никакой функции, вовлекающей менее чем 2fe-s записей. Более
точная формулировка этого утверждения приводится в следующей теореме.
Теорема 9.2. Если запросы продуцируют сумму «данных» всех за-
писей с ключами, состоящими из k бит и соответствующими специфицирован-
ным битам, число которых не превышает s, то никакая рациональная функ-
ция 1 результатов таких запросов не может быть функцией значений данных,
взятых более чем из нуля, но менее чем из 2fe-s записей.
Доказательство. Здесь не приводится. Его можно найти в ра-
боте Яо [179].
1 Т. е. функция, использующая только операции сложения, вычитания, умноже-
ния и деления.
284
Следствие. Если s < k, то никакая рациональная функция ре-
зультатов запросов не может быть значением элемента данных в одной запи-
си, т. е. база данных не может быть скомпрометирована.
УПРАЖНЕНИЯ
9.1. Предположим, что имеется база данных Query-by-Example, состоящая из
отношений:
СЛУЖАЩИЕ (ТАБ-НОМЕР, ИМЯ, АДРЕС, ЗАРПЛАТА, НОМЕР^ОТДЕЛА)
ОТДЕЛЫ (НОМЕР-ОТДЕЛА, НАЗВ_ОТДЕЛА, ЗАВЕДУЮЩИЙ)
Выразите следующие ограничения целостности:
а) ни один из служащих не зарабатывает более 100 000 дол.;
б) ни один из служащих в отделе 72 не зарабатывает более 50 000 дол;.
в) ни один из служащих в отделе игрушек («игрушка»—значение атрибута
НАЗВ_ОТДЕЛА), не получает более 50 000 дол.;
*г) не существует двух отделов, имеющих одинаковые номера.
Указание'. Используйте оператор CNT. (count — пересчитать).
**9.2. Покажите, что каждая функциональная и многозначная зависимость мо-
жет быть выражена в языке ограничений QBE.
9.3. Выразите с помощью языка предоставления прав QBE следующие ограниче-
ния на права пользователей, имеющие отношение к базе данных из упражнения 9.1:
а) каждый может читать отношение СЛУЖАЩИЕ, за исключением атрибута
ЗАРПЛАТА;
б) любой служащий может читать свою собственную зарплату;
в) заведущий отделом может читать зарплату любого служащего из его отдела;
г) служащий Варбакс может включать и удалять кортежи отношения СЛУЖА-
ЩИЕ и модифицировать в них зарплату.
**9.4. На рис. 9.5 изображена база данных вестсайдских гангстеров. Естест-
венно, гангстеры желают сохранить свои индивидуальные доходы в секрете. Поэтому
их база данных позволяет запрашивать только суммы доходов т или более членов груп-
пы. Более того, никакие два запроса не могут затрагивать более чем k одних и тех же
членов. При каких значениях т и k эта конкретная база данных является секретной
в том смысле, что не могут быть вычислены доходы какого-либо отдельного лица?
Указание. Проведите анализ, следуя теореме 9.1, предполагая, что нижняя оцен-
ка достижима (т. е. базы данных могут быть скомпрометированы при всех т и k, хотя
и медленно). Следует при этом предположить, что база данных — достаточно большая.
В случае базы данных для небольшого числа лиц конструкции, соответствующие тео-
реме 9.1, могут оказаться неработоспособными.
Имя Букмекерство Контрабанда Жульничество Доход
Ральф Крыса да да нет ?
«Доносчик» да нет да ?
«Человек со шрамом» нет да да ?
«Обманщик» да нет нет ?
Сэм Змея нет нет да ?
«172039» да да да ?
Рнс. 9.5. База данных вестсайдских гангстеров
*9.5. Предположим, что в вестсайдской базе данных допускаются лишь запросы
о сумме доходов по категориям, где категория определяется спецификацией того, уча-
ствует ли гангстер в одном или двух конкретных видах деятельности. Например, мож-
но запросить сумму доходов всех гангстеров, вовлеченных в операции с контрабандой,
но не занимающихся жульничеством. Оказывается, что такой запрос позволил бы нам
выяснить доход Ральфа Крысы, и, следовательно, база данных была бы скомпромети-
рована. Покажите, что с помощью запросов, ограниченных предложенным выше спо-
собом, можно вычислить доход каждого из гангстеров.
9.6. Почему упражнение 9.5 не противоречит теореме 9.2?
285
*9.7. Докажите лемму 9.1, в которой утверждается, Что если / (rlt .... гч) — Dj,
то можно предположить, что /— линейная функция. Указание. Воспользуйтесь соот-
ношением
df _ dfj
drj dvi
2L
dui
drj
того, т— есть константа Си
UVi а
df ( 1 , если i = 1;
dvi I 0—в противном случае.
9.8. Покажите, что теорема 9.1 дает точную нижнюю оценку даже для k > 1
Указание. Обобщите аргументы для случая k = 1, приведенные после теоремы 9.1.
**9.9. Докажите теорему 9.2.
Библиографические замечания
В книгах Хоффмана [87] и Де-Милло, Добкина, Джоунса и Липтона [55] обсужда-
ется общая проблема секретности в вычислительных системах. Материалы разд. 9.2
и 9.4 по секретности и целостности в Query-by-Example взяты из работы Злуфа [187].
Заметим, что эти средства в настоящее время не реализованы в коммерческой версии
QBE, описанной в руководстве ИБМ [92]. Обсуждение подобных методов в контексте
системы INGRES, включающих, однако, идею проверок секретности и целостности
путем добавления ограничений к предложению WHERE для каждого запроса, можно
найти в работах Стоунбрейкера и Вонга [163], Стоунбрейкера [160], а также Стоун-
брейкера и Рубинштейна [162].
В статье Фейгина [66] исследуется и доказывается корректность алгоритма пере-
дачи полномочий пользователям базы данных с возможностью передачи самого права
передачи полномочий. Эта идея была ранее исследована Гриффитсом и Вейдом [81].
Краткий обзор механизмов секретности базы данных содержится в отчете Мресса [121].
Более широкий обзор подготовлен Хсяо, Керром и Мэдником [90].
Наиболее ранние формулировки проблем секретности в статистической базе дан-
ных были предложены Хоффманом и Миллером [88] и Хэком [84, 85]. Формальное ис-
следование проблемы началось работой Добкина, Джоунса и Липтона [60], доказавших
теорему 9.1. Их модель была далее исследована Рейссом [137] и Ван-Лиувеном [173].
Теорема 9.2 принадлежит Яо [179], хотя Кэм и Ульман [96] ранее доказали эту теоре-
му для специального случая линейных рациональных функций.
Недавно были исследованы различные стратегии защиты статистических баз дан-
ных. Чин [37] рассмотрел схемы, запрещающие отвечать на запросы о малых множест-
вах, и показал, что даже если значения не могут быть выведены, наличие некоторой
записи в базе данных может быть подтверждено или опровергнуто. Де-Милло, Добкин
и Липтон [56] исследовали стратегии, при которых система иногда преднамеренно вы-
дает неправильный ответ, и показали, что даже этот механизм не обеспечивает секрет-
ности. Деннинг, Деннинг и Шварц [58] изучили базу данных, в которой поддержива-
лось секционирование ключей, а также запрещались запросы, затрагивающие слиш-
ком много лиц из одного блока секционирования. Обобщая идеи Шлорера [148, 149],
Деннинг, Деннинг и Шварц [59] показали, как вообще возможно конструировать
«шпиона», т. е. запрос, с помощью которого можно получить информацию о записях,
обладающих некоторым множеством характеристик, даже если это множество меньше,
чем допускается системой секретности базы данных.
Обзор по секретности статистических баз данных и дополнительную библиогра-
фию можно найти в работах Ю и Чина [182], а также Деннинга [57].
ГЛАВА 10
ПАРАЛЛЕЛЬНЫЕ ОПЕРАЦИИ НАД БАЗОЙ ДАННЫХ
До сих пор рассматривалась концепция базы данных, при которой пре-
дусматривается одновременное исполнение только одной программы, осу-
ществляющей доступ к базе данных (такие программы исполняются последо-
вательно). На практике это чаще всего и требуется. Однако существует це-
лый ряд приложений, когда одновременно (параллельно) исполняется не-
сколько программ или различных прогонов одной и той же программы. В си-
стеме продажи авиабилетов, например, продавать билеты и изменять таким
образом списки пассажиров и число свободных мест могут одновременно не-
сколько агентов. Главная проблема состоит в том, что если не позаботиться
о правилах, регулирующих доступ к базе данных двух или более программ,
то не исключается возможность продажи билетов на одно и то же место двум
пассажирам. Интуиция подсказывает нам, что не следует допускать парал-
лельное исполнение двух процессов, которые читают и изменяют значение
одного и того же объекта.
Другим примером может служить статистическая база данных, напри-
мер база данных переписи населения. К такой базе данных одновременно мо-
жет обращаться много пользователей. Поскольку здесь никто не изменяет
данные, нет нужды беспокоиться о том, в каком порядке их читают процес-
сы. Мы можем при этом позволить операционной системе планировать одно-
временное чтение данных по запросам на ее усмотрение. В подобных ситуа-
циях, когда осуществляется лишь чтение, для экономии времени желатель-
но в максимальной степени использовать параллелизм операций. Напротив,
в системе продажи билетов, где выполняется как чтение, так и запись, не-
обходимо наложить некоторые ограничения, если допускается одновремен-
ное исполнение двух программ.
В настоящей главе рассматриваются различные модели параллельных
процессов применительно к операциям над базой данных. Эти модели разли-
чаются в основном степенью подробности описания доступа к ее элементам.
Для каждой модели описывается целесообразный образ действий, позволя-
ющий выполнять параллельные операции, которые сохраняют целостность
базы данных, и в то же время препятствующий одновременному выполне-
нию тех из них, которые могут нарушить ее целостность. Как правило, чем
в большей степени детализирована модель, тем больший параллелизм можно
надежно обеспечить.
ЮЛ. ОСНОВНЫЕ КОНЦЕПЦИИ
Транзакция — это разовый прогон программы. Программа может быть
простым запросом, выраженным в одном из языков запросов, рассмотрен-
ных в гл. 4. Она может быть также сложной программой, написанной на
287
включающем языке с встроенными обращениями к базе данных средствами
языка запросов, например QUEL, SEQUEL, языка манипулирования дан-
ными DBTG или DL/1 системы IMS. Одновременно возможно исполнение не-
скольких независимых прогонов одной и той же программы, и каждый из
них является транзакцией.
Элементы
Представим себе, что база данных разбивается на элементы, т. е. на час-
ти, которые можно блокировать. Блокируя некоторый элемент, транзакция
может препятствовать доступу других транзакций к этому элементу до тех
пор, пока она не разблокирует его. Функциональный компонент СУБД,
называемый управлением блокировками, назначает и регистрирует блокиров-
ки, а также играет роль арбитра между двумя или более запросами на бло-
кировку одного и того же элемента.
Природа и размер элементов являются спорным вопросом. В реляцион-
ной модели данных, например, можно выбрать большие элементы, подоб-
ные отношениям, или малые, такие, как отдельные кортежи и даже’компо-
ненты кортежей. Можно подобрать и промежуточный размер элементов. Они
могут представлять собой, например, совокупности из 100 кортежей некото-
рого отношения. В сетевой модели элемент может быть совокупностью всех
записей одного типа либо, к примеру, тем, что в предложениях DBTG назы-
вается экземпляром набора.
Выбор больших элементов сокращает накладные расходы системы по
поддержанию блокировок, тогда как выбор малых элементов дает возмож-
ность параллельного исполнения многих транзакций. Рискуя упрощенно ис-
толковать выводы, полученные в ряде аналитических работ, упомянутых в
библиографии, предположим, что правильный выбор размера элементов сде-
лан в том случае, когда средняя транзакция требует доступа к малому числу
элементов. Так, если типичная транзакция (в реляционной системе) читает
или модифицирует один кортеж, который она находит с помощью индекса,
то целесообразно трактовать кортежи как элементы. Если же типичная тран-
закция производит соединение двух или более отношений и тем самым тре-
бует доступа ко всем кортежам этих отношений, более уместно, по-видимо-
му, в качестве элементов выбрать отношения.
В дальнейшем будем предполагать, что при модификации части элемен-
та модифицируется и весь элемент, получая при этом уникальное значение,
отличное от значения, которое он может получить при любой иной модифика-
ции. Мы принимаем такое допущение не только для упрощения моделирова-
ния транзакций. На практике, чтобы установить, что в результате данной
модификации элемент приобретает такое, же значение, как и после некоторой
предыдущей модификации, требуется значительная работа системы. Более
того, если система должна запоминать, остается ли неизменной часть эле-
мента после его модификации, то с тем же успехом она может разделить эле-
мент на несколько более мелких. Вследствие нашего предположения о неде-
лимости элементов не будет ошибкой рассматривать их как простые перемен-
ные, используемые в обычных языках программирования.
Блокировки
Пример 10.1. Чтобы убедиться в необходимости блокирования элементов,
рассмотрим две транзакции 1\ и Т2. Каждая Из них осуществляет доступ к элементу А,
имеющему, по нашему предположению, целочисленное значение, и увеличивает его
2НК
значение на единицу. Обе эти транзакции представляют собой прогоны программы Р,
имеющей следующий вид:
Р : READ А; А: = А + 1; WRITE А;
Значение А находится в базе данных. Программа Р читает (READ) значение А
в свое рабочее пространство, добавляет к нему единицу и записывает (WRITE) резуль-
тат в базу данных. На рис. 10.1 показаны эти транзакции, исполняемые вперемешку1,
и соответствующие значения А в базе данных на каждом шаге.
Значение А в базе данных 5 5 5 5 6 6
ТГ- READ А READ А Л:=Л-|_1 А:=А-|-1 WRITE А WRITE А
Значение А в рабочем про- странстве Г] 5 5 6 6 6 6
Значение А в рабочем про- странстве Т2 5 5 6 6
Рис. 10.1. Транзакции, демонстрирующие необходимость блокирования элемента А
Легко заметить, что, хотя каждая транзакция добавляла к А единицу, его зна-
чение возросло лишь на 1. Это представляет серьезную проблему, если, например, А —
число мест, проданных иа определенный авиарейс.|
Решение проблемы, обсуждавшейся в примере 10.1, состоит в обеспече-
нии блокировки для А. Перед тем как прочитать А, транзакция Т должна
его блокировать, что предотвратит доступ другой транзакции к нему до тех
пор, пока Т не завершит работу с А. Кроме того, необходимость для Т бло-
кировать А объясняется еще и тем, что при этом становится возможным вос-
препятствовать доступу этой транзакции к А в том случае, когда А уже ис-
пользуется какой-либо иной транзакцией. Транзакция Т должна ждать, по-
ка другая транзакция разблокирует А, что возможно только после оконча-
ния работы этой другой транзакции с А.
Рассмотрим теперь программы, которые при взаимодействии с базой дан-
ных не только читают и записывают ее элементы, но и блокируют и разбло-
кируют их. Условимся, что элемент должен быть блокирован до начала чте-
ния или записи и что операция блокирования действует как примитив син-
хронизации 1 2. Это означает, что если транзакция пытается блокировать уже
блокированный элемент, ей приходится ждать, пока блокировка не будет
снята по команде разблокирования, которая выполняется транзакцией, ус-
тановившей блокировку. Предположим также, что каждая программа в
конце концов должна разблокировать любой элемент, который она блоки-
ровала. Расписание элементарных шагов двух или более транзакций, такое,
что выполняются указанные выше правила, касающиеся блокировок, назы-
вается легальным.
1 Поскольку мы ие принимали допущения о том, что два аналогичных шага тре-
буют одинакового времени, то Т2 может завершиться ранее Tlt даже если обе транзак-
ции выполняют одинаковые шаги. Однако смысл данного примера не изменится, если
7\ будет записывать значение А в базу данных перед Т2.
2 Термин, используемый в литературе, посвященной проблематике параллельных
процессов. Смысл его поясняется далее. — Примеч. ред.
10 Зак. 1315
289
Пример 10.2. Программу Р из примера 10.1 можно было бы записать с бло-
кировками следующим образом;
Р : LOCK A; READ А; А : = А + 1; WRITE A; UNLOCK А;
Предположим, снова, что 7\ и Т2 — два исполнения программы Р. Если первой начи-
нается Т\, она запрашивает блокировку А. Система предоставляет эту блокировку при
условии, что никакая другая транзакция ие заблокировала А. Тогда транзакция 7\
(и только она одна) получает доступ к А. Если 7\ начинается до завершения 7\, то,
как только Т2 попытается выполнить команду БЛОКИРОВАТЬ A (LOCK А), система
заставит ее ждать. Лишь когда Тх выполнит команду РАЗБЛОКИРОВАТЬ А
(UNLOCK А), система разрешит продолжить исполнение транзакции Т2. Следователь-
но, аномалия, указанная в примере 10.1, не может иметь места. Одна из транзакций,
Тх либо Т2, будет выполнена полностью перед тем, как начнется другая из них, а их
совместным результатом окажется увеличение Л на 2.
Бесконечные ожидания и тупики
Мы приняли выше, что должен существовать функциональный компо-
нент СУБД, предоставляющий по запросам и приводящий в действие блоки-
ровки элементов. Поведение механизма такого рода не может быть непо-
стоянным, поскольку в противном случае мы столкнемся с нежелательными
явлениями. В примере 10.2 блокировка предоставляется Т2 после снятия
ее транзакцией Рассмотрим теперь иную ситуацию. Пусть во время пре-
бывания Т2 в состоянии ожидания транзакция Т3 также запрашивает блоки-
ровку А, и этот запрос выполняется раньше, чем запрос Т2. Далее, в то вре-
мя, когда блокировку установила транзакция Т3, ее запрашивает Т4, чье
требование удовлетворяется после разблокирования А транзакцией Т3, и т. д.
Очевидно, при этом не исключена возможность того, что Т2 будет бесконечно
находиться в состоянии ожидания, тогда как некоторые другие транзакции
постоянно осуществляют блокировку А, хотя и существует неограниченное
число моментов, когда транзакция Т2 имеет шансы заблокировать А.
Состояние такого рода называется бесконечным ожиданием. Подобная
проблема потенциально может возникнуть в любой обстановке, предусмат-
ривающей параллельное исполнение процессов. Разработчиками операцион-
ных систем предложены различные пути ее решения. Однако этот вопрос не
является специфическим для систем баз данных, поэтому мы его здесь обсу-
ждать не будем. Простой способ избежать бесконечного ожидания заключа-
ется в том, что система предоставления блокировок должна регистрировать
все не удовлетворенные немедленно запросы и предоставлять возможность
блокировки элемента А после его разблокирования первой запросившей ее
транзакции из числа ожидающих. Эта стратегия («первым вошел — первым
обслуживается») устраняет бесконечные ожидания и в дальнейшем мы мо-
жем считать, что такой проблемы не существует.
Более серьезная проблема, которая возникает при параллельной обра-
ботке, если не проявлять осторожности, — это так называемые «тупики».
Ее лучше всего проиллюстрировать на примере.
Пример 10.3. Пусть имеются две транзакции Тх и Т2, основными действиями
которых при параллельной обработке являются следующие:
7Х: LOCK A; LOCK В; UNLOCK A; UNLOCK В;
Т2 : LOCK В; LOCK A; UNLOCK В; UNLOCK А;
Здесь не имеет значения, что конкретно делают с элементами А и В эти транзак-
ции. Пусть они начинают исполняться примерно в одно и то же время. Транзакция Тх
1 Однако она может привести к «тупику». Такая ситуация обсуждается ниже.
290
запрашивает блокировку Л и ее запрос удовлетворяется. Точно так же удовлетворя-
ется запрос транзакции Т2 на блокировку В. Затем 7\ запрашивает блокировку В и
вынуждена ждать, поскольку этот элемент заблокирован транзакцией Т2. Аналогич-
но Т2 запрашивает блокировку А и должна ждать, пока разблокирует А. Таким
образом, ни одна транзакция не может продолжаться. Каждая из них ожидает, пока
другая разблокирует требуемый для нее элемент. Поэтому 7\ и Т2 будут ждать беско-
нечно.
Ситуация, при которой каждая из множества S двух или более транзак-
ций ожидает, когда ей будет предоставлена возможность заблокировать эле-
мент, заблокированный в данный момент времени какой-либо иной транзак-
цией из данного множества S, называется тупиком. Так как все транзакции
находятся в состоянии ожидания, ни одна из них не может разблокировать
элемент, необходимый для продолжения другой транзакции из S. Поэтому
ожидание для них становится бесконечным. Способы предотвращения тупи-
ков, как и бесконечных ожиданий, являются предметом многочисленных ис-
следований в литературе по операционным системам и по параллельной обра-
ботке вообще. Из существующих подходов к решению интересно отметить
следующие:
1. Потребовать, чтобы каждая транзакция единовременно запрашивала
все нужные ей блокировки. Пусть система либо полностью удовлетворяет
такой запрос (когда это возможно), либо не предоставляет вообще никаких
блокировок и заставляет данную транзакцию ждать, если один или более
требуемых элементов заблокирован другой транзакцией. Рассмотрим, каким
образом это правило позволило бы предотвратить тупик в примере 10.3. Си-
стема предоставила бы блокировку как А, так и В для транзакции 7\, если
бы она запросила блокировку первой. После завершения обе эти блоки-
ровки могли бы быть установлены для Т2.
2. Ввести произвольное линейное упорядочение элементов и по-
требовать, чтобы все транзакции запрашивали блокировки в этом по-
рядке.
Второй подход также предотвращает тупики. Пусть в примере 10.3 А
предшествует В (возможно, между ними имеются и другие элементы при за-
данном упорядочении). Тогда, затребовав блокировку А перед В, Т2 обна-
руживает, что А уже заблокирован 7\. Элемент В не был еще заблокирован
для Т2. Поэтому для 7\ доступна блокировка В, когда она будет запрашивать-
ся. При завершении 7\ блокировки на А и В снимаются, и Т2 может продол-
жаться. Чтобы убедиться в том, что никаких тупиков вообще не может воз-
никнуть при такой стратегии блокирования, предположим противное, т. е.
что существует множество S попавших в тупиковую ситуацию транзакций.
При этом транзакция Rt из S ожидает, когда некоторая другая транзакция
из S разблокирует элемент А,. Можно предположить, что каждая Rj из S
блокирует, по крайней мере, один из элементов Ait иначе мы могли бы уда-
лить Rj из S, но тем не менее все еще иметь тупиковую ситуацию. Пусть Ah —
первый при установленном линейном упорядочении элемент среди всех At.
Тогда Rh, ожидающая разблокирования Ah, не может удерживать блокиров-
ку ни одного из элементов А, для i Ф k, что противоречит принятым пред-
положениям.
Совсем иной способ борьбы с тупиками — Ничего не предпринимать для
их предотвращения, а периодически проверять запросы на блокировки и
выявлять, не возникла ли тупиковая ситуация. Облегчает проведение та-
кой проверки алгоритм построения графа, вершины которого представляют
транзакции, а дуга 7\ -> Т2 означает, что транзакция Тг ожидает выполне-
ния ее запроса на блокировку элемента, заблокированного в данный момент
10;
291
транзакцией Т2. Каждый цикл указывает тупик. Если же циклов нет, не су-
ществует и тупиков. В случае обнаружения тупика следует произвести ре-
старт хотя бы для одной из попавших в него транзакций, и ее воздействие на
базу данных должно быть аннулировано. Процесс такого рестарта может
усложниться, если не проявить должного внимания к тому, каким образом
транзакции осуществляют запись в базу данных до завершения их работы.
Этот вопрос обсуждается в разд. 10.6.
В дальнейшем предполагается, что при выполнении транзакций не воз-
никают ни тупики, ни бесконечные ожидания.
Сериализуемость
Теперь мы подошли к одной из проблем параллельной обработки, пред-
ставляющей интерес для разработчиков систем баз данных. В качестве вве-
дения вновь рассмотрим пример 10.1, когда две транзакции, исполняющие
программу Р, добавляют к А по единице, но в результате значение А увели-
чивается лишь на 1. Интуитивно ясно, что такая ситуация ошибочна. Тем
не менее эти транзакции делают в точности то, чего хотел автор программы Р.
Однако сомнительно, чтобы программист имел в виду такое поведение тран-
закций, так как если сначала исполняется 7\, а затем Т2, то мы получаем
иной результат — к А добавляется 2. Поскольку всегда имеется возможность
исполнять транзакции по одной одновременно (последовательно), разумно
считать нормальным или предполагаемым результат транзакции, который
мы получаем при отсутствии каких-либо иных параллельно исполняемых
транзакций. Таким образом, параллельное исполнение нескольких транзак-
ций корректно, если и только если их совместный результат будет тем же са-
мым, что и при исполнении этих транзакций последовательно в некотором по-
рядке.
Будем называть расписанием совокупности транзакций порядок, в ко-
тором выполняются элементарные шаги этих транзакций (блокировка, чте-
ние и т. д.). Естественно, шаги любой заданной транзакции должны появлять-
ся в расписании в порядке их вхождения в программу, прогоном которой яв-
ляется эта транзакция. Расписание считается последовательным, если все
шаги каждой транзакции выполняются последовательно, и сериализуемым1,
если его результат эквивалентен результату некоторого последовательного
расписания.
Пример 10.4. Рассмотрим следующие две транзакции, которые могут быть
частью бухгалтерской операции по переводу денежных средств с одного счета на дру-
гой:
Тх : READ А; А : = А — 10; WRITE A; READ В; В : = В + 10; WRITE В;
Tt : READ В; В : = В — 20; WRITE В; READ С; С : = С + 20; WRITE С;
Понятно, что любое последовательное расписание обладает свойством постоянст-
ва суммы А 4- В 4- С. На рис. 10.2, а показано последовательное, а на рис. 10.2, б —
сериализуемое, но не последовательное расписание. Несериализуемое расписание при-
ведено на рис. 10.2, в. Отметим, что в последнем случае величина В увеличивается, а
не уменьшается на 10 в силу того, что читает В прежде, чем Т2 записывает новое
уменьшенное значение В. Предотвратить возникновение подобной ситуации можно
посредством блокирования В.
1 Мы используем здесь этот термин, поскольку не удалось найти удобного
эквивалента в русском языке. Таким образом, сериализуемость означает приводимость
к последовательному виду. — Примеч. ред.
292
Тх Тх Гх Тх
READ А READ А READ А
А : - А—10 READ В А:=А—10
WRITE А А:= А—10 READ В
READ В В: = В —20 WRITE А
В: = В 4-10 WRITE А В: = В — 20
WRITE В WRITE В READ В
READ В READ В WRITE В
В:= В—20 READ С В: = В+10
WRITE В В:—В4-Ю READ С
READ С С:=С4-20 WRITE В
С.= С 4-20 WRITE В С: = С 4- 20
WRITE С WRITE С WRITE С
а) б) в)
Рис. 10.2. Варианты расписания
Напомним, что мы называем расписание сериализуемым, если его ре-
зультат эквивалентен результату некоторого последовательного расписания.
В том случае, когда допускаются произвольные операции с элементами, во-
обще невозможно проверить, дают ли два расписания одинаковый резуль-
тат при всех начальных значениях элементов. На практике делаются некото-
торые упрощающие предположения относительно операций, выполняемых
над элементами. Удобно предположить, в частности, что одинаковые их зна-
чения можно получить только при одной и той же последовательности опе-
раций. Поэтому мы не считаем, что (А + 10) — 20 и (А + 20) — 30 проду-
цируют одни и те же значения. Игнорируя алгебраические свойства арифме-
тики , мы совершаем лишь «нефатальные» ошибки в том смысле, что можно от-
вергнуть некоторое расписание как несериализуемое, хотя оно продуцирует
результат, аналогичный результату последовательного расписания. Но за-
то расписание никогда не рассматривается как сериализуемое, если оно не
является таким («фатальная» ошибка). Нефатальные ошибки могут исклю-
чить некоторые параллельные операции и тем самым сделать систему более
медленной, чем это теоретически возможно. Однако, в отличие от фатальных
ошибок, при этом никогда не могут быть получены некорректные результа-
ты. В остальных разделах последовательно используются модели с увеличи-
вающейся степенью детализации, которые позволяют установить, что более
широкие классы расписаний являются сериализуемыми, и, следовательно,
достигнуть большей степени параллелизма, гарантируя в то же время кор-
ректность результатов.
Протоколы и расписания
Как было показано выше, произвольные транзакции при их параллель-
ном исполнении могут приводить к бесконечному ожиданию, тупиковым си-
туациям и несериализуемому расписанию. Для исключения подобных ситу-
аций в нашем распоряжении имеются два инструмента. Первый из них —
планировщик — часть системы базы данных, которая служит арбитром
между конфликтующими запросами. Ранее уже обсуждалось, например, ка-
ким образом планировщик, основанный на стратегии «первым вошел — пер-
вым обслуживается», может исключить бесконечное ожидание. Планировщик
может также справляться с тупиками и несериализуемостью при помощи ре-
старта одной или более транзакций, предварительно аннулировав все вы-
полненные ими действия. Рестарты транзакций рассматриваются в разд. 10.6.
Другой подход, обеспечивающий преодоление тупиков и несериали-
зуемости, заключается в использовании одного или нескольких протоколов,
следовать которым должны все транзакции. Протокол в его наиболее общем
смысле представляет собой ограничение на последовательность шагов, кото-
293
рые может выполнять транзакция. Например, протоколом является исклю-
чающая тупики стратегия запрашивания блокировок элементов в некотором
фиксирование»! порядке. Главное внимание в последующих разделах этой
главы буде| уделено разработке протоколов, которые гарантируют сериали-
зуемость.
10.2. ПРОСТАЯ МОДЕЛЬ ТРАНЗАКЦИИ
Изучим простейшую модель транзакции, которая, однако, позволяет го-
ворить о сериализуемости. В этой модели транзакция рассматривается как
последовательность операторов блокирования и разблокирования. Каждый
блокированный элемент впоследствии должен быть разблокирован. Будем
считать, что между шагом LOCK А и последующим UNLOCK А транзакция
осуществляет блокировку А. Предполагается, что транзакция не предпри-
нимает попыток блокировать элемент, если она в это время уже осуществля-
ет его блокировку, и, кроме того, не пытается разблокировать элемент в про-
тивоположном случае.
Предположим далее, что всякий раз, когда транзакция осуществляет
блокировку элемента А, она изменяет его значение, и после разблокирова-
ния А имеет уникальное значение. Иными словами, если и v2 представ-
ляют собой два значения, которые может иметь А перед шагом LOCK А,
то после шага UNLOCK А значения А всегда различны в этих двух случаях
при условии, что v2.
Сопоставляя каждой паре шагов LOCK А и последующего за ним UN-
LOCK А однозначную функцию f, можно более формально рассматривать по-
ведение транзакций. Заметим, однако, что для данного элемента А транзак-
ция может иметь более одной такой пары, так как, хотя это вообще и не очень
хорошо, мы можем блокировать и разблокировать один и тот же элемент бо-
лее одного раза. Пусть До — начальное значение А до исполнения любых
транзакций. Значения, которые может принимать А, являются тогда форму-
лами вида f2... fn (До), где ft — функции, ассоциируемые с парами шагов
LOCK А — UNLOCK А соответствующих транзакций. Никакие различные
значения А не равны между собой, т. е. они рассматриваются как неинтер-
претируемые формулы. Такое определение «значения» точно трактует наше
неформальное утверждение из предыдущего раздела о том, что мы не должны
принимать каких-либо алгебраических законов, касающихся воздействия
транзакций на элементы.
Пример 10.5. На рис. 10.3 приведены трн транзакции н функции, ассоции-
рованные с каждой парой LOCK—UNLOCK. На рис. 10.4 показано возможное распи-
сание этих транзакций и результат их воздействия на элементы А, В н С. Нетрудно убе-
LOCK А )
LOCK В
UNLOCK A J
UNLOCK В
LOCK В
LOCK С
UNLOCK В
LOCK А
UNLOCK С
UNLOCK А
LOCK А
LOCK С
UNLOCK С
UNLOCK А
| ft ft
Ta
Рнс. 10.3. Три транзакции
диться в том, что это расписание не сериализуемо. Для доказательства допустим про-
тивное. Если бы 7\ предшествовало Т2, то конечным значением В было бы f3 (f2 (Во)),
а не f2 (f3 (Во)). Если же Т2 предшествовало бы Tlt то конечным значением А было бы
ft (fi (ft (А9)У), fi (ft (ft (Ao))) или fx (ft (fe (Ao))) в завнснмости от того, исполнялись
ли транзакции в порядке T2TiT3, Т2Т3Т1 или T’gT’jT’p Поскольку ни одна из этих фор-
294
мул не дает фактического конечного значения А на рис. 10.4, становится ясно, что Та
ие может нн предшествовать 1\, ни следовать за ней в эквивалентном последовательном
расписании. Поэтому такого последовательного расписания не существует.
Отметим, насколько существенно для доказательства наше предположение об
уникальности значений, продуцируемых данными функциями. Например, если допус-
калось бы равенство fja = fja, то нельзя было бы исключить возможности, что 7\
предшествует Та. Повторим еще раз, что предположение об уникальности значений
принято не просто для математического удобства. Разработка средств, необходимых
для того, чтобы система базы данных анализировала транзакции и выявляла такие си-
туации, когда fja = fj3, и тем самым позволяла бы рассматривать более широкий
класс расписаний как сериализуемых, вообще не оправдывает затрачиваемых усилий.
Проверка сериализуемости
При внимательном рассмотрении примера 10.5 и доказательства несе-
риализуемости расписания, приведенного на рис. 10.4, можно обнаружить
Шаг А В t c
(1) LOCK А 43 Bi Ci
(2) Г2: LOCK В 4® Bi Ci
(3) Т,: LOCK С 4® Bi Ci
(4) Г,; UNLOCK В А, f3 (Bi) Ci
(5) Л: LOCK В 4® f3 (Bi) Cq
(6) Т\: UNLOCK А fi (-4 о) f3 (Bq) Cq
(7) Т2: LOCK А fi (-4 о) f3 (Во) Ci
(8) Т2: UNLOCK С fi (А,) f 8 (Bq) fi (Cq)
(9) Т2: UNLOCK А fi (fl (А®)) fa (Bq) fi (Cq)
(10) Т3: LOCK 4 fi (fi (А о)) f3 (Bo) fi (Cq)
(11) Т3: LOCK С fi (fl (А о)) f3 (Bq) fi (Cq)
(12) Л: UNLOCKS fi (fi И®)) fi (fa (Bq)) fi (Cq)
(13) Т3: UNLOCK С fi (fl (-4 о)) fi (fs (Bq)) fl (fi (Cq))
(14) Т3: UNLOCKS fi (fi (fi (A0))J fi (fa (Bq)) fl (fi (Cq))
Рис. 10.4. Расписание
ключ к проверке сериализуемости. Анализируется предусмотренный в рас-
писании порядок, в котором различные транзакции блокируют данный эле-
мент. Этот порядок должен соответствовать гипотетическому эквивалентному
последовательному расписанию транзакций. Если для двух различных эле-
ментов необходимо исполнение каких-либо двух транзакций в разном поряд-
ке, то мы имеем парадокс, поскольку оба таких порядка не могут соответст-
вовать одному последовательному расписанию. Выявление этой ситуации
может быть сформулировано как задача обнаружения циклов в ориентиро-
ванном графе. Формальное описание метода ее решения дает следующий
алгоритм.
Алгоритм 10.1. Проверка сериализуемости расписания.
Входные данные. Расписание S для совокупности транзакций
Тк.
Выходные данные. Ответ на вопрос, является ли 3 сериали-
зуемым, и если да, то эквивалентное ему последовательное расписание.
Метод. Построим ориентированный граф G, называемый графом
предшествований, узлы которого соответствуют транзакциям. Определим
дуги графа G. Пусть 3 есть аг-, а2\...-, ап, где at — действие вида
Tj : LOCK Am или Т} : UNLOCK Am
и Т} указывает транзакцию, к которой относится данный шаг. Для at, име-
ющего вид
Т} : UNLOCK Am,
ищем следующее за ним действие ар вида Та: LOCK Am. Если оно существует,
то строим дугу от Т] к Та. Интуитивный смысл этой дуги заключается в
295
том, что в любом последовательном расписании, эквивалентном S,
должно предшествовать Та.
Если в графе G имеемся цикл, то 3 — не сериализуемо. При отсутствий
циклов находим такой линейный порядок транзакций, чтобы Тг предшество-
вала бы Tj всякий раз, когда существует дуга Tt->- Tj. Это всегда может
быть сделано при помощи процесса так называемой топологической сортиров-
ки, определяемого следующим образом. Из ацикличности G следует, что в
нем существует некоторый узел Tit который не имеет входящих дуг. Зане-
сем Ti в список, удалив его из графа. Процесс повторяется до тех пор, пока
в графе не останется узлов. Порядок перечисления узлов в списке дает по-
следовательный порядок транзакций.
Пример 10.6. Рассмотрим расписание, приведенное на рис. 10.4. В графе G,
изображенном на рис. 10.5, имеются узлы Tlt и Т3. Чтобы построить дуги, обратим-
ся к рис. 10.4 и рассмотрим каждый шаг UNLOCK. Например, за шагом (4) в Т2:
Рис. 10.5. Граф предше-
ствований для транзак-
ций
UNLOCK В, следует в Tt: LOCK В. В данном случае блокировка имеет место в следую-
щем шаге. Поэтому строится дуга Т2 Т2. За шагом (8) в Т2 : UNLOCK С, следует
шаг (11) в Т3. LOCK С; между ними нет иных шагов, блокирующих С. Следовательно,
строится дуга Т2 -* Т 3. Шаги (6) и (7) приводят к включению в граф дуги 7\ -» Т2.
Поскольку в графе существует цикл, расписание, представленное иа рис. 10.4, ие яв-
ляется сериализуемым.
LOCK А
UNLOCK А
Время LOCK А
UNLOCK А
1 LOCK В
UNLOCK В
LOCK В
UNLOCK В
Ti Т2 Т3
Рис. 10.6. Сериализуемое расписание
Пример 10.7. На рис. 10.6 показано расписание трех транзакций, а иа
рис. 10.7 — его граф предшествований. В силу ацикличности графа расписание иа
рис. 10.6 сериализуемо. С помощью алгоритма 10.1 определяется последовательный по-
рядок: Tlt Т2, Т3. Интересно отметить, что согласно полученному порядку 7\ предшест-
вует Т2, несмотря иа то, что на рис. 10.6 7\ не начинает исполняться до тех пор, пока
не окончится Т3.
Рис. 10.7. Граф предшествова-
ний для рис. 10.6
®-----<§}
Теорема 10.1. Алгоритм 10.1 корректно определяет, является ли
расписание сериализуемым.
Доказательство. Пусть граф предшествований G не имеет цик-
лов. Рассмотрим последовательность транзакций Tit, Tt,, .... Tir, которые
по расписанию 3 блокируют и разблокируют элемент А в указанном поряд-
296
ке. Тогда в Q существуют дуги 7\ Ttf -*• Tir. Поэтому ^именно в
этом порядке должны входить транзакции в построенное последовательное
расписание. Поскольку никакая иная транзакция не блокирует А, легко
проверить, что его значение после исполнения S является в точности таким
же, как и в результате исполнения последовательного расписания, постро-
енного по алгоритму 10.1. Так как аналогичные рассуждения справедливы
для любого элемента А, имеем в результате, что S эквивалентно построен-
ному последовательному расписанию. Таким образом, S сериализуемо.
Пусть, наоборот, в G имеется цикл Допустим,
что существует последовательное расписание R, эквивалентное S, и что в
R первой среди транзакций цикла встречается Т]р. Пусть из-за элемента
А в G имеется дуга 7'/р_1 Tj (примем /р_х равным /х для р = 1). Тогда в
R в окончательной формуле для А функция f, сопоставляемая некоторой
паре LOCK А — UNLOCK А в Tjp, применяется ранее функции g, ассоцииро-
ванной с парой LOCK Л —UNLOCK А в Tj Р так как Т;р встречается
в R раньше Тjp_ г В S тем не менее Т]р_ ] предшествует Тjp, поскольку суще-
ствует дуга Tjp_ j -> Tjp. Следовательно, в S функция g применяется ранее f.
Итак, конечные значения А в R и S различны в том смысле, что различны со-
ответствующие формулы. Отсюда мы делаем заключение, что R и S не экви-
валентны. Таким образом, S не эквивалентно никакому последовательному
расписанию, что и требовалось доказать.
Протокол, гарантирующий сериализуемость
Рассмотрим теперь простой протокол, обладающий следующим свойст-
вом: любая подчиняющаяся ему совокупность транзакций не может иметь
легального несериализуемого расписания. Более того, в некотором смысле
(обсуждаемом ниже)он является наилучшим среди возможных. Этот протокол
представляет собой просто требование, согласно которому в каждой транзак-
ции все операции блокирования должны предшествовать всем операциям раз-
блокирования L Подчиняющиеся этому протоколу транзакции называются
двухфазными. Первая фаза называется фазой блокирования, а вторая — фа-
зой разблокирования. Например, на рис. 10.3 транзакции Тг и Т3 — двух-
фазные, аТ2 — нет.
Теорема 10.2. Любое расписание S двухфазных транзакций явля-
ется сериализуемым.
Доказательство. Допустим противное. Тогда по теореме 10.1
в графе предшествований G для S найдется некоторый цикл Tit
Тip -+Тц. Это означает, что блокирование, осуществляемое Тt, по-
следует за разблокированием, осуществляемым Т\. Блокирование в тран-
закции Tt, последует за разблокированием в транзакции Tlt и т. д. И нако-
нец, блокирование в транзакции Тг произойдет после разблокирования в
транзакции Tip. Следовательно, блокирование в последует за разблокиро-
ванием в7\, что противоречит предположению о двухфазности транзакции
Как уже упоминалось, в некотором смысле двухфазный протокол — на-
илучший среди реально возможных. Точнее, можно показать, что для любой
1 Для устранения тупиков блокировки можно осуществлять в соответствий с
некоторым фиксированным линейным порядком элементов или применить какой-либо
другой метод. Здесь, однако, мы не имеем дела с тупиками.
297
транзакции Tlt не являющейся двухфазной, найдется какая-либо транзак-
ция Т2, совместно с которой 7\ сможет выполняться в несериализуемом рас-
писании. Пусть транзакция 7\ — не двухфазная. Тогда в 7\ существует шаг
UNLOCK А, предшествующий шагу LOCK В. Пусть Т2 имеет вид
Т2 : LOCK Л; LOCK В; UNLOCK Л : UNLOCK В;
Легко видеть, что расписание на рис. 10.8 не сериализуемо, поскольку
обработка А требует, чтобы Т± предшествовала Т2, в то время как обработка
В требует их обратного порядка.
LOCK Л
UNLOCK Л
LOCK Л
LOCK В
UNLOCK Л
UNLOCK В
LOCK В
UNLOCK В
Л ‘ Т2
Рис. 10.8. Несернализуемое расписание
Заметим, что существуют некоторые совокупности транзакций, подчиня-
ющиеся только последовательным расписаниям, причем не все из них явля-
ются двухфазными. В разд. 10.5 приводится важный пример такой совокуп-
ности. Однако, поскольку обычно неизвестно множество всех транзакций,
которые могут когда-либо выполняться параллельно с некоторой заданной
транзакцией, мы обычно вынуждены требовать, чтобы все транзакции были
двухфазными.
10.3. МОДЕЛЬ С БЛОКИРОВКАМИ ДЛЯ ЧТЕНИЯ И ЗАПИСИ
В разд. 10.2 предполагалось, что каждый раз, когда транзакция блоки-
рует элемент, она изменяет его значение. Зачастую на самом деле для тран-
закции необходимо лишь получить значение элемента с гарантией, что оно
не изменится. Проводя различия между доступами только для чтения и для
чтения и записи, можно разработать более детальную модель транзакций,
которая будет допускать некоторые виды параллелизма, отвергаемые в мо-
дели, рассмотренной в предыдущем разделе1. Различают два вида блокиро-
вок:
1. Блокировки для чтения. Транзакция Т, намеревающаяся только чи-
тать элемент А, выполняет RLOCK A (READ-LOCK — блокировать для чте-
ния), что препятствует записи нового значения А любой другой транзакцией
во время чтения А транзакцией Т. Однако блокировку А для чтения может
одновременно установить любое число транзакций.
2. Блокировки для записи. Имеются в виду блокировки в том смысле,
как они рассматривались в предыдущем разделе. Собирающаяся изменить
1 Заметим, что мы еще не вводим блокировок только для записи. Способность тран-
закций к записи значения элемента без предварительного его чтения рассматривает-
ся в следующем разделе и весьма усложняет вопрос о сериализуемости.
298
значение элемента А транзакция устанавливает сначала блокировку для за-
писи, выполняя WLOCK Л (WRITE-LOCK — блокировать для записи).
Когда некоторая транзакция осуществляет блокировку элемента для записи,
никакая другая транзакция не может установить для этого элемента ни бло-
кировку для чтения, ни блокировку для записи.
И блокировка для чтения, и блокировка для записи снимаются операто-
рами UNLOCK (разблокировать). Как и в разд. 10.2, здесь предполагается,
что ни одна транзакция не предпринимает попыток разблокировать элемент,
если она не осуществляет блокировку этого элемента для чтения или записи,
а также попыток установления блокировки для чтения элемента, блокировку
которого она уже осуществляет. Кроме того, транзакция не пытается блоки-
ровать элемент для записи, если она уже осуществляет такую блокировку
данного элемента. Однако при некоторых обстоятельствах она может уста-
навливать блокировку для записи элемента, который в это время блокирует-
ся ею для чтения. Последнее имеет смысл, так как блокировка для записи в
большей степени ограничивает поведение других транзакций, чем блокиров-
ка для чтения.
Два расписания эквивалентны, если
1) они продуцируют одно и то же значение для каждого элемента;
2) каждая блокировка для чтения, применяемая данной транзакцией,
встречается в обоих расписаниях, когда блокируемый элемент имеет Одно
и то же значение.
Проверка сериализуемости
Как и в предыдущем разделе, предположим, что каждый раз когда эле-
мент блокируется для записи, на его значение воздействует однозначная
функция, ассоциируемая с данной блокировкой. Напротив, значение эле-
мента не изменяется при блокировке его для чтения. Пусть имеется расписа-
ние S, в котором транзакция Т\ производит блокировку элемента А для за-
писи, a f — функция, ассоциируемая с этой блокировкой. Пусть Т2 — одна
из (возможно, многих) транзакций, которые устанавливают блокировку А
для чтения после разблокирования его транзакцией Ти прежде чем какая-
либо иная транзакция блокирует этот элемент для записи. Тогда 1\, несомнен-
но, должна предшествовать Т2 в любом последовательном расписании, экви-
валентом S. В противном случае Т2 будет читать значение А, на которое не
воздействовала функция f, и ни одно такое значение не будет идентично зна-
чению, на которое все-таки воздействовала f. Аналогичным образом, если
Т3—следующая после 7\ транзакция, устанавливающая блокировку А для
записи, то 7\ должна предшествовать Т3. По существу, это и есть аргумент
теоремы 10.1.
Пусть теперь транзакцией, блокировавшей элемент А для чтения до
того, как он был заблокирован 7\ для записи, оказалась 7\. Если в последо-
вательном расписании встречается ранее Т\, то последняя читает значе-
ние А с учетом f, тогда как в расписании S читаемое 7\ значение не учиты-
вает f. Поэтому в последовательном расписании 7\ должна предшествовать
Тг. Мы не можем, однако, утверждать, что две транзакции, которые в рас-
писании S в некотором порядке осуществляют блокировку одного и того же
элемента А для записи, должны следовать в том же порядке и в последова-
тельном расписании. В действительности все происходит наоборот. Относи-
тельный порядок блокировок для чтения вместе с тем не оказывает никакого
влияния на значения, продуцируемые параллельно исполняемыми транзак-
циями. Эти соображения наводят на мысль, что подход, подобный рассмот-
299
ренному в разд. 10.2, позволит нам определять, является ли расписание сери-
ализуемым.
Алгоритм 10.2. Проверка сериализуемости расписаний с блоки-
ровками для чтения/записи.
Входные данные. Расписание S для совокупности транзакций
Л, .... П-
Выходные данные. Ответ на вопрос, является ли S сериали-
зуемым, и если да, то эквивалентное последовательное расписание.
Метод. Строим граф предшествований G следующим образом. Узлы,
как и прежде, соответствуют транзакциям. Дуги определяются следующими
правилами:
1. Пусть в S транзакция Tt устанавливает блокировку элемента А
для чтения, a Tj — следующая за ней транзакция (если она существует) —
устанавливает блокировку А для записи. Тогда строим дугу из Tt в Tj.
2. Пусть транзакция Tt в S блокирует А для записи, a Tj — следующая
за ней (если, конечно, таковая существует) транзакция — устанавливает
блокировку А для записи. Тогда строим дугу Тг -> Tj. Пусть далее Тт —
какая-либо транзакция, блокирующая А для чтения после того, как Tt сни-
мает свою блокировку для записи, но перед тем, как Tj устанавливает блоки-
ровку А для записи. (Если Tj не существует, то Тт — любая транзакция,
которая блокирует А для чтения после того, как Ti разблокирует его.)
Тогда строим дугу Тт.
Если граф G имеет циклы, toS не сериализуемо. Если же G ацикличен, то
любая его топологическая сортировка определит последовательный порядок
для транзакций.
Пример 10.8. На рис. 10.9 показано расписание четырех транзакций, а иа
рис. 10.10— соответствующий граф предшествований. Первый оператор UNLOCK вы-
полняется на шаге 3, когда Г- снимает свою блокировку элемента А для записи. За
шагом 3 следуют блокировки А для чтения транзакциями Тг и Т2 (шаги 4 и 7) и блоки-
ровка этого элемента для записи транзакцией 7\ на шаге 12. Таким образом, Т1г Т2 и
должны следовать за Т3, и мы строим дуги нз Т3 в каждый из перечисленных узлов.
Обратим внимание на то, что после шага 7 транзакции 7\ и Т2 осуществляют блоки-
ровку элемента А для чтения, и в этом нет никакой ошибки. Однако 7\ не сможет уста-
новить блокировку А для записи до тех пор, пока этн транзакции не снимут свои бло-
кировки для чтения. В связи с тем что 7\ снимает блокировку В для записи на шаге 5,
а следующую блокировку В для записи устанавливает Т3, строится дуга из Tt в Т3.
Образуется цикл, свидетельствующий о том, что расписание, приведенное на рис. 10.9,
не является сериализуемым. Полная совокупность дуг показана на рис. 10.10.
(1) WLOCK А
(2) RLOCK В
(3) UNLOCK А
(4) RLOCK А
(5) UNLOCK В
(6) WLOCK В
(7) RLOCK А
(8) UNLOCK В
(9) WLOCK В
(10) UNLOCK А
(11) UNLOCK А
(12) WLOCK А
(13) UNLOCK В
(14) RLOCK В
(15) UNLOCK А
(16) UNLOCK В
Л т* Тз Л
Рис. 10.9. Расписание четырех транзакций
300
Теорема 10.3. Алгоритм 10.2 корректно определяет, является ли
расписание S сериализуемым.
Доказательство. Нетрудно показать, что всегда, когда мы име-
ем дугу из Ti в Tj в графе предшествований, транзакция Tt в любом экви-
валентном последовательном расписании должна предшествовать Tj. Таким
образом, если в G существует цикл, то, как и в теореме 10.1, можно доказать,
что никакого эквивалентного последовательного расписания для S не суще-
ствует. Пусть, наоборот, в графе G нет циклов. Тогда из аргумента, подоб-
ного приведенному в теореме 10.1, следует, что конечное значение каждого
элемента идентично для S и для последовательного расписания R, построен-
ного с помощью топологической сортировки G. Остается доказать лишь, .что
при соответствующих блокировках для чтения элемент А имеет одинаковые
Рис. 10.10. Граф предше-
ствований для рис. 10.9
значения в R и S. Это легко доказывается, поскольку дуги графа G гаранти-
руют, что блокировки элемента А для записи, предшествующие данной бло-
кировке его для чтения, являются одинаковыми в 7? и S и порядок их следо-
вания в обоих расписаниях идентичен.
Двухфазный протокол
Как и в модели из предыдущего раздела, достаточной гарантией сериа-
лизуемости является двухфазный протокол, в соответствии с которым уста-
новление блокировок для чтения и записи предшествует всем операторам
разблокирования. Более того, справедливо и обратное утверждение, а имен-
но, что для любой транзакции, в которой некоторый оператор UNLOCK
предшествует установлению блокировки для чтения или записи, существует
несериализуемое расписание, предусматривающее ее параллельное исполне-
ние с некоторой другой транзакцией. Доказательство этих результатов мы
предоставляем читателю в качестве упражнения.
10.4. МОДЕЛЬ «ТОЛЬКО ЧТЕНИЕ / ТОЛЬКО ЗАПИСЬ»
В разд. 10.2 и 10.3 было сделано предположение с далеко идущими по-
следствиями, согласно которому, прежде чем записать новое значение для
некоторого элемента А, транзакция предварительно читает его значение, и,
что еще важнее, новое значение А зависит от старого. Это предположение
встроено в определение понятия «значения» в предыдущем разделе. Более ре-
алистическая модель должна основываться на предположении, что транзак-
ция читает множество элементов {множества-чтения) и записывает множест-
во элементов {множества-записи). При этом элемент А может входить либо
в одно из этих множеств, либо в оба.
Например, любая транзакция, которая обращается с запросом к базе
301
данных, но не вносит в нее изменений, имеет пустое множество-записи1.
Для транзакции
READ A; READ В; С: = А + В; А : = А — 1; WRITE С; WRITE А;
множеством-чтения является {А, В}, а множеством-записи — {А, С}.
Эквивалентность расписаний
Если допускается только запись элементов, мы должны пересмотреть на-
ше представление об эквивалентности двух расписаний. Рассматриваемый
случай имеет важную отличительную особенность. В контексте модели из
разд. 10.3 допустим, что транзакция Тх записала значение элемента А, а поз-
же его записала транзакция Т2. В разд. 10.3. предполагалось, что в этом слу-
чае Т2 блокирует А после того, как его разблокирует 7\, и предположитель-
но использует прежнее значение А для вычисления его нового значения, по-
скольку относительно ассоциируемой с блокированием-разблокированием
элемента А функции предполагается, что она вырабатывает различные
новые значения А для разных старых его значений. Следовательно, при рас-
смотрении вопроса о сериализуемости считается само собой разумеющимся,
что в последовательном расписании 7\ должно предшествовать Тг и к тому же
между 7\ и Т2 не может выполняться никакая другая транзакция Т, блоки-
рующая элемент А для записи. В алгоритме 10.2 последнее условие обеспе-
чивается «бесплатно», так как этот алгоритм приводит к тому, что в последо-
вательном расписании Т появляется либо перед Tlt либо после Т2, независи-
мо от того, какой случай имел место в заданном расписании S.
Если предположить, однако, что транзакция Т2 записала свое значение
А без чтения этого элемента, то новое значение А будет зависеть не от старого
значения, а лишь от значений элементов, которые фактически были прочита-
ны этой транзакцией. Таким образом, если в промежутке между теми момен-
тами, когда Tt и Т2 записывали свои значения А, никакая другая транзакция
не читала Л, то записанное транзакцией 7\ значение «утрачивается» и не ока-
зывает какого-либо влияния на базу данных. Вледствие этого нет необхо-
димости в том, чтобы в последовательном расписании Т± предшествовала Т2
(по крайней мере, это касается элемента Л). Фактически к Тг предъявляется
единственное требование — она должна завершиться к тому моменту, когда
некоторая другая транзакция Т3 начнет позднее записывать Л, причем в про-
межутке между моментами записи Л транзакциями 7\ и Т3 ни одна транзак-
ция не может его читать.
Сформулируем теперь новое определение сериализуемости с позиций
введенной концепции, которая предусматривает, что записываемые транзак-
цией значения зависят только от читаемых ею значений и что из различных
читаемых значений продуцируются разные записываемые значения. Нефор-
мально (и не совсем точно) эти условия определяются следующим образом.
Если в расписании S транзакция Т2 читает Значение элемента Л, записан-
ное транзакцией Тъ то 1) 7\ должна предшествовать Т2 в любом последова-
тельном расписании, эквивалентном S; 2) если Т3 — транзакция, записыва-
ющая Л, то в любом эквивалентном S последовательном расписании эта
транзакция может либо предшествовать Тъ либо следовать за Т2, но не может
выполняться между 7\ и Т2.
Для того чтобы приведенное определение стало строгим, нужно упомя-
нуть еще о двух деталях. Во-первых, существуют «граничные эффекты»,
1 Напротив, если существен порядок, в котором производятся ответы на запросы,
то можно рассматривать устройство вывода как элемент в множестве-записи запроса.
302
связанные с чтением элемента перед тем, как его запишет какая-либо тран-
закция, или с записью элемента, который никогда больше не будет модифи-
цироваться. Эти эффекты можно учесть, если постулировать существование
начальной транзакции То, которая записывает каждый элемент, не читая ни
одного из них, и финальной транзакции Tf, которая читает каждый элемент,,
ни одного из них не записывая.
Во-вторых, нужно сделать уточнение, касающееся транзакций Т, ре-
зультат исполнения которых является «невидимым» в том смысле, что лю-
бое значение, записываемое Т, не оказывает никакого влияния на значение,
читаемое Tf. Заметим, что здесь имеется в виду не обязательно непосредст-
венное влияние. Такое влияние может быть следствием цепочки, в которой
некоторая транзакция Т' читает записанное Т значение, затем Т“ читает зна-
чение, записанное Т', и т. д. до тех пор, пока не будет выполнена транзак-
ция, записывающая значение, читаемое Tf. Назовем транзакцию, не оказы-
вающую влияние на Tf, бесполезной. Второе уточнение приведенного выше
определения должно исключить возможность того, чтобы в п. 1 и 2 транзак-
ция Т2 была бесполезной х.
Проверка бесполезности транзакций
При заданном расписании S нетрудно определить, какие транзакции
оказываются бесполезными. Построим граф с узлами-транзакциями, включая
фиктивную транзакцию Tj, о которой предполагается, что она находится в
конце S. Если записывает значение, читаемое Т2, строим дугу из Тг в Т2.
Тогда бесполезными окажутся только те транзакции, из которых нет пути
ъ Tf. Пример такого алгоритма будет приведен после обсуждения проверки
сериализуемости.
Формальная модель
Как и в разд. 10.3, будем считать транзакцию последовательностью ша-
гов RLOCK А (заблокировать элемент А для чтения), WLOCK А (заблоки-
ровать элемент А для записи) и UNLOCK А (разблокировать элемент Л)..
Как и прежде, здесь предполагается, что транзакции не пытаются разбло-
кировать элементы, блокировку которых для чтения или записи они в дан-
ный момент не осуществляют. Предполагается, кроме того, что транзакции
не могут блокировать элементы, блокировку которых они уже осуществля-
ют. Исключение составляют случаи, когда транзакция, осуществляющая
блокировку элемента для чтения, вправе блокировать его для записи или на-
оборот. Единственное существенное различие между этой и ранее представ-
ленной моделью заключается в семантике. Здесь допускается, что, блоки-
руя элемент для записи, транзакция не читает его значения (если она не бло-
кирует его еще и для чтения), тогда как ранее мы предполагали, что блоки-
ровка для записи предусматривает и привилегии для чтения, а фактически
также обязательство читать и использовать прочитанное значение.
Проверка сериализуемости
В данном случае нам не поможет простой граф предшествований.
Напомним, что в рассматриваемой модели имеются два типа ограничений на
возможные последовательные расписания, эквивалентные заданному распи-
1 Просто устранить бесполезные транзакции из S невозможно, потому что зани-
мающаяся планированием транзакций часть системы априори не умеет распознавать,
какие из включаемых в расписание транзакций окажутся далее бесполезными.
303
санию S. Ограничения типа, 1 состоят в том, что если Т2 читает значение Л,
записанное Tlt то Тг обязательно предшествует Т2 в любом последователь-
ном расписании. Такой тип ограничений графически может выражаться ду-
гой из Тх в Т2. Ограничения типа 2 заключаются в том, что всякая транзак-
ция Т3, записывающая А, должна выполняться либо до Тх, либо после Т2.
Это ограничение нельзя представить обычной дугой. Скорее, мы имеем пару
дуг Т3-+ 7\ и 72->- Т3, одну нз которых следует выбрать. Расписание S
является сериализуемым, если и только если в результате выбора из каждой
такой пары мы получим ацикличный граф.
Совокупность узлов, дуг и пар альтернативных дуг называется полигра-
фом. Полиграф ацикличен, если существует некоторая последовательность
выборов одной дуги из каждой пары, в результате которой получится граф,
ацикличный в обычном смысле. Проверка сериализуемости расписания для
рассматриваемой модели сводится к тому, чтобы построить некоторый поли-
граф и убедиться в его ацикличности. К сожалению, проверка полиграфа
на ацикличность представляет собой весьма трудную задачу. Ее NP-полно-
та показана Пападимитриу, Бернштейном и Ротни [130].
Алгоритм 10.3. Проверка сериализуемости расписания транзак-
ций с блокировками только для чтения и только для записи.
Входные данные. Расписание S совокупности транзакций 7\,
Т3.... Tk.
Выходные данные. Ответ на вопрос, является ли S сериализу-
емым, и если да, то эквивалентное ему последовательное расписание.
Метод.
1. Дополняем в начало S последовательность шагов, в которых фиктив-
ная транзакция Т3 записывает каждый элемент, встречающийся в S. В кон-
це расписания также добавляем последовательность шагов, в которых фик-
тивная транзакция Tf, читает каждый такой элемент.
2. Начинаем построение полиграфа Р, включая в него по одному узлу
для каждой транзакции, в том числе для То и Tf. Временно помещаем в Р ду-
гу Tt -> Tj всякий раз, когда Tj читает элемент А, который был последним
записан транзакцией Ti в расширенном расписании S.
3. Находим бесполезные транзакции. Транзакция Т бесполезна, если
не существует пути из Т в Tf.
4. Для каждой бесполезной транзакции Т исключаем все дуги, входящие
в Т.
5. Для каждой оставшейся дуги Tt -+ Tj и для каждого элемента А,
значение которого, записанное Tt, читает Tj, рассмотрим все остальные тран-
закции Т =/= То, тоже записывающие значения этого элемента. При Tt =
= То и Tj = Tf мы не добавляем никаких дуг. Когда Tt = То, но Tj
Ф Tj, добавляем дугу Т} -> Т. Если Tj — Tf, но Tt =# То, добавляем ду-
гу Т Tt. При Tt #= Т3 и Tj=/= Tf вводим пару дуг (7Ть Tj-+ Т).
6. Выясняем, ацикличен ли полученный в результате полиграф Р. Для
этого шага нет лучшего метода, чем полный перебор. При наличии в полигра-
фе п пар альтернативных дуг испытываем все 2" вариантов выбора альтерна-
тив с тем, чтобы оценить, является ли результат ацикличным графом1.
Пусть Р — ацикличен и G — ацикличный граф, сформированный из Р пу-
1 Очевидно, можно придумать некоторые эвристические Правила, упрощающие эту
работу. Например, если выбор одной дуги из некоторой пары дуг приводит к циклу с
существующими дугами, то следует выбрать другую дугу в рассматриваемой паре.
Одиако бывают случаи, когда ни одна дуга из пары непосредственно цикла не вызывает,
а все же выбор какой-то из иих отрицательно сказывается где-либо на последующих
стадиях при выборе дуг из других пар.
304
тем выбора некоторой дуги из каждой пары. Тогда любая топологическая
сортировка G с удалением фиктивных транзакций То и Tf представляет
последовательное расписание, эквивалентное S. Если же Р не обладает свой-
ством ацикличности, то последовательного расписания, эквивалентного S,
не существует.
Пример 10.9. Рассмотрим расписание, представленное на рис. 10.11. Дуги,
построенные иа шаге 2 алгоритма 10.3, изображены иа рис. 10.12. Каждая дуга поме-
(1) RLOCK А
(2) RLOCK А
(3) WLOCK С
(4) UNLOCK С
(5) RLOCK С
(6) WLOCK В
(7) UNLOCK В
(8) RLOCK В
(9) UNLOCK А
(Ю) UNLOCK А
(П) WLOCK А
(12) RLOCK С
(13) WLOCK D
(14) UNLOCK В
(15) UNLOCK С
(16) RLOCK В
(17) UNLOCK А
(18) WLOCK А
(19) UNLOCK В
(20) WLOCK В
(21) UNLOCK В
(22) UNLOCK D
(23) UNLOCK С
(24) UNLOCK А
Л Т’г т3 Т<
Рис. 10.11. Расписание
чена для ясности элементом или элементами, оправдывающими ее присутствие в графе.
Уяснение принципов построения графа на рис. 10.12 помогает прежде всего обнару-
жить, что расписание на рис. 10.11 является легальным в том смысле, что никакие две
транзакции не устаианливают блокировок для записи или для записи и чтения одновре-
менно. Таким образом, мы можем считать, что все операции чтения и записи осуществ-
ляются в то время, когда осуществляется соответствующая блокировка, и можно игно-
рировать шаги UNLOCK (разблокировать).
Рис. 10.12. Первый шаг в построении полиграфа
Рассмотрим поочередно каждую блокировку для чтения. Такие блокировки эле-
мента А иа шагах 1 и 2 будут обеспечивать чтение значения, «записанного» фиктивной
транзакцией То. Поэтому строятся дуги из То в Тг и Т«. Шаг 5 предусматривает чтение
значения С транзакцией Т3, записанного Тг на шаге 3. Поэтому мы имеем дугу 7\ Т3.
На шаге 8 транзакция Tt читает то, что Тг записала иа шаге 6. Таким образом, появля-
ется дуга Ti -» Tt и т. д. Наконец, Tf «читает» А, В, С и D, значения которых послед-
11 Зак. 1315
305
ними записали транзакции Tt, Tt, 7\ и Т2 соответствеиио. Этим объясняется включе-
ние в граф трех дуг, входящих в узел Ту.
Теперь попытаемся иайти бесполезные транзакции. Для них на рис. 10.12 иет
пути к Tf. Единственной такой транзакцией оказывается Т3. Поэтому удалим дугу
71 -► Т3 из графа.
На шаге 5 алгоритма 10.3 мы рассматривали дуги или пары дуг, необходимые для
предотвращения помех, создаваемых одной операцией записи для другой. Элементы,
значения которых, подобно С и D, записываются лишь одной иефиктивиой транзакци-
ей, иа этом шаге не фигурируют. Однако значение элемента А записывается не только
двумя транзакциями Т3 и Т4, но и фиктивной транзакцией То. Значение, которое запи-
сывает Т3, не читает ни одна транзакция. Поэтому Tt не должна занимать какую-либо
конкретную позицию относительно Т 3. Значение, записываемое транзакцией Т4, «чи-
тает» Tf. Таким образом, поскольку Т3 ие может исполняться после Tf, она должна
следовать до Т4. В этом случае ие требуется никакой пары дуг. К графу Р просто до-
бавляется дуга Т3 -► Т4. Значение А, которое записывает Т3, читают Тг и Т2. Так как
невозможно, чтобы Т3 и Т4 выполнялись ранее Т3. добавляются дуги из Тг и Т2 в 7'3
и Т4. Здесь снова нет необходимости в паре дуг.
Рис. 10.13. Окончательный вид полиграфа
Элемент В записывают транзакции Т2 и Т'4. При этом значение В, которое запи-
сывает Т4, читает только Tf. Следовательно, необходима дуга Тг Т4. В то же время
значение В, записываемое Тг, читают Т2 и Т4. Запись В транзакцией Т4 не создает помех
чтению В этой же транзакцией. Таким образом, ие требуется, чтобы *Т3 предшество-
вала 7\ или следовала за Т\». Одиако Tt ие должна вставляться между Т2 и Т2. Поэто-
му нужно добавить пару дуг (7'4 -► Т1г Т2 -* Т4). Полученный в результате полиграф
показан на рис. 10.13, где одна из пар дуг выделена пунктиром. Заметим, что удален-
ная иа шаге 4 дуга Т\ -► Т3 возвращена иа шаге 5.
Если из пары выбрать дугу Т3 -► Т2, то мы получим цикл. Выбирая, одиако,
вместо этого Т2 Т4, имеем ацикличный граф, который дает иам последовательный
порядок транзакций Tlt Т2, Т3, Т4. Таким образом, расписание, представленное иа
рис. 10.11, сериализуемо.
Теорема 10.4. Алгоритм 10.3 корректно определяет, является ли
расписание сериализуемым.
Доказательство. Ограничимся здесь лишь краткой схемой до-
казательства. Предположим сначала, что полиграф ацикличен, т. е. сущест-
вует некоторый вариант выбора дуги из каждой пары, который дает в ре-
зультате ацикличный граф G. Построение графа Р, проведенное в соответст-
вии с алгоритмом 10.3, гарантирует, что любая небесполезная транзакция,
включая Tf, читает ту же самую копию каждого элемента в S, что и в после-
довательном расписании, получаемом в результате топологической сорти-
ровки G. Таким образом, соответствующие значения, получаемые для каждо-
го элемента, идентичны при обоих расписаниях.
Пусть, наоборот, существует последовательное расписание S', эквива-
лентное S. Тогда согласно аргументам, приведенным в теореме 10.1, Т[ долж-
на предшествовать 7\ в S', если Tt -м Т} оказывается дугой, введенной на
шаге 2 и не удаленной на шаге 4. Пусть на шаге 5 в граф включена пара дуг
(Тп -> Ti, Tj-*~ Тп). Тогда Тп не может находиться между Tt и Tj в S'.
Из этой пары выберем дугу Тп -* Т{, если Тп предшествует Т, в S', или
Tj-+ Тп — в противном случае. Линейный порядок, предполагаемый рас-
писанием S', не будет противоречить такому выбору из пар дуг. Аналогично
306
одиночные дуги, добавляемые на шаге 5, заведомо не должны порождать про-
тиворечий с этим линейным порядком. Таким образом, существует конст-
руктивный способ выделения ацикличного графа из полиграфа Р, базирую-
щийся на расписании S'.
Снова двухфазный протокол
Как и для ранее рассмотренных моделей, двухфазный протокол, тре-
бующий от каждой транзакции, чтобы она выполняла все блокирования пе-
ред всеми разблокированиями, служит достаточной гарантией сериализуе-
мости любого легального расписания. Чтобы убедиться в этом, предположим,
что S — легальное расписание транзакций, подчиняющихся двухфазному
протоколу. Пусть, кроме того, (Та-+ Tlt Та-+ Т а) — пара дуг в полиграфе
р. Тогда найдется некоторый элемент А, такой, что Та читает копию А, за-
писанную 7\. Если в расписании S транзакция Т8 разблокирует А прежде,
чем Tj установит блокировку его для чтения, то из этой пары выберем дугу
Та-+ Л. Если же Та блокирует А для записи после снятия блокировки это-
го элемента транзакцией Та, то выберем дугу Та Та. Никаких других воз-
можностей не существует, так как эта пара дуг была включена в Р алгорит-
мом 10.5.
Обратимся теперь к графу G, построенному из Р. Пусть в G имеется цикл
Tj -+ Та -+ ... -> Тп-+ Tj. Заметим, что никакая фиктивная транзакция,
конечно, не может быть составной частью какого-либо цикла. Анализ алго-
ритма 10.5 и рассмотренных выше правил конструирования графа G из Р
показывает, что для каждой дуги Tt -+ Ti+1 (здесь Тп+1 = Т±) данного цик-
ла найдется элемент такой, что в S транзакция Tt разблокирует At перед
блокированием этого элемента транзакцией T,+i. Согласно двухфазному про-
токолу Ti+j должна снять блокировку Аг+1 после того, как она установит
блокировку At. Таким образом, Tj разблокирует Aj прежде, чем Тп+1
заблокирует Ап. Но Tn+i~ Tj, и двухфазный протокол запрещает 7\ раз-
блокировать Aj прежде , чем она заблокирует Ап. Таким образом, мы можем
считать, что доказана следующая теорема.
Теорема 10.5. Для модели, рассмотренной в настоящем разделе, с
транзакциями, подчиняющимися двухфазному протоколу, каждое легаль-
ное расписание является сериализуемым.
10.5. ПАРАЛЛЕЛЬНЫЙ ДОСТУП К ИЕРАРХИЧЕСКИ
СТРУКТУРИЗОВАННЫМ ЭЛЕМЕНТАМ
Во многих случаях совокупность элементов, к которым транзакция осу-
ществляет доступ, может естественным образом рассматриваться как дере-
во или лес. Приведем несколько примеров.
1. Элементы являются экземплярами логических записей (экземпляра-
ми сегментов — см. гл. 8) в базе данных, структуризованной согласно иерар-
хической модели.
2. Элементы являются узлами В-дерева (см. разд. 2.4).
3. Определенные элементы, имеющие различные размеры, причем мень-
шие элементы вложены в более крупные. В частности, реляционная база
данных могла бы иметь элементы на четырех уровнях:
а) база данных в целом;
б) каждое отношение;
в) каждый блок, в котором хранится файл, соответствующий отноше-
нию;
11* 307
г) каждый кортеж.
При блокировке элементов можно придерживаться двух разных страте-
гий. Во-первых блокировка элемента может предполагать и блокировку
всех элементов, являющихся его потомками. Такая стратегия экономит вре-
мя, поскольку она исключает блокировки многих мелких элементов. Так, в
приведенном выше примере 3 транзакция, которая должна читать все от-
ношение, может блокировать его в целом, а не отдельно каждый кортеж.
Другая стратегия заключается в том, чтобы блокировать элемент без каких-
либо предположений относительно блокировки его потомков. Например,
при осуществлении поиска в В-дереве мы читаем узел и выбираем для сле-
дующего чтения одного из его сыновей. При чтении узла нет необходимости
в блокировании всех его потомков. Оказывается, что приемлемый протокол
для стратегии блокирования отдельных элементов объяснить легче, чем про-
токол для стратегии блокирования поддеревьев. Поэтому рассмотрим снача-
ла блокирование отдельных элементов.
Простой протокол для дерева элементов
Вернемся снова к модели из разд. 10.2, используя только операции
LOCK и UNLOCK L Предположим, что блокировка элемента (узла дерева)
не приводит к автоматической блокировке каких-либо его потомков. Как и в
разд. 10.2, блокировать элемент может одновременно только одна транзак-
ция. Будем говорить, что транзакция подчиняется протоколу для дерева,
если за исключением первого заблокированного элемента (который не обяза-
тельно должен быть корнем) ни один элемент
(jf\ нельзя заблокировать, пока осуществляется
блокировка узла, являющегося его отцом.
/ Заметим, что транзакция, подчиняющаяся
_/ (С^) протоколу для дерева, не обязательно должна
(в) быть двухфазной. Так, она может заблокиро-
/\ вать элемент А, затем заблокировать его сына
/ \ В, снять блокировку А и заблокировать эле-
/ мент С, являющийся сыном В. Это — весьма
{Е} реалистичная ситуация, например, для слу-
ч-/ чая> когДа транзакция выполняет операцию
/ \ включения в В-дерево. Если В служит узлом
/ \_ В-дерева, которое имеет пространство еще для
(5) одного указателя, то мы знаем, что ни в какой
реструктуризации этого дерева после включе-
ния узла не может участвовать отец элемента
Рис. 10.14. Иерархия элементов В. Таким образом, после просмотра В мож-
но снять блокировку его отца — элемента А,
допуская тем самым параллельные обновления В-дерева, затрагивающие
потомков А, не являющихся потомками В.
Пример 10.10. На рис. 10.14 показано дерево элементов, а на рис. 10.15 —
расписание трех транзакций Tlt Т2 и Т3, подчиняющихся протоколу для дерева. Отме-
тим, что транзакция 7\ не является двухфазной, поскольку она блокирует С после сня-
тия блокировки В.
Хотя мы и не приводим здесь доказательства (его можно найти в работе
Зильбершаца и Кедема [154]), любое легальное расписание транзакций,
1 Обсуждаемый здесь протокол можно обобщить также на более сложные модели
из разд. 10.3 и 10.4.
308
подчиняющихся протоколу для дерева, сериализуемо. Алгоритм построе-
ния последовательного порядка транзакций начинается с создания узла в
графе для каждой транзакции. Пусть Tt и Т} представляют собой транзакции,
которые блокируют один и тот же элемент (конечно, в различное время).
Пусть далее FIRST (Т) — первый из элементов, блокируемых транзакцией
(1) LOCK А (2) LOCK В (3) LOCK D (4) UNLOCK В
(5) LOCK В
(6) LOCK С (7) LOCK £
(8) UNLOCK D
(9) (10) UNLOCK A LOCK F
(11) LOCK G
(12) UNLOCK C (13) UNLOCK £
(14) LOCK £
(15) UNLOCK F
(16) UNLOCK В
(17) UNLOCK G
(18) UNLOCK £
T’a T3
Рис. 10.15. Расписание транзакций, удовлетворяющих протоколу для дерева
Т. При независимости FIRST (Тг) и FIRST (Т}) (когда ни один из них не
является потомком другого) протокол для дерева гарантирует, что Tt и
Тj не блокируют какого-либо общего узла и не нужно строить дуги между
ними. Предположим поэтому, не теряя общности, что FIRST (7\) является
предком FIRST (Т>). Если Т( блокирует FIRST (Ту) перед тем, как это дела-
ет Tj, строим дугу Tt -> Tj. В против-
ном случае строим дугу Т} -► Tt. ______Ст\
Можно показать, что полученный в
результате граф не имеет циклов и любая
топологическая сортировка этого графа Рис 1016 Граф предШеСТвований
даст последовательный порядок транзак- для рис. 10.15
ций. Интуитивной основой доказательства
служит то, что у каждой транзакции всег-
да имеется граница, образованная самыми низшими узлами в дереве, на
которые она установила блокировку. Протокол для дерева гарантирует,
что такие границы не могут пересекать одна другую. Поэтому, если
граница для транзакции Tt начинается выше границы для транзакции
1}, то так и должно быть, и каждый элемент, блокируемый обеими транзак-
циями Tt и Т}, сначала будет блокироваться транзакцией Т}.
Пример 10.11. Из расписания, представленного на рис. 10.15, имеем:
FIRST (Л) = A, FIRST (Г2) = В, FIRST (Т3) = £.
Обе транзакции Тг и Т2 блокируют В, причем первой это делает Tj. Поэтому
строится дуга Тг -* Т2. Кроме того, каждая из транзакций Т2 и Т3 блокирует £, при-
чем Та предшествует в этом Т2. Итак, получаем дугу Т3 Т2. Граф предшествова-
ний для этого расписания изображен иа рис. 10.16. Нетрудно видеть, что существуют
два возможных последовательных расписания, а именно: 71, Т3, Т2 и Т3, Т1г Тг.
309
Протокол, допускающий блокировки для поддеревьев
В некоторых случаях элементы иерархии являются подмножествами
других элементов, как в рассмотренном выше примере иерархической струк-
туры: база данных — отношения — блоки 1 — кортежи. В таких случаях
удобно предположить, что при блокировании элемента блокируются и все
его потомки. Так, если транзакция должна блокировать большую часть или
все кортежи отношения, она может также блокировать и само отношение.
Если блокировать отношение в целом, то ценою возможного исключения
каких-либо параллельных операций над отношением система будет выпол-
нять значительно меньшую работу, связанную с блокированием и разбло-
кированием элементов.
Однако в результате такого недифференцированного блокирования мож-
но получить расписание, не являющееся легальным, в котором две транзак-
ции, по существу, устанавливают блокировку одного и того же элемента в од-
но и то же время. Например, пусть на рис. 10.14 транзакция Т1 блокирует
Е (а, следовательно, по нашим новым предположениям, также и F, и G).
Пусть далее блокирует В, порождая тем самым конфликтную ситуацию
в связи с необходимостью блокирования Е, F и G. Для исключения таких
конфликтов разработан протокол, в соответствии с которым транзакция не
может блокировать какой-либо элемент, если она сначала не установит
«предупреждение» для всех его предков. Предупреждение, установленное для
элемента А, предотвращает его блокировку любой другой транзакцией, хотя
и не препятствует установке предупреждения для А или блокированию не-
которых его потомков, не имеющих предупреждения.
Мы рассмотрим здесь транзакции, состоящие из следующих операций:
1. LOCK, которая блокирует элемент и всех его потомков. Никакие две
транзакции не могут блокировать какой-либо элемент одновременно.
2. WARN, устанавливающая «предупреждение» для элемента. Ни одна
транзакция не может блокировать элемент, для которого установила преду-
преждение другая транзакция.
3. UNLOCK, снимающая с элемента либо блокировку, либо предупреж-
дение, либо и то и другое.
Транзакция подчиняется протоколу с предупреждениями на иерархии
элементов в том случае, когда
1) она начинается с установки блокировки или предупреждения для
корня;
2) она не устанавливает ни блокировки, ни предупреждения для эле-
мента, не установив к этому моменту предупреждения на его отца2;
3) она не снимает ни блокировки, ни предупреждения, не установив ка-
ких-либо блокировок или предупреждений для его сыновей;
4) она подчиняется двухфазному протоколу в том смысле, что снятия
всех блокировок следуют за всеми установками блокировок и предупрежде-
ний.
Пример 10.12. На рис. 10.17 показана иерархия элементов, а на рис. 10.18 —
расписание трех транзакций, подчиняющихся протоколу с предупреждениями. Обра-
тим внимание иа то, что на шаге 4, в частности, 7\ устанавливает предупреждение для
В. Поэтому у Та иет возможности блокировать В до тех пор, пока Т± ие снимет свое
предупреждение для В иа шаге 10. Тем не менее на шагах 1—3 все три транзакции уста-
навливают предупреждение для А, что допустимо.
1 Здесь «блок» означает множество кортежей отношения. — Примеч. ред.
2 Отметим, что нет никакой необходимости блокировать элемент, если уже уста-
новлена блокировка его отца.
310
Устанавливая на шаге 5 блокировку С, транзакция Т3 неявво блокирует С, F и
G. Предполагается, что Т3 изменяет значения всех этих элементов или некоторых из
них прежде, чем она снимет блокировку на шаге 7.
Теорема 10.6. Расписания, подчиняющиеся протоколу с преду-
преждениями, сериализуемы.
Доказательство. Пункты 1—3 протокола с предупреждениями
гарантируют, что никакая транзакция не может блокировать элемент, если
она не установила предупреждения для всех
его предков. Из этого следует, что две тран-
закции никогда не могут одновременно бло-
кировать двух предков одного и того же
элемента. Теперь можно показать, что рас-
писание, подчиняющееся протоколу с пре-
дупреждениями, эквивалентно расписанию,
используемому в модели из разд. 10.2, в
которой все элементы блокируются явным Рнс. 10.17. Иерархия элементов
способом, в отличие от неявного, осущест-
вляемого путем блокирования предков. Если задано расписание S, подчиняю-
щееся протоколу с предупреждениями, построим расписание S' в соответ-
ствии с моделью из разд. 10.2. Для этого поступим следующим образом:
1. Исключим все шаги, устанавливающие предупреждения, и соответ-
ствующие им шаги снятия предупреждений.
(1) WARN А
(2) WARN A
(3) WARN A
(4) WARN В
(5) LOCK C
(6) LOCK D
(7) UNLOCK C
(8) UNLOCK D
(9) UNLOCK A
(10) UNLOCK В
(И) LOCK В
(12) WARN C
(13) LOCK F
(14) UNLOCK A
(15) UNLOCK В
(16) UNLOCK F
(17) UNLOCK C
(18) UNLOCK A
7’1 Т»
Рис. 10.18. Расписание транзакций, удовлетворяющих протоколу с предупреждениями
2. Заменим все блокировки блокировками элемента и всех его потом-
ков. То же самое проделаем с соответствующими операциями снятия блоки-
ровок. Полученное в результате такой процедуры расписание S' оказывает-
ся легальным в силу п. 1—3 протокола с предупреждениями, а планируемые с
его помощью транзакции являются двухфазными, так как транзакции в
S — также двухфазные в соответствии с п. 4 протокола с предупреждения-
ми.
10.6. ЗАЩИТА ОТ ОТКАЗОВ
До сих пор предполагалось, что каждая транзакция исполняется удач-
но вплоть до своего завершения. На практике, однако, различные обстоя-
тельства могут препятствовать ее завершению.
311
1. По тем или иным причинам, связанным с оборудованием или програм-
мным обеспечением, может произойти отказ системы. В этом случае все ак-
тивные транзакции не способны завершиться, и возможно даже, что некото-
рые уже завершенные транзакции должны быть «аннулированы», так как они
читали значения, записанные транзакциями, которые еще на завершились.
Отказы системы порождают серьезные проблемы. Необходимо не только
найти множество транзакций, которые следует «аннулировать», чтобы возвра-
тить систему в непротиворечивое состояние, но и удостовериться в том, что
существует некоторый способ восстановления такого состояния.
2. Исполнение конкретной транзакции может быть принудительно пре-
кращено до ее завершения. Так, если система обнаружила состояние тупи-
ка, данная транзакция может быть признана одной из его причин и выбрана
системой для аннулирования. Ошибка в транзакции, например деление на
нуль, может вызвать прерывание и аннулирование этой транзакции. Подоб-
ным же образом пользователь может вызвать прерывание со своего термина-
ла с целью аннулирования транзакции.
Копии для восстановления
Очевидно, что нельзя полагаться на неограниченную сохранность дан-
ных в базе данных. Например, мы не можем предполагать, что сохраняются
данные в машинных регистрах или памяти на интегральных схемах при
включении питания ЭВМ. В то же время данные на магнитных устройствах,
таких, как ленты, диски или запоминающие устройства на ферритовых сер-
дечниках, обычно могут сохраняться и при выключении машины. Но даже
эти данные уязвимы с точки зрения различных физических факторов, та-
ких, как «отказ головки» в запоминающем устройстве на магнитных дисках
или маленький ребенок с большим магнитом, озорничающий в машинном за-
ле. Кроме того, нет данных, которые были бы гарантированы от уничтоже-
ния из-за ошибок в программном обеспечении системы.
По этим причинам копии базы данных для восстановления должны делать-
ся периодически, по возможности ежедневно, хотя чрезвычайно большие
базы данных, для которых процесс копирования длится часами, могут копи-
роваться реже. После того как копия на ленте или диске сделана, она не
должна находиться в непосредственной близости от ЭВМ (на случай пожара,
например). Ее следует хранить в надежном месте. Для повышения надежно-
сти несколько последних копий могут храниться в различных местах.
При изготовлении копии важно, чтобы копируемые данные представ-
ляли непротиворечивое состояние. Поэтому служебная программа для копи-
рования должна сама быть транзакцией, которая блокирует для чтения все
элементы в базе данных.
Журнал
Необходимо также быть готовым к восстановлению непротиворечивого
состояния базы данных, которое отражает ситуацию, возникшую в резуль-
тате выполнения некоторого (возможно, большого) числа транзакций, за-
вершенных после создания последней копии базы данных для восстановле-
ния *. Поэтому необходимо сохранять в относительно надежном месте, на-
1 Такое непротиворечивое состояние может не существовать в течение жизни базы
данных, так как другие незавершенные нли даже завершенные транзакции могут вы-
полняться параллельно с выбранным множеством транзакций, на котором это состояние
базируется.
312
пример на ленте или диске, историю (журнал) всех изменений в базе данных,
произведенных после того, как была сделана последняя копия для восста-
новления. В наиболее общем случае записи журнала содержат:
1) уникальный идентификатор транзакции, вызывающей изменение;
2) старое значение элемента;
3) новое значение элемента.
Мы полагаем, что в журнале должны регистрироваться моменты време-
ни, характеризующие главные этапы хода выполнения транзакции, напри-
мер моменты ее начала и окончания, а также момент, который позже будет
назван «точкой фиксации транзакции».
Необходимость в старых и новых значениях станет очевидной, когда
мы увидим, что они нужны не только для рестарта транзакций, но и для
их аннулирования, т. е. для полного устранения результатов определенных
транзакций. Если элементы большие, например, если они являются отноше-
ниями, то разумно представлять в журнале только изменения, а не список
полных старых и новых значений. Так, можно регистрировать включаемые
и удаляемые кортежи, а также старые и новые значения для модифицирован-
ных кортежей.
Зафиксированные транзакции
Имея дело с транзакциями, для которых приходится производить рестарт
или аннулирование, удобно оперировать понятиями «зафиксированных» и
«незафиксированных» транзакций. В процессе исполнения любой транзакции
наступает некоторый момент, когда мы рассматриваем транзакцию как за-
вершенную. Все вычисления, сделанные транзакцией в ее рабочем прост-
ранстве, должны быть закончены, и копия результатов ее исполнения долж-
на быть записана в безопасное место, предпочтительнее всего в журнал.
После этого мы можем считать транзакцию зафиксированной. Если впослед-
ствии будет иметь место отказ системы, результаты транзакции уцелеют,
хотя продуцированные ею значения могут еще не появиться в самой базе
данных. Действие фиксации транзакции может быть само записано в жур-
нал. Поэтому если восстановление при отказе выполняется с использованием
журнала, можно узнать, какие транзакции были зафиксированы. Опреде-
лим стратегию двухфазной фиксации 1 следующим образом:
1. Транзакция не может осуществлять запись в базу данных до своей
фиксации.
2. Транзакция не может зафиксироваться до тех пор, пока она не за-
пишет все произведенные ею изменения элементов в журнал.
Заметим, что первая фаза представляет собой запись данных в журнал,
а вторая — запись тех же самых данных в базу данных.
Если, кроме того, все транзакции следуют двухфазному протоколу бло-
кирования, а разблокирование осуществляется только после их фиксации,
то ясно, что ни одна транзакция не сможет прочитать из базы данных зна-
чение, записанное незафиксированной транзакцией. В случае отказа си-
стемы имеется возможность просмотреть журнал и произвести рестарт всех
зафиксированных транзакций, у которых не было возможности записать свои
значения в базу данных. Если отказ сопровождается разрушением данных в
базе данных, мы должны исполнить рестарт всех транзакций, зафиксирован-
ных с тех пор, как была сделана последняя копия для восстановления, что,
1 Нет никакой связи между «двухфазным протоколом» и «двухфазной фиксацией»,
за исключением того, что и то и другое — разумные идеи.
313
вообще говоря, потребует значительно больше времени. Совсем не обязатель-
но, однако, аннулировать все транзакции, которые не достигли точки фик-
сации до отказа системы, так как они не оказали еще какого-либо влияния
на базу данных. Неплохая идея — выдавать пользователю сообщение, пре-
дупреждающее, что его транзакция не закончилась. Для того чтобы это
можно было сделать после отказа, необходимо с помощью программных
средств отмечать в журнале начало транзакции. Заметим также, что в ре-
зультате отказа системы некоторые элементы могут остаться заблокирован-
ными зафиксированными или незафиксированными транзакциями. Снимать
такие блокировки должна программа восстановления.
Неудачное исполнение отдельных транзакций
Менее серьезным, чем сбой системы, является неудачное исполнение от-
дельной транзакции, когда, например, она приводит к тупику или прерыва-
ется по какой-либо причине. Если мы следуем стратегии двухфазной фикса-
ции, то база данных при этом не затрагивается при условии, что никаких
прерываний транзакции не может быть после фиксации. Если к тому же
следовать двухфазному протоколу, то никакие блокировки или вычисления
не могут иметь место после фиксации. Поэтому невозможно возникнове-
ние тупика, участником которого является данная транзакция, после ее
фиксации. Кроме того, невозможны прерывания в связи с арифметически-
ми ошибками. Поэтому неудачно исполненная транзакция, не оставляет сле-
да в базе данных. В журнале должна быть сделана запись о том, что транзак-
ция была аннулирована. Тогда в случае выполнения после отказа системы
рестарта нам становится известно, что нужно игнорировать записи в журна-
ле для этой транзакции.
Транзакции, не подчиняющиеся стратегии
двухфазной фиксации
Кратко обсудим, что произойдет, если не требовать от транзакций, чтобы
они осуществляли запись в базу данных только после точки фиксации.
Ослабив это требование, можно позволить транзакциям снимать блокировку
элементов несколько ранее и тем самым допустить параллельное исполнение
других транзакций (вместо ожидания). Однако, как мы увидим далее, за
такое потенциальное увеличение параллелизма нам придется расплачиваться
тем, что восстановление после отказов окажется затруднительным.
По-прежнему предполагаем, что для каждого элемента его измененные
значения записываются в журнал, прежде чем фактически будет обновляться
сама база данных. Пусть, кроме того, транзакции подчиняются двухфазно-
му протоколу в отношении блокировок, и транзакция не фиксируется, пока
она не завершит запись в журнал всех элементов, которые она изменяет.
При наших новых предположениях восстановление после отказов системы
или неудачных исполнений отдельных транзакций не является невозможным,
но становится более трудным по двум причинам:
1. Для транзакции, не зафиксированной к моменту отказа системы,
должны быть аннулированы все изменения, которые она сделала в базе
данных.
2. Транзакция, прочитавшая значение, записанное некоторой другой
транзакцией, которая должна быть аннулирована, должна и сама быть ан-
нулирована. Этот эффект может распространяться неограниченно.
Пример 10.13. Рассмотрим две транзакции на рнс. 10.19. Теоретически эти
транзакции удовлетворяют модели из разд. 10.2, хотя для пояснения некоторых дета-
314
лей синхронизации мы явно показали фиксацию, операции чтения, записи и ариф-
метические действия, выполняемые в рабочем пространстве каждой транзакции. Пред-
полагается, что шаги WRITE осуществляют запись старого и нового значений в жур-
нал, а затем — в базу данных. Пусть после шага 14 происходит отказ. Поскольку Т\
является единственной активной транзакцией, то не имеет значения, произошел ли
отказ системы или имело место неудачное исполнение этой транзакции, например из-
за деления на нуль на шаге 14.
(1) LOCK А
(2) READ А
(3) А: = А — 1
(4) WRITE А
(5) LOCK В
(6) UNLOCK А
(7) LOCK А
(8) READ А
О) А: = 4*2
(Ю) READ В
(И) WRITE А
(12) COMMIT
(13) UNLOCK А
(14) В: = В/А
Л
Рис. 10.19. Расписание
Так как транзакция Тг не зафиксировалась, мы должны аннулировать ее. По-
скольку она осуществляет блокировку В, последняя должна быть снята. Далее следует
восстановить для А его значение, которое оно имело до шага 1. Требуется также ан-
нулировать транзакцию Тъ, несмотря на то, что она зафиксировалась и в действитель-
ности полностью закончена. Если некоторая другая транзакция Тг читала А между
шагами 13 и 14, то Тг также должна быть аннулирована, даже если она полностью
закончена, и т. д.
Для того чтобы аннулировать транзакции, которые этого требуют, рассмотрим
каждый элемент С, записанный одной или несколькими транзакциями, подлежащими
аннулированию. Проверим журнал для выявления самой ранней записи элемента С
одной из этих транзакций. Соответствующая запись в журнале будет содержать старое
значение С, которое может быть помещено в базу данных. Заметим, что все транзакции,
по нашему предположению, являются двухфазными и что мы используем модель из
разд. 10.2, где все элементы блокируются как для чтения, так и для записи. При этих
условиях ие может иметь места ситуация, когда некоторая транзакция Т, не подлежа-
щая аннулированию, записала бы значение С позже, чем это сделала самая ранняя ан-
нулируемая транзакция. Мы оставляем читателю в качестве упражнения разработку
корректного алгоритма модификации базы данных, связанной с аннулированием тран-
закций при использовании модели из разд. 10.4, которая позволяет выполнять запись
без предварительного чтения.
В случае нашего примера, приведенного на рис. 10.19, только А было записано
транзакциями 7\ и Тг прежде, чем имел место отказ. Находим, что самая ранняя за-
пись А одной из указанных транзакций — это запись, осуществленная транзакцией
Tj на шаге 4. В записи журнала для шага 4 будет содержаться старое значение А, про-
читанное на шаге 2. Замена А этим значением полностью аннулирует влияние тран-
закций 7\ и 7*2 на базу данных.
Может создаться впечатление, что после аннулирования транзакций
7\ и Т2 в примере 10.13 станет возможным восстановление результатов
поскольку она была зафиксирована, путем простого просмотра журнала, а
не посредством повторного ее исполнения. Однако это не так, потому что Т,
читала значение А, записанное в базу данных 7\, а этого значения больше
не существует. Выборка его из журнала без повторного исполнения тран-
закции Тх может привести к нарушению непротиворечивости базы данных.
315
УПРАЖНЕНИЯ
10.1. На рис. 10.20 показано расписание четырех транзакций. Допустим, как и
в разд. 10.3, что блокировки для записи предполагают чтение. Постройте граф пред-
шествований и определите, является ли это расписание сериализуемым.
(1) RLOCK А
(2) RLOCK А
(3) WLOCK В
(4) UNLOCK А
(5) WLOCK А
(6) UNLOCK В
(7) RLOCK В
(8) UNLOCK А
(9) RLOCK В
(10) RLOCK А
(11) UNLOCK В
(12) WLOCK С
(13) UNLOCK А
(14) WLOCK А
(15) UNLOCK А
(16) UNLOCK В
(17) UNLOCK С
Ti Т2 Та 7\
Рис. 10.20. Расписание
10.2. Повторите упражнение 10.1 при допущениях, сделанных в разд. 10.4, ког-
да блокировка для записи не предполагает, что значение читается.
*10.3. На рис. 10.21 приведены две транзакции. Сколько существует для них ва-
риантов легальных расписаний? Сколько нз этих расписаний являются сериализуемы-
ми?
LOCK А
LOCK В
UNLOCK А
UNLOCK В
LOCK В
UNLOCK В
LOCK А
UNLOCK А
Tt
Рис. 10.21. Две транзакции
10.4. Приведите пример, показывающий, почему является слишком сильным
допущение из разд. 10.2 о том, что с каждым блокированием элемента транзакцией мо-
жет быть ассоциирована однозначная функция. Иными словами, приведите расписа-
ние транзакций, которое в соответствии с алгоритмом 10.1 не сериализуемо, на факти-
чески дает те же результаты, что и некоторое последовательное расписание.
10.5. Докажите, что если транзакция над деревом элементов не подчиняется
протоколу для дерева, то найдется некоторая транзакция (фактически подчиняющаяся
этому протоколу), такая, что для обеих транзакций существует легальное, но не сериа-
лизуемое расписание.
*10.6. Пусть имеются три транзакции, подчиняющиеся протоколу для дерева на
иерархической структуре, приведенной на рис. 10.17 в разд. 10.5. Первая транзакция
блокирует А, В, С и Е, вторая — С н F, а третья — В и Е. Сколькими способами для
этих транзакций можно построить легальное расписание?
**10.7. Обобщение протокола с предупреждениями из разд. 10.5 допускает как
блокировки для чтения и записи, так и предупреждения относительно этих блоки-
ровок с очевидной семантикой . Таким образом, в принципе существует 16 «состоя-
ний» элемента, которые могут задаваться транзакцией, в соответствии с 16 под-
множествами двух видов блокировок и двух видов предупреждений. Однако некото-
рые из этих комбинаций бессмысленны. Например, необязательно устанавливать пре-
дупреждения о чтении и записи для одного н того же элемента, потому что предупреж-
дение о записи запрещает любые действия, которые запрещают предупреждение о чте-
нии. Сколько различных состояний может быть установлено транзакцией для элемен-
та? Приведите таблицу, показывающую, какие комбинации состояний могут быть ус-
тановлены двумя различными транзакциями для одного элемента. Например, каждая
316
из двух транзакций может установить предупреждение о чтении для элемента, но ни
одна из них не может установить блокировку для чтения в то время, когда другая ус-
тановила предупреждение о записи.
**10.8. Пусть множество элементов образует ориентированный ацикличный граф
(ОАГ). Покажите, что следующий протокол обеспечивает сериализуемость.
а) Первая блокировка может быть установлена для любого узла.
б) Впоследствии узел п можно блокировать только в том случае, когда данная
транзакция осуществляет блокировку по крайней мере одного предка п, и эта транзак-
ция блокировала каждого предка п в некоторый момент в прошлом.
**10.9. Покажите, что следующий протокол также допустим для ОАГ.
а) Первая блокировка может быть установлена для любого узла.
б) Впоследствии транзакция может заблокировать узел только тогда, когда она
осуществляет блокировку для большинства его предков.
Библиографические замечания
Модель параллельного исполнения из разд. 10.2 и 10.3, двухфазный протокол и
его необходимость для сериализуемости — все эти вопросы рассматриваются в работе
Эсверена н др. [64]. Модель, обсуждаемая в разд. 10.4 (допускающая блокировки толь-
ко для записи), и метод проверки сериализуемости, основанный на полиграфе, предло-
жены Пападимитриу, Бернштейном и Ротни [130] и Пападимитриу [129]. Вопросы,
касающиеся протоколов с блокировками для чтения и для записи, обсуждаются Леи-
ном и Вайнбергером [105].
Три протокола для иерархически структуризованных баз данных заимствованы
у Зильбершаца и Кедема [154]. Байер и Школьник [15], а также Эллис [62] разработа-
ли алгоритмы для специального случая параллельного доступа к В-деревьям. Кроме
того, Кедем и Зильбершац [97] исследовали границы использования так называемого
«протокола для дерева» на совокупности элементов, структуризованных более общим
образом.
«Протокол с предупреждениями» представляет собой упрощение идей (упомяну-
тых в упражнении 10.7), описанных у Грея, Путзоло и Трейгера [78] и Грея [76]. В
последней статье обсуждается также стратегия двухфазной фиксации и приводится
полезный обзор по блокировке, параллелизму и восстановлению после отказов вооб-
ще. Менаск, Попек и Мунц [116] детально проанализировали стратегии восстановле-
ния после отказов, в том числе ситуацию, когда отказ имел место во время восстановле-
ния.
Имеется целый ряд других уже изученных направлений, связанных с параллель-
ной обработкой. Розенкранц и др. [142] и Стирнз и др. [159] моделировали «общесис-
темное планирование», при котором элементы не блокируются транзакциями, ио цент-
ральный модуль управления блокировками регистрирует блокировки и принимает ре-
шение о предоставлении запросам прав на чтение или запись элемента. В работах Берн-
штейна и др. [22, 24], Эпштейна и др. [63], Томаса [167, 168] и Гарсия-Молина [71] про-
изведена оценка алгоритмов для поддержания в существенной степени распределен-
ных копий базы данных. В этой ситуации возникают проблемы, когда различные тран-
закции в разных участках выполняются параллельно, а затем транслируют сделанные
ими изменения в другие участки.
Куиг и Пападимитриу [103] создали теорию о том, каким образом применяемая
при планировании транзакций информация влияет на использование протокола для
обеспечения сериализуемости. Янакейкис [177] исследовал связь между структурой
элементов (такой, как древовидная структура, обсуждавшаяся в разд. 10.5) и прото-
колами, которые гарантируют сериализуемость. Там же был предложен протокол ОАГ
из упражнения 10.8, а протокол из упражнения 10.9 рассмотрен у Кедема и Зильбер-
шаца [98].
Грей, Лори и Путзоло [77], а также Рейс и Стоуибрейкер [135, 136] рассмотре-
ли вопрос о «разрешающей способности блокирования», т. е. насколько большими
должны быть индивидуально блокируемые элементы.
Книга Коффмана и Деннинга [48] является источником по общим вопросам пара-
лельиых систем. Работа Ротни и Гудмэна [143] является обзором техники параллель-
ной обработки для систем распределенных баз данных.
ЛИТЕРАТУРА
I. A h о А. V., В е е г i С. and Ullman J. D. The theory of joins in relational
databases, Submitted to TODS. A preliminary version appeared in Proc. Eighteenth
Annual IEEE Symposium on Foundations of Computer Science, 1978, p. 107—113.
2. A h о A. V., Hopcroft J. E. and Ullman J. D. The Design and Analysis
of Computer Algorithms, Addison Wesley, Reading, Mass, 1974.
3. A h о A. V., Kernighan B. W., and Weinberger P. J. Awk-a pattern
scanning and processing language. — Software Practice and Experience, 9, 1979,
p. 267—279.
4. Aho A. V., S a g i v Y. and U 1 1 m a n J. D. Equivalence of relational expres-
sions. SIAM J. Computing, 8 : 2, 1979, p. 218—246.
5. A h о A. V. and Ullman J. D. Optimal partial match retrieval when fields are
independently specified. — ACM Trans, on Database Systems, 4: 2, 1979,
p. 168—179.
6. A h о A. V. and Ullman J. D. Universality of data retrieval languages. —
Proc. Sixth ACM Symposium on Principles of Programming Languages, 1979,
p. 110—120.
7. ANSI/X3/SPARC Study group on data dase management systems: interim report,
FDT, 7 : 2, ACM, New York, 1975.
8. Armstrong W. W. Dependency structures of data base relationships, Proc
1974 IFIP Congress, North Holland, Amsterdam, 1974, p. 580—583.
9. Arora A. K. and Carlson C. R. The information preserving properties of cer-
tain relational database transformations. — Proc. ACM Inti. Conf, on Very Large
Data Bases, 1978, p. 352—359.
10. A s t r a h a п M. M. and Chamberlin D. D. Implementation of a structured
English query language. — Comm. ACM, 18 : 10, 1975, p. 580—587.
11. Astrahan M. M., et al. System R: a relational approach to data manage-
ment,— ACM Trans, on Database Systems, 1 : 2, 1976, p. 97—137.
12. Bachman C. W. Data structure diagrams. — Data base 1 : 2, 1969, p. 4—10.
13. В a n c i 1 h о n F. On the completeness of query languages for relational data-
bases.— Proc. Seventh Symp. on Mathematical Foundations of Computer Science,
Springer-Verlag, 1978.
14. В a у e r R. and McCreight E. M. Organization and maintenance of large
ordered indices. — Acta Informatica, 1 : 3; 1972 p. 173—189.
15. В a у e r R. and Shkolnick M. Concurrency of operation on B—trees. —
Acta Informatica, 9 : 1, 1977, p. 1—21.
16. В e с к L. L. On minimal sets of operations for relational data sublanguages.—
TR CS-7802, SMU, Dallas, 1978.
17. Beer i C. On the membership problem for multivalued dependencies in relatio-
nal databases.— TR229, Dept, of EECS, Princeton Univ., Princeton, N. J., 1977.
18. В e e г i C. and Bernstein P. A. Computational problems related to the
design of normal form relation schemes.— ACM Trans, on Database Systems, 4:1,
1979, p. 30—59.
19. В e e r i С., В e r n s.t e i п P. A. and Goodman N. A sophisticate's in-
troduction to database normalization theory.—Proc. ACM Inti. Conf, on Very Large
Data Bases, 1978, p. 113—124.
318
20. В е е г i С., Fagin R., and Howard J. H. A complete axiomatization
for functional and multivalued dependencies, — ACM/SIGMOD International Sym-
posium on Management of Data, 1977, p. 47—61.
21. Beeri C., Men delzon A. O., S a g i v Y. and U 1 1 m a n J. D. Equi-
valence of relational database schemes, — Proc. Eleventh Annual ACM Symposium
on the Theory of Computing, 1979, p. 319—329.
22. Bernstein, P. A., Goodman N., Rothnie J. B., and P a p a di-
rn i t r i о u С. H. Analysis of serializability of SDD-1: a system of distributed
databases (the fully redundant case). To appear in IEEE Trans. Software Engg, 197b.
23. В e r n s t e i п P. A. Synthesizing third normal form relations from functional
dependencies. — ACM Trans, on Database Systems, 1 : 4, 1976, p. 277-298.
24. В e r n s t e i n P. A., Shi pm an D. W., Rothnie J. B. and Good-
man N. The concurrency control mechanism of SDD-1: a system for distributed
databases (the general case). TR CCA—77—09, Computer Corp, of America, Cembiid-
ge, Mass, 1977.
25. В i s к u p J. Inferences of multivalued dependencies in fixed and undetermined
universes. Unpublished manuscript, to appear in Theor. Computer Science, 1978.
26. В i s к u p J., D a у a 1 U., and Bernstein P. A. Synthesizing indepen-
dent database schemas, — ACM/SIGMOD International Symposium on Management
of Data, 1979, p. 143—152.
27. В о 1 о u r A. Optimality properties of multiple key hashing functions. — J. ACM,
26 ; 2, 1979 p. 196—210.
28. В о у c e R. F., Chamberlin D. D., King W. F. and Hammer
M. M. Specifying queries as relational expressions; the SQUARE data sublanguage. —
Comm. ACM, 18: 11, 1975, p. 621—628.
29. Burkhard W. A. Hashing and trie algorithms for partial match retrieval. —
ACM Trans, on Database Systems, 1:2, p. 175—187, 1976.
30. C a r d e n a s A. F. Data Base Management Systems. Allyn and Bacon, Boston,
Mass, 1979.
31. С a r 1 s о n C. R. and Kaplan R. S. A generalized access path model and
its application to a relational database system. — ACM/SIGMOD International
Symposium on Management of Data, 1976, p. 143—156.
32. C h a m b e r 1 i n D. D., et al. SEQUEL-2: a unified approach to data definition,
manipulation, and control. — IBM J. Res., 20 : 6, 1976, p. 560—575.
33. C h a n d r a A. K., and H a r e 1 D. Computable queries for relational databa-
ses. — Proc. Eleventh Annual ACM Symposium on the Theory of Computing, 1979,
p. 309—319.
34. C h a n d r a A. K. and Merlin P. M. Optimal implementation of conjuncti-
ve queries in relational databases. — Proc. Ninth Annual ACM Symposium on
the Theory of Computing, 1976, p. 77—90.
35. C h e n P. P. The entity—relationship model: toward a unified view of data. —
ACM Trans, on Database Systems, 1:1, 1976, p. 9—36.
36. C h i 1 d s D. L. Feasibility of a set-theoretical data structure—a general structure
based on a reconstituted definition of relation. — Proc. 1968 I FI P Congress, North
Holland, Amsterdam, 1968, p. 162—172.
37. Chin F. Y. Security in statistical databases for queries with small counts. — ACM
Trans, on Database System, 3:1, 1978, p. 92—104.
38. C i n с о m. OS TOTAL Reference Manual, Cincom Systems, Cincinnati, Ohio, 1978.
39. CODASYL Data Base Task Group April 71 Report, ACM, New York, 1971.
40. CODASYL COBOL J. Development, Materiel Data Management Center,
Quebec, Que, 1978, Earlier editions appeared in 1973 and 1968.
41. Co d d E. F. Further normalization of the data base relational model. In Data
Base Systems (R. Rustin, ed.), Prentice Hall, Englewood Cliffs, N. J., 1972, p. 33—64.
42. С о d d E. F. A relational model for large shared data banks. — Comm. ACM, 13 : 6,
1970, p. 377—387.
319
43. С о d d Е. F. Relational completeness of data base sublanguages. — Ibid. 1972,
p, 65—98.
44. С о d d E. F. Understanding relations, FDT, 7 : 3—4, ACM, New York, 1975,
p. 23—28.
45. С о d d E. F. How about recently, In [152], p. 3—28.
46. С о d d E. F. Extending the data base relational model. — ACM/SIGMOD Inter-
national Symposium on Management of Data, 1979, p. 161, To appear in a special
issue of TODS.
47. С о d d E. F., Arnold R. S., C a d i о u J. M., Chang C. L. and
Roussopoulos N. Rendezvous version I: an experimental English language
query formulation system for casual users of relational databases. — RJ2144, IBM,
San Jose, 1978.
48. С о f f m a п E. G. and Denning P. J. Operating Systems Theory. Prentice
Hall, Englewood Cliffs, N. J., 1973.
49. С о m e r D. The difficulty of optimum index selection. — ACM Trans, on Databa-
se Systems, 3 : 4, 1978, p. 440—445.
50. IDMS DML Programmer’s Reference Guide, Cullinane Corp.. Wellesley, Mass, 1978.
51. D a t e C. J. An Introduction to Database Systems. Addison Wesley, Reading,
Mass, 1977. Русский перевод: Дейт К. Введение в системы баз данных. М.,
Наука, 1980.
52. D е 1 1' О г с о Р., S р a d a v е с с h i о V. N. and King М. Using knowled-
ge of a data base world in interpreting natural language queries. — Proc. 1977 IFIP
Congress, North Holland, Amsterdam, 1977, p. 139—144.
53. D e 1 о b e 1 C. Normalization and hierarchical dependencies in the relational data
model. — ACM Trans, on Database Systems, 3 : 3, 1978, p. 201—222.
54. D e 1 о b e 1 C. and Casey R. C. Decomposition of a database and the theory
of Boolean switching functions. — IBM J. Res., 17 : 5, 1972, p. 370—386.
55. D e M i 1 1 о R. A., Dobkin D. P., Jones A. K. and Lipton R. J.
Foundations of Secure Computation. Academic Press, New York, 1978.
56. D e M i 1 1 о R. A., Dobkin D. P. and Lipton R. J. Even databases
that lie can be compromised. — IEEE Trans, on Software Engineering, SE 4 : 1,
1978, p. 73—75.
57. Denning D. E. A review of research on statistical database security. In [55],
p. 15—26.
58. D e п n i n g D. E., Denning P. J. and Schwartz M. D. Securing
databases under linear queries, — Proc. 1977 IFIP Congress, North Holland, Amster-
dam, 1977, p. 395—398. Also see ACM Trans, on Database Systems, 4 : 2, p. 156—167.
59. Denning D. E., Denning P. J. and Schwartz M. D. The Tracker:
a threat to statistical database security. — ACM Trans, on Database Systems, 4 : 1,
1979, p. 76—96.
60. Dobkin D., Jones A. K. and Lipton R. J. Secure databases: pro-
tection against user inference. — ACM Trans, on Database Systems, 4:1, 1979,
p. 97—106.
61. Douque В. С. M. and Nijssen G. M. (eds). Database Description. North
Holland, Amsterdam, 1976.
62. E 1 1 i s C. S. Concurrent search and insertion in 2—3 tress. — TR-78-05-01,
Dept, of Computer Science, Univ, of Washington, Seattle, 1978.
63. Epstein R., Stonebraker M. R. and Wong E. Distributed query
processing in a relational database system. — ACM/SIGMOD International Sympo-
sium on Management of Data, 1978, p. 169—180.
64. E s w a г а и К. P., Gray J. N. , L о r i e R. A. and T r a i g e r I. L.
The notions of consistency and predicate locks in a database system. — Comm. ACM,
19 : 11, 1976, p. 624— 633.
320
65. F a g i n R. Multivalued dependencies and a new normal form for relational data-
bases. — ACM Trans, on Database Systems, 2 : 3, 1977, p. 262—278.
66. F a g i n R. On an authorization mechanism. — ACM Trans, on Database Systems,
3 : 3, 1978, p. 310—319.
67. F a g i n R. Normal forms and relational detabase operators. ACM/SIGMOD In-
ternational Symposium on Management of Data, 1979, p. 153—160.
68. F a g i n R. A normal form for relational database that is based on domains and
keys. — RJ2520, IBM, San Jose, 1979.
69. F u r t a d о A. L. Formal aspects of the relational model. — Information sys-
tems, 3:2, 1978, p. 131—140.
70. G a 1 1 a i r e H. and M i n к e r J. Logic and databases. Plenum Press, New
York, 1978.
71. Garcia-Molina H. Performance comparison of update algorithms for dis
tributed databases. Part I: Tech. Note 143. Part II: Tech. Note 146, Digital Systems
Laboratory, Stanford Univ., 1979.
72. G a г e у M. R. and Johnson D. S. Computers and Intractability: A Guide
to the Theory of NR-Completeness. Freeman, San Francisco, 1979.
73. G о t 1 i e b С. C. and G о t 1 i e b L. R. Data Types and Structures. Prentice
Hall, Englewood Cliffs, N. J., 1978.
74. G о t 1 i e b С. C. and T о m p a F. W. Choosing a storage schema. Acta Infor-
matica, 3, 1973, p. 297—319.
75. G о t 1 i e b L. R. Computing joins of relations. — ACM/SIGMOD International
Symposium on Management of Data, 1975, p. 55—63.
76. Gray J. N. Notes on data base operation systems. — RJ2188, IBM, San Jose,
Calif., 1978.
77. G г a у J. N. , L о r i e R. A. and P u t z о 1 о G. R. Granularity of locks in
a shared database. — Proc. ACM Inti. Conf, on Very Large Data Bases, 1975, p.
428—451.
78. G г a у J. N., P u t z о 1 о F. and T r a i g e r I. Granularity of locks and
degrees of consistency in a shared data base. In [125].
79. G r e e n b 1 a t t D. and Waxman J. A study of three database query langua-
ges. In [152], p. 77—98.
80. G r i f f i t h s P. P., Astra han M. M.., Chamberlin D. D., Lo-
rie R. A. and Price T. G. Access path selection in a relational database
management system. — RJ2429, IBM, San Jose, 1979.
81. Griffiths P. P. and Wade B. W. An authorization mechanism for a re-
lational database system. — ACM Trans, on Database Systems, 1 : 3, 1976, p. 242—
255.
82. H a g i h a r a K., Ito M., Taniguchi K. and К a s a m i T. Decision
problems for multivalued dependencies in relational databases. SIAM J. Computing,
8 : 2, 1979, p. 247—264.
83. H a 1 1 P. A. V. Optimization of a single relational expression in a relational
database. — IBM J. Res., 20 : 3, 1976, p. 244—257.
84. Haq M. I. Security in a statistical database. — Proc. Amer. Soc. Inform. Science,
11:1, 1974, p. 33—39.
85. Haq M. I. Insuring individual’s privacy from statistical database tisers. —
Proc. 1975 National Computer Conference, AFIPS Press, Montvale, N. J., 1975,
p. 941—946.
86. H e 1 d G. and Stonebraker M. В-trees reexamined. — Comm. ACM,
21:2, 1978, p. 139—143.
87. H о f f m a n L. J. Modern Methods for Computer Security and Privacy. Prentice
Hall, Englewood Cliffs, N. J. 1977. Русский перевод: Хоффман Л. Дж. Сов-
ременные методы защиты информации. М., Сов. радио, 1980.
88. Н о f f m а п L. J. and Miller W. F. Getting a personal dossier from a sta-
tistical data bank. — Datamation, 16 : 5, 1970, p. 74—75.
321
89. Н о г о w i t z E. and S a h n i S. Fundamentals of Data Structures, Computer
Science press, Potomac, Md., 1976.
90. H s i a о D. K-, Kerr D. S. and M a d n i с к S. E. Privacy and security
of data communications and data bases. — Proc. ACM Inti. Conf, on Very Large
Data Bases, 1978, p. 55—67.
91. Hunt H. B. Ill and Rosenkran tz D. J. The complexity of testing predi-
cate locks. ACM/SIGMOD International Sysposium on Management of Data, 1979,
p. 127—133.
92. Query-by-Example terminal Users Guide, SH20-2078—0, IBM, White
Plains, N. Y., 1978.
93. IMS/VS publications, especially GH20-1260 (General Information), SH20-9025
(System/Application Design Guide), SH20-9026 (Application Programming Refe-
rence Manual), and SH20-9027 (Systems Programming Reference Manual), IBM,
White Plains, N. Y., 1978.
94. J а с о b s В. E. On queries definable in database structures. — TR 757, Dept,
of Computer Science, Univ, of Maryland, 1979.
95. К a m b a у a s h i Y. An efficient algorithm for processing multirelation que-
ries in relational databases. — ER78—01, Dept, of Information Science, Kyoto
Univ., Kyoto, Japan, 1978.
96. Kam J. B. and Ullman J. D. A model of statistical databases and their
security. — ACM Trans, on Database Systems, 2 : 1, 1977, p. 1—10.
97. К e d e m Z. and Silberschatz A. A characterization of database graphs
admitting a simple locking protocol. — TR 49, Dept, of Mathematical Sciences,
Univ, of Texas, Dallas, 1979.
98. К e d e m Z. and Silberschatz A. Controlling concurrency using locking
protocols. To appear in Proc. IEEE Twentieth Annl. Symp. on Foundations of Com-
puter Science, 1979.
99. Kerschberg L., Klug A. and Tsichritzis D. C.. A taxonomy
of data models. In Systems for Large Data Bases (Lockemann and Neuhold, eds),
North Holland, Amsterdam, 1977, p. 43—64.
100. Knuth D. E. The Art of Computer Programming. Vol. 1. Fundamental Algo-
rithms. Addison Wesley, Reading, Mass, 1968. Русский перевод: Кнут Д. Ис-
кусство программирования для ЭВМ. Т. 1. Основные алгоритмы М., Мир, 1976.
101. К п u t h D. Е. The Art of Computer Programming. Vol. 3. Sorting and Sear-
ching. Addison Wesley, Reading, Mass, 1973. Русский перевод: Кнут Д. Ис-
кусство программирования для ЭВМ. Т. 3. Сортировка и поиск. М., Мир, 1978.
102. Kuhns J. L. Answering questions by computer; a logical study. RM-5428-PR,
Rand Corp., Santa Monica, Calif, 1967.
103. Kung H. T. and Papadimitriou С. H. An optimality theory of con-
currency control for databases, ACM/SIGMOD International Symposium on Mana-
gement of Data, 1979, p. 116—126.
104. Lacroix M. and P i г о t t e A. Generalized joins. — SIGMOD Record,
8:3, 1976, p. 14—15.
105. Lien Y. E. and Weinberger P. J. Consistency, concurrency and crash
recovery. — ACM/SlGMOD International Symposium on Management of Data,
1978, p. 9—14.
106. Ling T.-W. and T о m p a F. Adequate definitions for third normal form. —
CS-78-34, Dept, of CS, Univ, of Waterloo, Waterloo, Ont, 1978.
107. Lipski W. Jr. On databases with incomplete information. Unpublished memo-
randum, Univ, of Illinois, 1978.
108. Liu L. and Demers A. An efficient algorithm for testing lossless joins in
relational databases. — TR 78—351, Dept, of Computer Science, Cornell Univ,
1978.
109. Lucchesi C. L. and Osborn S. L. Candidate keys for relations. — J.
Computer and Systems Sciences, 17 : 2, p. 270—279.
322
110. Lum V. and Ling H. Multi-attribute retrieval with combinedindices.—
Comm. ACM, 13 : 11, 1970, p. 660—665.
111. Maier D. Minimum covers in the relational database model. — Proc. Ele-
venth Annual ACM Symposium on the Theory of Computing, 1979, p. 330—337.
112. Maier D., M e n d e 1 z о n A. O., Sadr! F. and Ullman J. D. Notions
of decomposability in relational database schemes. Unpublished memorandum,
Dept, of EECS, Princeton Univ., Princeton, N. J., 1978.
113. M a e i r D., Me n de 1 zo n A. O. and S a g i v Y. Testing implications of data
dependencies. — ACM/SIGMOD International Symposium on Management of Data,
1978, p. 152. To appear in special issue of TODS.
114. Martin J. Computer Data Base Organization.— Prentice Hall, Englewood
Cliffs, N. J. 1977.
Русский перевод: M a p т и и Дж. Организация баз данных в вычислительных
системах. М., Мир, 1980.
115. Maurer W. D. and Lewis Т. G. Hash table methods. — Computing Surveys,
7 : 1, 1975, p. 5—20.
116. Menasce D. A., Popek G. J. and Muntz R. R. A locking protocol for
resource coordination in distributed databases. To appear in TODS, 1978.
117. M e n d e 1 z о n A. O. On axiomatizing multivalued dependencies in relational
databases, — J. ACM, 26:1, 1979, p. 37—44.
118. M e n d e 1 z о n A. O. and Maier D. Generalized mutual dependencies and the
decomposition of database relations. — Unpublished memorandum, Princeton Univ.,
Princeton, N. J., 1979.
119. M i n k e r J. Perfoming inferences over relational databases. — TR363, Dept, of
C. S., Univ, of Maryland, March, 1975.
120. M о r r i s S. Scatter storage techniques. — Comm. ACM, 11:1, 1968, p. 38—43.
121. Mr esse M. Identification and authorization in data base systems. — RJ2161,
IBM, San Jose, 1978.
122. System 2000 Reference manual, MRI Systems Corp., Austin, Tex., 1978.
123. Nicolas J. M. Mutual dependencies and some results on undecomposable rela-
tions. — Proc. ACM Inti. Conf, on Very Large Data Bases, 1978, p. 360—367.
124. Nijssen G. M. On the gross architecture for the next generation database mana-
gement systems. — Proc. 1977 IFIP Congress, 1977, North Holland, Amsterdam,
p. 327—335.
125. Nijssen G. M. (ed.) Modeling in Data Base Management Systems, North Hol
land, Amsterdam, 1976.
126. О 1 1 e T. W. The Codasyl Approach to Data Base Management. John Wiley and
Sons, New York, 1978.
Русский перевод: Олле T. В. Предложения КОДАСИЛ по управлению ба-
зами данных. М., Финансы и статистика, 1981.
127. О s b о г п S. L. Normal forms for relational databases, Ph. D. Thesis, Univ, of
Waterloo., 1977.
128. Palermo F. P. A database search problem, — Information Systems COINS IV
(J. T. Tou, ed.), Plenum Press, N. Y., 1974.
129. Papadimitriou С. H. The serializability of concurrent batabase updates.
Unpublished memorandum, Harvard Univ., Cambridge, Mass., 1978.
130. Papadimitriou С. H., Bernstein P. A. and R о t h n i e J. B. Com-
putational problems related to database concurrency control. — Proc. Conf, on Theo-
retical Computer Science, Univ, of Waterloo, Waterloo, Ont., 1977.
131. Pare daens J. On the expressive power of relational algebra. — Information
Processing Letters, 7 : 2, 1978, p. 107—111.
132. Pecherer R. M. Efficient evaluation of expressions in a relational algebra. —
Proc. ACM Pacific Conf., 1975, p. 44—49.
323
133. Perl Y., I t a i A. and A v n 1 H. Interpolation search — a log log n search. —
C mm. ACM, 21:7, 1978, p. 550—553.
134. P i г о t t e A. High level data base query languages. In Г70], p. 409—436.
135. Reis D. R. and Stonebraker M. R. Effects of locking granularity in a
database management system. — ACM Trans, on Database Systems, 2 : 3, 1977,
p. 233—246.
136. Reis D. R. and Stonebraker M. R. Locking granularity revisited.
UCB/ERL M78/71, Univ, of Calif., Berkeley, 1978.'
137. Reiss S; P. Security in databases: a combinatorial study,—J. ACM, 26 : 1, 1979,
p. 45—57.
138. Rissanen J. Independent components of relations. — ACM Trans, on Databa-
se Systems, 2 : 4, 1977, p. 317—325.
139. Rissanen J. Relations with functional and join dependencies and their repre-
sentation by independent components. — Unpublished manuscript, IBM, San Jose,
Calif., 1978.
140. R i v e s t R. L. Partial match retrieval algorithms. — SIAM J. Computing, 5 : 1,
1976, p. 19—50.
141. Roberts C. S. Partial match retrieval via the method of superimposed codes. —
Unpublished manuscript, Bell Laboratories, Holmdel, N. J., 1978.
142. Ros e n к r a n t z D. J., S t e a r n s R. E. and L e w i s P. M. II System level
concurrency control for distributed data base systems. — ACM Trans, on Database
Systems, 3 : 2, 1978, p. 178—198.
143. R о t h n i e J. B. and Goodman N. A survey of research and development in
distributed database management. — Proc. ACM Inti. Conf, on Very Large Data
Bases, 1977, p. 48—62.
144. R о t h n i e J. B. Jr. and Lozano T. Attribute based file organization in a
paged memory environment. — Comm. ACM, 17:2, 1974, p. 63—69.
145. R u s t i n R. (ed). Data-Structure-Set vs. Relational, Proc. ACM/SIGMOD Conf,
on Data Models, New York, 1974.
146. S a g i v Y. and Yannakakis M. Equivalence among relational expressions
with the union and difference operators. — Proc. Inti. Symp. on Very Large Data
Bases, 1978.
147. Schenk K. L. and P i n к e r t J. R. An algorithm for servicing multirelational
queries. — ACM/SIGMOD International Symposium on Management of Data, 1977,
p. 10—19.
148. Schlorer J. Identification and retrieval of personal records from a statistical
data bank. — Methods of Inform, in Medicine, 14 : 1, 1975, p. 7—13.
149. Schlorer J. Confidentiality of statistical records: a threat monitoring scheme
for on-line dialogue. — Methods of Inform, in Medicine, 15 : 1, 1976, p. 36—42.
150. Schmid H. A. and Swenson J. R. On the semantics of the relational mo-
del. — ACM/SIGMOD International Symposium on Management of Data, 1976,
p. 9—36.
151. S c i о r e E. Improving semantic specification in the database relational model. —
ACM/SIGMOD International Symposium on Management of Data, 1979, p. 170—
178.
152. Shneiderman B. (ed.). Database: Improving Usability and responsiveness.
Academic Press, New York, 1978.
153. Sibley E. (ed.). Computer Surveys, 8 : 1, March, 1976.
154. Silberschatz A. and К e d e m Z. Consistency in hierarchical database
systems. — Unpublished memorandum, Univ, of Texas, Dallas, 1978.
155. S m i t h J. M. and Chang P. Y. Optimizing the performance of a relational al-
gebra database interface. — Comm. ACM, 18 : 10. 1975. p. 568—579.
156. S m i t h J. M. and Smith D. С. P. Database abstractions: aggregation and ge-
neralization, ACM Trans, on Database Systems, 2 : 2, 1977, p. 105—133.
324
157. Snyder L. On В-trees reexamined. — Comm. ACM, 21 : 7, 1978, p. 594.
158. Software AG. ADABAS Introduction, Software AG of North America, Reston, Va,
1978.
159. Stearns R. E., Lewis P. M. and Rosenkrantz D. J. Concurrency
control for database systems. — Proc. Seventeenth Annual IEEE Symposium on
Foundations of Computer Science, 1976, p. 19—32.
160. Stonebraker M. Implementation of integrity constraints and views by query
modification. — ACM/SIGMOD International Symposium on Management of
Data, 1975, p. 65—78.
161, Stonebraker M. and Rowe L. A. Observations on data manipulation lan-
guages and their embedding in general purpose programming languages. TR UCB/
ERL M77-53, Univ, of California, Berkeley, July, 1977.
162. Stonebraker M. and Rubinstein P. The INGRES protection system.—
Proc. ACM National Conf., 1976, p. 80—84.
163. Stonebraker M. and Wong E. Access control in a relational database
management system by query modification. — Proc. ACM National Conf., 1974,
p. 180—187.
164. Stonebraker M., Wong E., Kreps P. and Held G. The desing and
implementation of INGRES. — ACM Trans, on Database Systems, 1 : 3, 1976,
p. 189—222.
165. Sundgren B. Theory of Databases, Mason/Charter, New York, 1975.
166. Tanaka K., Kambayashi Y., and Y a j i m a S. Properties of embedded
multivalued dependencies in relational databases. To appear in J. IECE, Japan,
1978.
167. T h о m a s R. H. A solution to the update problem for multipl copy databases
which use distributed control. — Rept. 3340, Bolt Beranek, and Newman, Camb-
ridge, Mass, 1975.
168. Thomas R. H. A majority consensus approach to concurrency control. — ACM
Trans, on Database Systems, 4 : 2, 1979, p. 180—219.
169. T о d d S. J. P. The Peterlee relational test vehicle — a system overview. — IBM
Systems J., 15 : 4, 1976, p. 285—308.
170. Tsichritzis D. C. and Lochovsky F. H. Data Base Management Sys-
tems, Academic Press, New York, 1977.
171. T s i c h r i t z i s D. C. and Lochovsky F. H. Data Models. To appear
Prentice Hall., Englewood Cliffs, N. J., 1979.
172. Tsichritzis D. and Klug A. (eds.). The ANSI/X3/SPARC Framework,
AFIPS Press, Nontvale, N. J., 1978.
173. VanLeeuwenJ. On compromising statistical databases with a few known ele-
ments.— Information Processing Letters, 1979, p. 149—153.
174. V a s s i 1 i о u Y. Null values in database management — a denotational seman-
tics approach. — ACM/SIGMOD International Symposium on Management of Data,
1979, p. 162—169.
175. Weiderhold G. Database Desing. McGraw Hill, New York,’ 1977.
176. Wong E. and Youssefi K. Decomposition — a strategy for query proces-
sing. — ACM Trans, on Database Systems, 1 : 3, 1976, p. 223—241.
177. Yannakakis M. Locking policies: safety and freedom from deablock. To ap-
pear in Proc. IEEE Twentieth Annl. Symp. on Foundations of Computer Science,
1979.
178. Y а о A. C. On random 2—3 trees. — Acta Informatics, 9 : 2, 1978, p. 159—170.
179. Y а о A. C. A note on a conjecture of Kam and Ullman concerning statistical data-
bases. To appear in Inf. Proccessing Letters, 1979.
180. Y а о A. C. and Y a о F. F. The complexity of searching an ordered random table. —
Proc. Seventeenth Annual IEEE Symposium on Foundations of Computer Science,
1976, p. 173-177.
3?5
181. Y a о S. В. Optimization of query eValuation algorithms. — ACM Trans, on Data-
base Systems, 4 : 2, 1979, p. 133—155.
182. Yu С. T. and Chin F. Y. A study on the protection of statistical databases. —
ACM/SIGMOD International Symposium on Management of Data, 1977, p. 169—181.
183. Z a n i о 1 о C. Analysis and desing of relational schemata for database systems,
Doctoral dissertation, UCLA, July, 1976.
184. Z a n i о 1 о C. Relational views in a database system support for queries. — Proc.
IEEE COMPSAC 77, 1977.
185. Z 1 о о f M. M. Query-by-Example: operations on the transitive closure. —IBM
RC 5526, Yorktown Hts., N. Y., 1975.
186. Z 1 о о f M. M. Query-by-Example: a data base language. — IBM System J., 16 : 4,
1977, p. 324—343.
187. Z 1 о о f M. M. Security and intergrity within the Query-by-Example data base ma-
nagement language. — IBM RC 6982, Yorktown Hts., N. Y., 1978.
188. Zook W., Y о u s s e f i K., Whyte N., Rubinstein P., Kreps P.
Held J., Ford J., Berman R. and Allman E. INGRES Reference
Manual, Dept, of EECS, Univ, of California, Berkeley, 1977.
ИМЕННОЙ УКАЗАТЕЛЬ
Авии (Avni Н.) 71
Армстронг (Armstrong W. W.) 157—160,
189
Арнольд (Arnold R. S.) 151
Арора (Arora А. К.) 190
Астрахан (Astrahan М. М.) 150, 215
Ахо (Aho А. V.) 5, 71, 150, 176, 186, 189,
215
Байер (Bayer R.) 71, 317
Бахман (Bachman С. W.) 25
Бек (Beck L. L.) 151
Бенсилои (Bancilhon F.) 150
Берман (Berman R.) 150
Бернштейн (Bernstein Р. А.) 177, 189,
190, 317
Бири (Beeri С.) 182—184, 186, 189, 190
Бискап (Biskup J.) 189
Бойс (Воусе R. F.) 150, 170, 172—176,
185, 188—189
Болур (Bolour А.) 71
Бурхард (Burkhard W. А.) 71
Вайдерхольд (Weiderhold G.) 240
Вайнбергер (Weinberger Р. J.) 150, 317
Вайт (Whyte N.) 150
Ваксман (Waxman J.) 150
Ван-Лиувен (Van Leeuwen J.) 286
Вассилоу (Vassilou Y.) 151
Вейд (Wade В. W.) 286
Вонг (Wong E.) 150, 215, 286
Галлер (Gallaire H.) 150
Гарсиа-Молина (Garcia-Molina H.) 317
Гарэй (Garey M. R.) 71, 176
Говард (Howard J. H.)
Готлиб К. К. (Gotlieb С. С.) 71
Готлиб Л. Р. (Gotlieb L. R.) 71, 215
Грей (Gray J. N.) 317
Грииблат (Greenblatt D.) 150
Гриффитс (Griffiths Р.) 215, 286
Гудмэн (Goodman N.) 190, 317
Дейт (Date С. J.) 5, 269
Дейэл (Dayal U.) 189
Делобель (Delobel С.) 189
Дель ’Орко (Dell ’Oreo Р.) 151
Демерс (Demers А.) 189
Де-Милло (Demillo R. А.) 286
Де-Морган (De Morgan) 147
Деннинг Д. Э. (Denning D. Е.) 286
Деннинг П. Д. (Denning Р. J.) 286, 317
Джекобс (Jacobs В. Е.) 150
Джонсон (Johnson D. S.) 71, 176
Джоуис (Jones А. К) 286
Добкин (Dobkin D. Р.) 286
Дук (Douque В. С. М.) 25
Заниоло (Zaniolo С.) 151, 189
Зильбершац (Silberschatz А.) 308, 317
Злуф (Zloof М. М.) 150, 286
Зук (Zook W.) 150
Итаи (Itai А.) 71
Ито (Ito М.) 189
Кадью (Cadiou J. М.) 151
Камбаяси (Kambayashi Y.) 189, 190
Карденас (Cardenas A. F.) 240, 269
Карлсон (Carlson С. R.) 190
Касами (Kasami Т.) 189
Кедем (Kedem Z.) 308, 317
Кейси (Casey R. С.) 189
Керниган (Kernighan В. W.) 150
Керр (Kerr D. S.) 286
Кершберг (Kerschberg L.) 25
Кинг В. Ф. (King W. F.) 150
Кинг М. (King М.) 151
Клуг (Klug А.) 25
Кнут (Knuth D. Е.) 29, 71, 193
Кодд (Codd Е. F.) 97, 150, 151, 170,
172—176, 185, 188—189
Комер (Comer D.) 71
Коффмаи (Coffman Е. G.) 317
Крепе (Kreps Р.) 150
Куиг (Kung Н. Т.) 317
Кунс (Kuhns J. L.) 150
Кэм (Kam J. В.) 286
Лакруа (Lacroix М.) 151
Лакизи (Lucchesi С. L.) 190
Леин (Lein Y. Е.) 317
Линг Т. В. (Ling Т. W.) 189
Линг X. (Ling Н.) 71
Липскн (Lipski W.) 151
Липтон (Lipton R. J.) 286
Лиу (Liu L.) 189
Лозано (Lozano Т.) 71
Лори (Lorie R. А.) 317
Лоховский (Lochovsky F. Н.) 25, 240,
269
Лум (Lum V.) 71
Льюнс П. М. (Lewis Р. М.) 317
Льюис Т. Г. (Lewis Т. G.) 71
Мак-Крейт (McCreight Е. М.) 71
Мартин (Martin J.) 5, 71
Маурер (Maurer W. D.) 71
Мейер (Maier D.) 189, 190
Меиаск (Menasce D. А.) 317
Мендельзон (Mendelzon А. О.) 189, 190
Мерлин (Merlin Р. М.) 215
Миллер (Miller W. F.) 286
Минкер (Minker J.) 150, 215
Моррис (Morris R.) 71
Мресс (Mresse М.) 286
Мунц (Muntz R. R.) 317
Мэдник (Madnick S. Е.) 286
Найсеи (Nijssen G. М.) 25
Никола (Nicolas J. М.) 190
Олле (Olle Т. W.) 5, 240
Осборн (Osborn S. L.) 189, 190
Палермо (Palermo F. Р.) 215
Пападимитриу (Papadimitriou С. Н.) 317
Перл (Perl Y.) 71
Печерер (Pecherer R. М.) 215
Пинкерт (Pinkert J. R.) 190
327
Пиротт (Pirotte А.) 150, 151
Попек (Popek G. J.) 317
Прайс (Price T. G.i 215
Путзоло (Putzolo г.) 317
Пэреданс (Paredaens J.) 150
Райвест (Rivest R. L.) 71
Растил (Rastin R.) 97
Рейс (Reis D. R.) 317
Рейсс (Reiss S, P.) 286
Риссанен (Rissanen J.) 189, 190
Робертс (Roberts C. S.) 71
Розенкранц (Rosenkrantz D. J.) 317
Ротни (Rothnie J. B.) 71, 317
Рубинштейн (Rubinstein P.) 286
Руссопулос (Roussopoulos N.) 151
Садри (Sadri F.) 190
Сани (Sahni S.) 71
Свенсон (Swenson J. R.) 151
Сейгив (Sagiv Y.) 189, 215
Сибли (Sibley E.) 97
Сайор (Sciore E.j 151
Смит Д. (Smith D. С. P.) 151
Смит Д. M. (Smith J. M.) 151, 215
Снайдер (Snyder L.) 71
Спадавекиб (Spadavecchio V. N.) 151
Стирнз (Stearns R. E.) 317
Стоунбрейкер (Stonebraker M.) 71, 150,
286, 317
Танака (Tanaka K.) 189
Танигути (Taniguchi K.) 189
Тодд (Todd S. J. P.) 150
Томас (Thomas R. H.) 317
Томпа (Tompa F. W.) 71, 189
Трейгер (Traiger I. L.) 317
Ульман (Ullman J. D.) 5, 7, 8, 71, 150,
176, 186, 189, 190, 215, 286
ФейЬин (Fagin R.) 182, 186, 189, 286
Форд (Ford J.) 150
Фостер (Foster J. M.) 46
Фуртадо (Furtado A. L.) 151
Хаммер (Hammer M. M.) 150
Харел (Harel D.) 150
Хегихара (Haginara K-) 189
Хелд (Held G.) 71, 150
Холл (Hall P. A. V.) 215
Хопкрофт (Hopcroft J. E.) 5, 71
Хоровиц (Horowitz E.) 71
Хоффман (Hoffman L. J.) 286
Хсяо (Hsiao D. K.) 286
Хэк (Haq M. I.) 286
Цикритзис (Tsichritzis D. C.) 25, 240,
269
Чайлдс (Childs D. L.) 97
Чанг К. Л. (Chang C. L.) 151
Чанг П. (Chang С. L.) 215
Чандра (Chandra А. К.) 150, 215
Чемберлин (Chemberlin D. D.) 150
Чен (Chen Р. Р.) 6, 25
Чин (Chin F. Y.) 286
Шварц (Schwartz М. D.) 286
Шенк (Schenk К. L.) 190
Шипмэн (Shipman D. W.) 317
Школьник (.Shkolnick М.) 71, 317
Шлорер (Schlorer J.) 286
Шмид (Schmidt Н, А.) 151
Эллис (Ellis С. S.) 317
Эпштейн (Epstein R.) 317
Эсверен (Eswaran К. Р.) 317
Ю (Yu С. Т.) 286
Юзефи (Youssefi К.) 150, 215
Ядзима (Yajima S.) 189
Янакейкиз (Yannakakis М.) 215, 317
Яо А. К. (Yao А. С.) 284, 286
Яо С. Б. (Yao S. В.) 71, 215
Яо Ф. Ф. (Yao F. F.) 71
ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ
Агрегация 151
Администратор базы данных 15
Адрес 26
Аксиомы Армстронга 157
— многозначных зависимостей 180—183
— функциональных зависимостей 157—
160, 180—183
Аномалия включения 153, 172
— обновления 153, 172
— удаления 153, 172
Аргумент поиска сегмента 252
Арность отношения 73
Атом 103, 108
Атрибут 19, 73
— отношения 73
----непервичиый 171
----первичный 171
База данных 10
----концептуальная 12, 14, 16
---- логическая 241—242, 253—259
---- реляционная 74
---- статистическая 279
----физическая 11—12, 241
Базис зависимостей 183
Базисная организация хранения 261
Бесконечное ожидание 290—292
Бит «заполнеи/свободеи» 31
Бит удаления 29, 31, 262
Блок 26
— первичный 260, 264
— переполнения 260, 264
— связи программы 245
— спецификации программы 245
— условия 145
— физический 26
Блокировка 288—290, 294
— для записи 298—301
— для чтения 298—301
Вид обработки 245
Включение 32, 39—40, 44, 49, 60, 79,
86, 123, 132, 143—144, 230—233, 261—
262, 264—265
Владелец набора DBTG 217
Восстановление базы данных 312—315
Выражение безопасное 105—109
— вида «селекция-проекция-соедцнеиие»
1'15
— регулярное 56
Вхождение переменной свободное 103—
104, 108, 122—123
----связанное 103—104, 108
Гнперграф 204
Гиперребро 204
Граф предшествований 295
— связей 204—209
Данные пересечения 256
Декартово произведение отношений 72,
99, 106, 127, 191—197, 202—204
Декомпозиция запросов 202—209
— схем отношений 164—179, 185—187
Диаграмма объектов-связей 23
Домен 19, 72
Доступ к блоку 27
Дубликаты кортежей 126, 132—133
Журнал 312—313
Зависимость данных 152
— встроенная 187—188
— многозначная 179—180
— соединений 189
— транзитивная 171—173
— тривиальная 157
— функциональная 153—164, 166—189
— частичная 171
Заголовок блока 28
Законы ассоциативности 195—196
— де Моргаиа 147
— коммутативности 195—196
Замыкание множества зависимостей
156, 183—184
---атрибутов 1591—162
Запись 26
— базы данных 244, 259
— закрепленная 28—29, 42—46, 54
— логическая 81
— незакрепленная 28, 38—42
— переменной длины 26, 54—60, 91'—93
Запрос 80—81, 86—87
— конъюнктивный 210—215
— линейный 280—283
Защита от отказов 11, 311—315
Идентификатор кортежа 129
Идентификация пользователя 275—276
Иерархия 87
Избыточность данных 152
Индекс 36, 53—54, 61, 63—64
— вторичный 61, 63—64, 136, 146, 192—
193, 239, 265
— многоуровневый 47
— первичный 61
— плотный 52—54, 129
— разреженный 36, 54, 260
Инстанцнация 205—209
Интерпретатор 10
Квантор 104
Класс сохранения членства в наборе 237
Ключ базы данных 220, 225
— записи поисковый 39
— отношения 156—157, 144, 146, 172,
272
---возможный 157
---первичный 156
— файла 19, 28, 30, 59—61
— полный сцепленный 246
Код модификации команды 252
КОДАСИЛ 5, 7, 15, 25, 72, 216, 222, 240
Компонент кортежа 73
Компрометация базы данных 280
Конкатенация 141
яоо
Копня базы данных для восстановления
312
Кортеж 73, 81
Куча 29, 136
Лес 87
Метод доступа HDAM 264—267
----HIDAM 262—264, 266—267
----HISAM 260—262, 266—267
----HSAM 260, 266—267
----ISAM 136
----ISAM/OSAM 261
----VSAM 261, 267
Множество чтения транзакции 301
— записи транзакции 301
Модель данных 13, 72
----иерархическая 13, 87—93, 271 —
304, 307
----объектов-связей 10, 18—23, 28
----реляционная 13, 72—81, 98—215,
272—279
----сетевая 13, 81—87, 241—270
Модификация 31, 39, 44, 49, 80, 86,
123—124, 144, 234, 250—251
Мультисписок 84, 87
Набор объектов-связей 19, 20, 74
— DBTG 217—218, 221—223, 227—240,
258—259, 271—272
----сингулярный 228
Навигация в базе данных 80, 224—230
Независимость данных 18
---- логическая 18
----физическая 18
— операторов 150
Неопределенное знамение 123, 151
Нормальная форма Бойса'—Кодда 170,
172—176, 185, 188—189
---- вторая 171
---- первая 171
----третья 170—172, 176—179
---- четвертая 185—186
Область базы данных 237—238
— ввода-вывода 247
Обобщение 20, 151
Объединение отношений 99, 104, 131'—
132, 197
Объект 19
Оператор FIND 224—230, 235
— GET 247—250
— STORE 230
Описание базы данных 241—244, 255—
257
Определенный триггер 273—274
Оптимизация запросов 191—215
Отношение 72—74
Отображение 74, 121, 125, 210—211
Отчет ANSI/SPARC 25
Память вторичная 26—27
Параллелизм 287—317
Пароль 275—276
Переменная, определенная на домене
108
Переменная-кортеж 103
Пересечение отношений 101
Планировщик 293
Подсхема 14, 216
Поиск 26, 31, 37—39, 44, 48—49, 80
— двоичный 37
— линейный 37
— по частичному соответствию 63—69
— с помощью вычисления адреса 38
Покрытие множества зависимостей 162—
164
------минимальное 163—164
Поле записи 81
Полиграф транзакций 304
Полное множество аксиом 157
— семейство зависимостей 156
Порядок лексикографический 35
— прямой (сверху вниз) 92—93, 263
Правило вывода 157
---надежное 157—1'58
— декомпозиции 158, 182
— дополнения 181
— объединения 158, 182
— пополнения 157, 180—181
— псевдотранзитивности 158, 182
— рефлексивности 157, 180
— транзитивности 157, 180—181
Право доступа 276—279
Предложения DBTG 25, 216—241, 258—
259, 271—272, 276-277
Представление 14—17, 2211—222, 245—
246, 276—277
— только для чтения 276
Прерывание 271
Проекция отношения 99—100, 104,
193—194, 196—197
— множества зависимостей 169
Протокол 293
— двухфазный 297, 301, 307
— для дерева элементов 308—309
— ОАГ 317
— с предупреждениями 310—311
Процесс 223
330
Рабочая область пользователя 222
Разбиение 206—209
Разность отношений 99, 197
Расписание транзакций 289, 293
— легальное 289
— последовательное 293
— сериализуемое 292—304, 306—307,
309,311,317
Реляционная алгебра 98—103, 106—108,
110—115, 194—202
Реляционное исчисление 103—113, 122,
130—131
----с переменными-кортежами 103—
1'10, 122, 130—131
----с переменными на доменах 108—
113, 136, 138
Сборка мусора 29
Свертка 2111—215
Сверхключ 157
Связь 20, 811—82, 86, 130
— вида «многие к одному» 21, 81—82,
85
----«многие ко многим» 21, 89—90,
257—258
----«один к одному» 21
Сегмент 241
— логически исходный 254—255
----порожденный 254
— текущий исходный 249
— целевой 247
— чувствительный 245
Секретность 10, 16, 239, 275—286
Селекция 100, 104, 193—194, 196—197
— набора DBTG 221, 230—232, 239
Семантика 151
Сеть 81, 89
Синхронизация 11
Система управления базами данных
(СУБД) 10
— ADABAS 240
— IDMS 240
— IMS 57, 72, 241—269, 271, 276—277
288
— INGRES 7, 130, 136, 150, 209, 286
— PRTV 115, 120
— Query-by-Example 7, 95, 150, 272, 286
— SIBAS 217
— System R 95, 128—130, 150, 209, 276
— System 2000, 269
— TOTAL 240
Схема базы данных 12, 74
-------концептуальная 12—16
-------физическая 12—13, 16
— отношения 74
Таблица ограничений 275
— предоставляемых прав 279
Тип записи 81, 217
---логической 81, 217, 241
------- виртуальной 87
--- владельца набора 217
--- члена набора 217
Транзакция 287—288
— аннулированная 312—315
— бесполезная 303
— двухфазная 297—298
— завершенная 313
— зафиксированная 313—315
— начальная 303
— финальная 303
Транзитивное замыкание 150
Тупик 290—292
Удаление 32, 40, 44, 49—50, 60, 79, 123,
131, 143—144, 233—235, 261—262, 264-
265
Указатель 27—29, 254, 259
— зависший 27
— вида порожденный/подобный 263—
266
— иерархический 263—266
— текущего состояния 222—223, 229,
247
Универсальное множество атрибутов 157
Управление блокировками 288
Участок 29
Файл 26
— главный 36
— инвертированный 61
— индекса 36
— индексированный 35
— логический 55
— реляционный для записи 120
--- для чтения 120
— с записями переменной длины 54
— с плотным индексом 52—54
— сортированный 35—46
— хешированный 29
— цепной 42, 45—46
Фиксация транзакции 313—315
---двухфазная 313—314
Форма таблицы 137
Формат записи 26
331
---- логической 81
----переменной длины 55
Функция агрегатная 124—125, 135, 143
— хеширования (хеш-функция) 30, 225,
264—265
---- раздельного 64—65
Хеширование 29—35, 54, 136, 225, 235,
264—265
Целостность базы данных 10, 152—154,
270—275, 286—287
Цепь 42, 84—85
Частное отношений 101
Член набора DBTG 217
Эквивалентность выражений 194—195,
— запросов 211
— множеств зависимостей 162
— расписаний 293, 299, 302—303
Эквисоединение отношений 102
Экземпляр набора DBTG 217, 227—233,
237—238
Элемент блокирования 288
— данных 217
Язык Ассемблера 222, 242, 246—247
— включающий 17
— запросов 16
----естественный 151
----полный 113, 117, 127—128, 133,
146—147
— манипулирования данными 16—17,
95, 98—151, 216, 222—230, 233—234, 271,
288
— непроцедурный 115
— определения данных 13, 15—16, 218—
219, 228, 230—232, 235—239, 242
------подсхемы 16
— Алгол-60 116
— АПЛ 10, 95
— Кобол 17, 216, 222, 240, 246—247, 249
— Лисп 95
— Паскаль 97
— ПЛ/1 17, 95, 97, 120, 128, 145, 222,
246, 247, 249, 252, 271
— Сетл 95
— Снобол 23, 95
— Фортран 95, 222
— «С» 97
— DL/1 246—253, 288
— ISBL 6, 98, 115—120, 149—150, 194,
215, 221, 276
— QUEL 6—7, 98, 130—136, 149—150,
192, 194, 202—210, 215, 288
— Query-by-Example (QBE) 6, 95, 98,
136—150, 210, 215, 221, 272—277, 285—
286
— SEQUEL 6, 98, 120—121, 125—130,
149—150, 194, 210, 216, 288
— SQUARE 6, 98, 120—127, 149—150,
194, 210, 215
В-дерево 47—52, 54, 129, 307—308
CALC-ключ 220—221, 225—226, 235, 240
NP-полнота 71, 189—190, 210, 304
Null-указатель 30
ON-условие 239, 271—272
СОДЕРЖАНИЕ
Предисловие к русскому изданию ................................. 5
Предисловие..................................................... 9
Глава 1. ОБЩЕЕ ПРЕДСТАВЛЕНИЕ О СИСТЕМЕ БАЗ ДАННЫХ. ... 10
1.1. Система баз данных..........................................10
1.2. Уровни абстракции в СУБД....................................11
1.3. Различие восприятий базы данных.............................15
1.4. Модель реального мира.......................................18
Упражнения...................................................... 23
Библиографические замечания......................................25
Глава 2. ФИЗИЧЕСКАЯ ОРГАНИЗАЦИЯ ДАННЫХ..............................26
2.1. Модель организации внешней памяти...........................26
2.2. Хешированные файлы..........................................29
2.3. Индексированные файлы.......................................35
2.4. В-деревья.......................ч...........................47
2.5. Файлы с плотным индексом........... ........................52
2.6. Файлы с записями переменной длины...........................54
2.7. Структуры данных для поиска по неключевым полям.............60
2.8. Поиск по частичному соответствию............................63
Упражнения.......................................................70
Библиографические замечания ................................... 71
Глава 3. ТРИ ЗАМЕЧАТЕЛЬНЫЕ МОДЕЛИ ДАННЫХ............................72
3.1. Реляционная модель данных...................................72
3.2. Сетевая модель данных.......................................81
3.3. Иерархическая модель данных.................................87
3.4. Сравнение моделей...........................................93
Упражнения.......................................................96
Библиографические замечания......................................97
Глава 4. ЯЗЫКИ МАНИПУЛИРОВАНИЯ ДАННЫМИ ДЛЯ РЕЛЯЦИ-
ОННОЙ МОДЕЛИ...................................................98
4.1. Реляционная алгебра......................................98
4.2. Реляционное исчисление...................................ЮЗ
4.3. Общие замечания относительно языков запросов.......... 113
4.4. ISBL: «чистый» язык реляционной алгебры....................П5
4.5. SQUARE и SEQUEL: эволюционные шаги от алгебраических язы-
ков к языкам исчисления.......................................120
4.6. QUEL: язык реляционного исчисления с переменными-кортежами. . 130
4.7. Query-by-Example: язык исчисления с переменными иа доменах. . 136
Упражнения.......................................................148
Библиографические замечания .....................................150
Глава 5. ТЕОРИЯ ПРОЕКТИРОВАНИЯ РЕЛЯЦИОННЫХ БАЗ ДАННЫХ 152
5.1. Почему проект базы данных может быть плохим?...............152
5.2. Функциональные зависимости.................................153
5.3. Декомпозиция схем отношений................................164
5.4. Нормальные формы схем отношений............................170
5.5. Многозначные зависимости...................................179
5.6. Четвертая нормальная форма............................... 185
Упражнения.................................................... 188
Библиографические замечания.................................... 189
Глава 6. ОПТИМИЗАЦИЯ ЗАПРОСОВ............................191
6.1. Общие замечания об оптимизации...................191
333
6.2. Алгебраическое манипулирование............................192
6.3. Алгоритм декомпозиции для языка QUEL......................202
6.4. Точная оптимизация для подмножества реляционных запросов .... 209
Упражнения.....................................................2J4
Библиографические замечания ...................................215
Глава 7. ПРЕДЛОЖЕНИЯ DBTG..........................................216
7.1. Основные концепции DBTG...................................217
7.2. Программная обстановка....................................222
7.3. Навигация в базе данных...................................224
7.4. Другие команды базы данных................................230
7.5. Некоторые дополнительные возможности предложений DBTG . . . 235
Упражнения.....................................................240
Библиографические замечания....................................240
Глава 8. IMS: ИЕРАРХИЧЕСКАЯ СИСТЕМА................................241
8.1. Обзор системы.............................................241
8.2. Язык манипулирования данными..............................246
8.3. Логические базы данных................................... 253
8.4. Организация хранения данных............................. 259
Упражнения.....................................................267
Библиографические замечания....................................269
Глава 9. ЗАЩИТА БАЗЫ ДАННЫХ........................................270
9.1. Целостность данных........................................270
9.2. Ограничения целостности данных в языке Query-by-Example . . . 272
9.3. Секретность...............................................275
9.4. Секретность в системе Query-by-Example....................277
9.5. Секретность в статистических базах данных.................279
Упражнения.....................................................285
Библиографические замечания....................................286
Глава 10. ПАРАЛЛЕЛЬНЫЕ ОПЕРАЦИИ НАД БАЗОЙ ДАННЫХ. . . 287
10.1. Основные концепции.......................................287
10.2. Простая модель транзакции................................294
10.3. Модель с блокировками для чтения и записи ...............298
10.4. Модель «только чтение/только запись».....................301
10.5. Параллельный доступ к иерархически структуризованным элементам 307
10.6. Защита от отказов........................................311
Упражнения.....................................................316
Библиографические замечания....................................317
Литература.........................................................318
Именной указатель..................................................327
Предметный указатель...............................................329
Ульман Дж.
У51 Основы систем баз данных / Пер. с англ. М. Р. Кога-
ловского и В. В. Когутовского; Под ред. М. Р. Когаловско-
го. — М.: Финансы и статистика, 1983. — 334 с., ил.
В пер.: 1 р. 90 к.
Излагаются концепции многоуровневого представления данных, архитектуры
СУБД, организации среды хранения данных, три основных типа моделей данных,
языковые средства реляционной модели. Рассматриваются основы теории проек-
тирования реляционных БД, методы оптимизации запросов, обеспечения целост-
ности БД и защиты данных от несанкционированного использования, а также уп-
равления параллельными процессами в среде СУБД.
Для пользователей и разработчиков СУБД, специалистов по системам обра-
ботки данных. Может служить пособием для учебных курсов.
2405000000—134 ББК 32.973
010(01)—83 6Ф7.3
Дж. Ульман
ОСНОВЫ СИСТЕМ БАЗ ДАН'НЫХ
Книга одобрена на заседании секции редсовета по электронной обработке
данных в экономике 12 марта 1981 г.
Зав. редакцией А. В. Павлюков
Редактор Н. К. Логинова
Мл. редактор О. Б. Степанченко
Техн, редактор И. В. Завгородняя
Корректоры Г. В. Хлопцева, Я. Б. Островский, М. А. Синяговская,
Т. М. Иванова
Художественный редактор О. И. Поленова
Переплет художника А. В. Амаспюра
ИБ Ns 1232
Сдано в набор 15.11.82. Подписано в печать 15.08.83.
Формат 70Х 100'/i6. Бум. тип. № 2. Гарнитура «Литературная».
Печать офсетная. Усл. печ. л. 27,3. Уч.-изд. л. 27,0. Тираж 20 000 экз.
Заказ 1315 Цена 1 р. 90 к.
Издательство «Финансы и статистика»,
101000, Москва, ул. Чернышевского, 7
Московская типография № 4 Союзполиграфпрома
при Государственном комитете СССР
по делам издательств, полиграфии и книжной торговли
129041, Москва, Б. Переяславская ул., д. 46