/
Author: Дейт К.Дж.
Tags: компьютерные технологии информатика программное обеспечение базы данных
ISBN: 5-8459-0138-3
Year: 2001
Text
Введение
(СИСТЕМЫ БАЗ
ДАННЫХ
AN INTRODUCTION TO
Database
Systems
SEVENTH
EDITION
ВВЕДЕНИЕ В
системы
баз данных
СЕДЬМОЕ
ИЗДАНИЕ
К. Дж. Дейт
Москва • Санкт-Петербург • Киев
2001
ББК 32.973.26-018.2.75
Д27
УДК 681.3.07
Издательский дом “Вильямс”
Перевод с английского канд.физ.-мат.наук Ю Г Гордиенко,
В В Репецкого, А.В. Слепцова
Под редакцией А.В. Слепцова
По общим вопросам обращайтесь в Издательский дом “Вильямс”
по адресу: info@williamspublishing.com, http://www.williamspublishing com
Дейт, К., Дж.
Д27 Введение в системы баз данных, 7-е издание. : Пер. с англ. — М. : Издательский
дом “Вильямс”, 2001. — 1072 с. : ил. — Парал. тит. англ.
ISBN 5-8459-0138-3 (рус.)
Новое издание фундаментального труда Криса Дейта— одного из наиболее
уважаемых во всем мире экспертов и мыслителей в области технологии баз данных —
несомненно, вызовет интерес у программистов-профессионалов, научных работников и
студентов, изучающих соответствующие курсы в высших учебных заведениях. Эта
книга содержит исчерпывающее изложение как классических идей в области реляцион-
ной теории, так и развернутое обсуждение наиболее современных практических
решений и технологий в области проектирования, реализации и сопровождения баз
данных. Несмотря на исключительную глубину рассмотрения предмета, материал
излагается простым и ясным языком и сопровождается большим количеством
практических примеров. Книга, безусловно, будет полезна всем, кому приходится иметь
дело с базами данных или кто просто интересуется данной темой.
ББК 32.973.26-018.2.75
Все названия программных продуктов являются зарегистрированными торговыми марками
соответствующих фирм
Никакая часть настоящего издания ни в каких целях не может быть воспроизведена в какой бы то ни было
форме и какими бы то ни было средствами, будь то электронные или механические, включая
фотокопирование и запись на магнитный носитель, если на это нет письменного разрешения издательства
Addison-Wesley Publishing Company, Inc
Authorized translation from the English language edition published by Addison-Wesley Publishing Company,
Inc. Copyright © 2000
All rights reserved No part of this book may be reproduced or transmitted in any form or by any means,
electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without
permission from the Publisher
Russian language edition published by Williams Publishing House according to the Agreement with R&I
Enterprises International, Copyright © 2001
ISBN 5-8459-0138-3 (pyc)
ISBN 0-201-38590-2 (англ)
© Издательский дом “Вильямс”, 2001
© Addison-Wesley Longman, Inc, 2000
Эта книга посвящается моей жене Линди
и памяти моей матери Рине
Оглавление
Об авторе 23
Предисловие к седьмому изданию 24
ЧАСТЬ I. ОСНОВНЫЕ ПОНЯТИЯ 31
Глава 1. Базы данных и управление ими 32
Глава 2. Архитектура системы баз данных 65
Глава 3. Введение в реляционные базы данных 92
Глава 4. Введение в язык SQL 119
ЧАСТЬ II. РЕЛЯЦИОННАЯ МОДЕЛЬ 149
Глава 5. Домены, отношения и базовые переменные-отношения 151
Глава 6. Реляционная алгебра 192
Глава 7. Реляционное исчисление 243
Глава 8. Целостность данных 301
Глава 9. Представления 350
ЧАСТЬ III. ПРОЕКТИРОВАНИЕ БАЗЫ ДАННЫХ 397
Глава 10. Функциональные зависимости 400
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 422
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 469
Глава 13. Семантическое моделирование 505
ЧАСТЬ IV. УПРАВЛЕНИЕ ТРАНЗАКЦИЯМИ 543
Глава 14. Восстановление 544
Глава 15. Параллельность 566
ЧАСТЬ V. ДОПОЛНИТЕЛЬНЫЕ АСПЕКТЫ 601
Глава 16. Защита данных 602
Глава 17. Оптимизация 639
Глава 18. Отсутствующая информация 693
Глава 19. Наследование типов 725
Глава 20. Распределенные базы данных 767
Глава 21. Поддержка принятия решений 813
Глава 22. Хронологические базы данных 853
Глава 23. Логические системы управления базами данных 899
ЧАСТЬ VI. ОБЪЕКТНЫЕ И ОБЪЕКТНО-РЕЛЯЦИОННЫЕ
БАЗЫ ДАННЫХ 943
Глава 24. Объектные базы данных 944
Глава 25. Объектно-реляционные базы данных 999
ПРИЛОЖЕНИЯ 1027
Приложение А. Выражения языка SQL 1028
Приложение Б. Обзор языка SQL3 1041
Приложение В. Сокращения и специальные символы 1058
6
Оглавление
Содержание
Об авторе , 23
Предисловие к седьмому изданию 24
ЧАСТЬ I
Основные понятия 31
Глава 1. Базы данных и управление ими 32
1.1. Вводный пример 32
1.2. Что такое система баз данных 35
Данные 35
Аппаратное обеспечение 37
Программное обеспечение 38
Пользователи 39
1.3. Что такое база данных 40
Перманентные данные 40
Сущности и связи 41
Свойства 43
Данные и модели данных 44
1.4. Назначение баз данных 45
Администрирование данных и администрирование базы данных 46
Преимущества централизованного подхода к управлению данными 47
1.5. Независимость данных 50
1.6. Реляционные и другие системы 56
1.7. Резюме 59
Упражнения 59
Список литературы 61
Ответы к некоторым упражнениям 62
Глава 2. Архитектура системы баз данных 65
2.1. Введение 65
2.2. Три уровня архитектуры 65
2.3. Внешний уровень 68
2.4. Концептуальный уровень 72
2.5. Внутренний уровень 73
2.6. Отображения 74
2.7. Администратор базы данных 74
2.8. Система управления базой данных 77
2.9. Система управления передачей данных 81
2.10. Архитектура “клиент/сервер” 81
2.11. Утилиты 83
2.12. Распределенная обработка 84
2.13. Резюме 88
Содержание
7
Упражнения 88
Список литературы 90
Глава 3. Введение в реляционные базы данных 92
3.1. Введение 92
3.2. Реляционная модель 92
3.3. Отношения и переменные-отношения 97
3.4. Смысл отношений 99
3.5. Оптимизация 101
3.6. Каталог 104
3.7. Базовые переменные-отношения и представления 105
3.8. Транзакции 109
3.9. База данных поставщиков и деталей 110
3.10. Резюме 113
Упражнения 115
Список литературы 116
Ответы к некоторым упражнениям 117
Глава 4. Введение в язык SQL 119
4.1. Введение 119
4.2. Обзор языка SQL 120
4.3. Каталог 124
4.4. Представления 125
4.5. Транзакции 126
4.6. Внедрение SQL-операторов 126
Операции, не использующие курсоры 130
Операции, использующие курсоры 131
Динамический SQL 134
4.7. Несовершенство языка SQL 136
4.8. Резюме 136
Упражнения 137
Список литературы 140
Ответы к некоторым упражнениям 145
ЧАСТЬ II
Реляционная модель 149
Глава 5. Домены, отношения и базовые переменные-отношения 151
5.1. Введение 151
5.2. Домены 152
Каждое значение имеет тип 154
Определение типа 155
Допустимые представления 156
Определение операторов 159
Преобразование типов 161
Заключительные замечания 162
8
Содержание
5.3. Значения отношений 163
Свойства отношений 166
Атрибуты, значениями которых являются отношения 168
Отношения и их интерпретация 169
5.4. Переменные-отношения 169
Определение базовых переменных-отношений 169
Обновление переменных-отношений 171
5.5. Средства SQL 174
Домены 174
Базовые таблицы 177
5.6. Резюме 178
Упражнения 180
Список литературы 181
Ответы к некоторым упражнениям 185
Глава 6. Реляционная алгебра 192
6.1. Введение 192
Обзор операций начальной алгебры 192
6.2. Реляционная замкнутость 195
6.3. Синтаксис 197
6.4. Семантика 199
Объединение 199
Пересечение 200
Вычитание 200
Произведение 201
Выборка 202
Проекция 203
Соединение 205
Деление 207
Ассоциативность и коммутативность 208
6.5. Примеры 209
6.5.1. Получить имена поставщиков детали с номером ‘Р2’ 209
6.5.2. Получить имена поставщиков по крайней мере одной красной
детали 209
6.5.3. Получить имена поставщиков всех типов деталей 209
6.5.4. Получить номера поставщиков по крайней мере тех типов
деталей, которые поставляет поставщик с номером ‘S2’ 210
6.5.5. Получить все пары номеров поставщиков, находящихся в одном
городе 210
6.5.6. Получить имена поставщиков, которые не поставляют деталь с
номером ‘Р2’ 210
6.6. Зачем нужна реляционная алгебра 211
6.7. Дополнительные операторы 213
Полусоединение 214
Полувычитание 214
Операция расширения 215
Операция обобщения 218
Содержание 9
Транзитивное замыкание 221
6.8. Группирование и разгруппирование 222
6.9. Реляционные сравнения 225
6.10. Резюме 227
Упражнения 227
Упражнения по составлению запросов 228
Список литературы 231
Ответы к некоторым упражнениям 234
Глава 7. Реляционное исчисление 243
7.1. Введение 243
7.2. Исчисление кортежей 245
Синтаксис 245
Переменные кортежей 247
Свободные и связанные переменные кортежей 248
Кванторы 249
Еще раз о свободных и связанных переменных 251
Реляционные операции 252
7.3. Примеры 253
7.3.1. Определить номера поставщиков из Парижа со статусом,
большим 20 254
7.3.2. Найти все такие пары номеров поставщиков, в которых два
поставщика находятся в одном городе 254
7.3.3. Определить имена поставщиков детали с номером ‘Р2’ 254
7.3.4. Определить имена поставщиков по крайней мере одной красной
детали 254
7.3.5. Найти имена поставщиков по крайней мере одной детали,
поставляемой поставщиком с номером ‘S2’ 255
7.3.6. Выбрать имена поставщиков всех типов деталей 255
7.3.7. Определить имена поставщиков, которые не поставляют деталь с
номером ‘Р2’ 255
7.3.8. Определить номера поставщиков по крайней мере всех типов
деталей, поставляемых поставщиком с номером ‘S2’ 256
7.3.9. Получить номера деталей, которые либо весят более 16 фунтов,
либо поставляются поставщиком с номером ‘S2’, либо и то, и другое 256
7.4. Сравнительный анализ реляционного исчисления и реляционной алгебры 257
7.5. Вычислительные возможности 262
7.5.1. Определить номера и вес в граммах всех типов деталей, вес
которых превышает 10 000 г 262
7.5.2. Выбрать сведения обо всех поставщиках, добавив для каждого из
них литеральное значение ‘Поставщик’ 262
7.5.3. Выбрать сведения о каждой поставке и указать полные данные о
входящих в нее типах деталей и общий вес поставки 263
7.5.4. Для каждой детали выбрать номер и общий объем поставки в
штуках 263
7.5.5. Определить общее количество поставляемых деталей 263
10
Содержание
7.5.6. Для каждого поставщика указать номер и общий объем поставки
в штуках 263
7.5.7. Указать названия городов, в которых находится более пяти
красных деталей 263
7.6. Исчисление доменов 263
7.6.1. Выбрать номера поставщиков из Парижа со статусом, большим 20 265
7.6.2. Найти все такие пары номеров поставщиков, в которых два
поставщика находятся в одном городе 265
7.6.3. Определить имена поставщиков по крайней мере одной красной
детали 265
7.6.4. Определить номера поставщиков всех типов деталей,
поставляемых поставщиком с номером ‘S2’ 265
7.6.5. Выбрать имена поставщиков всех типов деталей 265
7.6.6. Определить имена поставщиков, которые не поставляют деталь с
номером ‘Р2’ 266
7.6.7. Определить номера поставщиков всех типов деталей,
поставляемых поставщиком с номером ‘S2’ 266
7.6.8. Получить номера деталей, которые либо весят более 16 фунтов,
либо поставляются поставщиком с номером ‘S2’, либо и то, и другое 266
7.7. Средства языка SQL 266
7.7.1. Указать цвета деталей и названия городов, в которых находятся
детали “не из Парижа” с весом, превышающим 10 фунтов 267
7.7.2. Для всех деталей указать номер и вес в граммах 269
7.7.3. Выбрать информацию обо всех парах поставщиков и деталей,
находящихся в одном городе 269
7.7.4. Найти все пары названий городов, таких, что поставщик из
первого города поставляет деталь, находящуюся во втором городе 270
7.7.5. Выбрать все пары номеров поставщиков, таких, что оба поставщика
в каждой паре находятся в одном городе 270
7.7.6. Определить общее количество поставщиков 271
7.7.7. Определить в поставках максимальное и минимальное количество
деталей с номером ‘Р2’ 271
7.7.8. Для каждой поставляемой детали указать номер и общий объем
поставки в штуках 272
7.7.9. Указать номера всех типов деталей, поставляемых более чем
одним поставщиком 273
7.7.10. Определить имена поставщиков детали с номером ‘Р2’ 273
7.7.11. Определить имена поставщиков по крайней мере одной красной
детали 274
7.7.12. Указать номера поставщиков, статус которых меньше текущего
максимального статуса в таблице S 274
7.7.13. Указать имена поставщиков детали с номером ‘Р2’ 274
7.7.14. Выбрать имена поставщиков, которые не поставляют деталь с
номером ‘Р2’ 275
7.7.15. Определить имена поставщиков всех типов деталей 275
7.7.16. Определить номера деталей, которые либо весят более 16 фунтов,
либо поставляются поставщиком с номером ‘S2’, либо и то, и другое 276
Содержание
11
7.8. Резюме 277
Упражнения 278
Упражнения по запросам 280
Список литературы 280
Ответы к некоторым упражнениям 284
Глава 8. Целостность данных 301
8.1. Введение 301
Схема классификации ограничений 303
8.2. Ограничения типа 303
8.3. Ограничения атрибута 305
8.4. Ограничения переменной-отношения 305
8.5. Ограничения баз данных 306
8.6. “Золотое правило” 307
8.7. Ограничения состояния и ограничения перехода 309
8.8. Ключи 311
Потенциальные ключи 311
Первичные и альтернативные ключи 314
Внешние ключи 315
Ссылочные операции 319
Триггерные процедуры 321
8.9. Средства языка SQL 322
Ограничения домена 323
Ограничения базовой таблицы 323
Утверждения 325
Откладываемая проверка 326
8.10. Резюме 327
Упражнения 328
Список литературы 331
Ответы к некоторым упражнениям 337
Глава 9. Представления 350
9.1. Введение 350
Дополнительные примеры 352
Определение и удаление представлений 352
9.2. Для чего нужны представления 353
Логическая независимость данных 354
Два важных принципа 356
9.3. Выборка данных из представлений 357
9.4. Обновление данных в представлениях 358
Еще раз о “золотом правиле” 359
Механизм обновления представления 360
Операция объединения 363
Операция пересечения 366
Операция вычитания 367
Операция выборки 367
Операция проекции 368
Операция расширения 370
12
Содержание
Операция соединения 372
Прочие операции 377
9.5. Моментальные снимки 378
9.6. Поддержка представлений в языке SQL 380
Выборка данных из представлений 381
Обновление данных в представлениях 381
9.7. Резюме 383
Упражнения 383
Список литературы 386
Ответы к некоторым упражнениям 389
ЧАСТЬ III
Проектирование базы данных 397
Глава 10. Функциональные зависимости 400
10.1. Введение 400
10.2. Основные определения 401
10.3. Тривиальные и нетривиальные зависимости 404
10.4. Замыкание множества зависимостей 405
10.5. Замыкание множества атрибутов 407
10.6. Неприводимые множества зависимостей 409
10.7. Резюме 411
Упражнения 413
Список литературы 415
Ответы к некоторым упражнениям 417
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 422
11.1. Введение 422
Нормальные формы 424
Структура этой главы 425
11.2. Декомпозиция без потерь и функциональные зависимости 426
Еще о функциональных зависимостях 429
11.3. Первая, вторая и третья нормальные формы 430
11.4. Сохранение зависимостей 439
11.5. Нормальная форма Бойса-Кодда 442
11.6. Замечание по поводу атрибутов, содержащих в качестве значений
отношения 448
11.7. Резюме 450
Упражнения 452
Список литературы 455
Ответы к упражнениям 457
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 469
12.1. Введение 469
12.2. Многозначные зависимости и четвертая нормальная форма 469
12.3. Зависимости соединения и пятая нормальная форма 475
12.4. Общая схема процедуры нормализации 481
Содержание
13
12.5. Денормализация 483
Что такое денормализация 484
Другие проблемы 485
12.6. Ортогональное проектирование (небольшое отступление от темы) 486
Замечания 489
12.7. Другие нормальные формы 490
12.8. Резюме 491
Упражнения 492
Список литературы 493
Ответы к упражнениям 501
Глава 13. Семантическое моделирование 505
13.1. Введение 505
13.2. Общий подход 507
13.3. Модель “сущность/связь” 510
Сущности 511
Свойства 512
Связи 512
Подтипы и супертипы сущностей 513
13.4. ER-диаграммы 514
Сущности 515
Свойства 515
Связи 516
Подтипы и супертипы сущностей 516
13.5. Проектирование базы данных с помощью метода ER-моделирования 516
Сильные сущности 517
Связи типа “многие ко многим” 517
Связи типа “многие к одному” 519
Слабые сущности 519
Свойства 520
Супертипы и подтипы сущности 520
13.6. Краткий анализ ER-модели 522
ER-модель как основа реляционной модели 522
Является ли ER-модель моделью данных 523
Сравнительный анализ сущностей и связей 524
Заключительные замечания 525
13.7. Резюме 525
Упражнения 527
Список литературы 528
ЧАСТЬ IV
Управление транзакциями 543
Глава 14. Восстановление 544
14.1. Введение 544
14
Содержание
14.2. Транзакции 545
14.3. Восстановление транзакции 547
ACID-свойства транзакций 549
14.4. Восстановление системы 550
14.5. Восстановление носителей 552
14.6. Двухфазная фиксация 553
14.7. Поддержка языка SQL 554
14.8. Резюме 556
Упражнения 557
Список литературы 558
Ответы к некоторым упражнениям 563
Глава 15. Параллельность 566
15.1. Введение 566
15.2. Три проблемы параллельности 567
Проблема потери результатов обновления 567
Проблема зависимости от незафиксированных результатов 567
Проблема несогласованной обработки данных 569
15.3. Блокировка 569
15.4. Устранение трех проблем параллельности 572
Проблема потери результатов обновления 572
Проблема зависимости от незафиксированных результатов 572
Проблема несогласованной обработки данных 573
15.5. Взаимная блокировка 575
15.6. Упорядочиваемость 576
15.7. Уровни изоляции 578
15.8. Блокировка намерения 580
15.9. Средства языка SQL 583
Уровни изоляции 583
15.10. Резюме 585
Упражнения 586
Список литературы 588
Ответы к некоторым упражнениям 596
ЧАСТЬ V
Дополнительные аспекты 601
Глава 16. Защита данных 602
16.1. Введение 602
Общие соображения 602
16.2. Избирательная схема управления доступом 605
Модификация запроса 609
Контрольное слежение 610
16.3. Мандатная схема управления доступом 611
Многоуровневая защита 613
Содержание
15
16.4. Статистические базы данных 615
16.5. Шифрование данных 621
Стандарт шифрования данных 622
Шифрование на основе открытого ключа 623
16.6. Средства языка SQL 626
Представления и защита данных 626
Операторы GRANT и REVOKE 628
16.7. Резюме 630
Упражнения 631
Список литературы 632
Ответы к некоторым упражнениям 635
Глава 17. Оптимизация 639
17.1. Введение 639
17.2. Пример выполнения оптимизации 641
17.3. Оптимизация запросов 642
Стадия 1. Преобразование запроса во внутреннюю форму 643
Стадия 2. Преобразование запроса в каноническую форму 644
Стадия 3. Выбор потенциальных низкоуровневых процедур 645
Стадия 4. Генерация различных вариантов планов вычисления запроса
и выбор плана с минимальными затратами 646
17.4. Преобразование выражений 647
Выборки и проекции 647
Распределительный закон 648
Коммутативность и ассоциативность 649
Идемпотентность 650
Вычисляемые скалярные выражения 650
Логические выражения 650
Семантические преобразования 651
Заключительные замечания 653
17.5. Статистические показатели базы данных 653
17.6. Стратегия по принципу “разделяй и властвуй” 654
17.7. Реализация реляционных операторов 658
Последовательный просмотр 659
Поиск по индексу 661
Поиск по хеш-таблице 662
Метод слияния 662
Хеширование 663
17.8. Резюме 663
Упражнения 665
Список литературы 668
Ответы к некоторым упражнениям 691
Глава 18. Отсутствующая информация 693
18.1. Введение 693
18.2. Обзор концепции трехзначной логики 695
Логические выражения 695
Кванторы EXISTS и FORALL 696
16
Содержание
Вычисляемые скалярные выражения 697
UNK. — это не ипк . 698
Могут ли домены содержать величину UNK 698
Реляционные выражения 699
Операции обновления 700
Ограничения целостности 700
18.3. Некоторые следствия изложенной схемы 700
Преобразование выражений 701
Пример с базой данных отделов и сотрудников 702
Проблема интерпретации 703
Еще раз о предикатах 704
18.4. Отсутствующие значения и ключи 704
Первичные ключи 705
Внешние ключи 706
18.5. Внешнее соединение 707
18.6. Специальные значения 711
18.7. Поддержка неопределенных значений в языке SQL 711
Определение данных 712
Табличные выражения 712
Условные выражения 712
Скалярные выражения 713
Ключи 714
Внедренные SQL-операторы 715
18.8. Резюме 715
Упражнения 717
Список литературы 719
Ответы к некоторым упражнениям 723
Глава 19. Наследование типов 725
19.1. Введение 725
Почему используется наследование типов 727
Предварительные замечания 727
19.2. Иерархия типов 729
Терминология 731
Предположение о несвязности 732
Физическое представление 733
19.3. Полиморфизм и заменимость 733
Полиморфизм 733
Полиморфизм в программировании 735
Заменимость 736
19.4. Переменные и операция присвоения 737
Скалярные переменные 738
Пересмотр понятия заменимости 739
Оператор TREAT DOWN 739
19.5. Специализация по ограничениям 741
Пересмотр оператора ТНЕпсевдопеременная 742
Горизонтальное изменение типов 743
Содержание
17
19.6. Операции сравнения 744
Сравнения в реляционной алгебре 744
Операторы проверки типа 746
19.7. Операторы, версии и сигнатуры 748
Сигнатуры 749
Операторы чтения и обновления 751
Изменение семантики оператора 751
19.8. Является ли окружность эллипсом 753
Об изменении семантики 754
Существует ли гибкая модель 754
Решение проблемы 755
19.9. Пересмотр специализации ограничением 757
Наследование возможных представлений 757
Действительный смысл понятия подтипа 758
19.10. Резюме 759
Упражнения 761
Список литературы 762
Ответы к некоторым упражнениям 764
Глава 20. Распределенные базы данных 767
20.1. Введение 767
20.2. Предварительные сведения 767
Преимущества 769
Примеры распределенных систем 770
Фундаментальный принцип 770
20.3. Двенадцать основных целей 772
1. Локальная независимость 772
2. Отсутствие опоры на центральный узел 772
3. Непрерывное функционирование 773
4. Независимость от расположения 773
5. Независимость от фрагментации 773
6. Независимость от репликации 777
7. Обработка распределенных запросов 778
8. Управление распределенными транзакциями 779
9. Аппаратная независимость 779
10. Независимость от операционной системы 779
11. Независимость от сети 780
12. Независимость от типа СУБД 780
20.4. Проблемы распределенных систем 780
Обработка запросов 781
Управление каталогом 783
Распространение обновлений 785
Управление восстановлением 787
Управление параллельностью 791
20.5. Системы “клиент/сервер” 792
Стандарты для систем “клиент/сервер” 794
Программирование приложений “клиент/сервер” 795
18
Содержание
20.6. Независимость от СУБД 796
Шлюзы 796
Промежуточное программное обеспечение для доступа к данным 799
Заключительное слово 801
20.7. Средства SQL 801
20.8. Резюме 802
Упражнения 803
Список литературы 804
Глава 21. Поддержка принятия решений 813
21.1. Введение 813
21.2. Некоторые аспекты технологии поддержки принятия решений 815
21.3. Проектирование базы данных поддержки принятия решений 817
Логическое проектирование 818
Физическое проектирование 820
Распространенные ошибки проектирования 825
21.4. Подготовка данных 826
Извлечение данных 827
Очистка данных 827
Преобразование и консолидация данных 827
Загрузка данных 828
Обновление данных 829
Банки оперативных данных 829
21.5. Хранилища данных и магазины данных 829
Хранилище данных 830
Магазины данных 831
Многомерные схемы 832
21.6. Оперативная аналитическая обработка 836
Многокоординатные таблицы 841
Многомерные базы данных 842
21.7. Разработка данных 844
21.8. Резюме 846
Упражнения 847
Список литературы 848
Ответы к некоторым упражнениям 851
Глава 22. Хронологические базы данных 853
22.1. Введение 853
22.2. Хронологические данные 855
Некоторые основные концепции и вопросы 856
22.3. Основная проблема хронологических баз данных 860
“Полуограниченные во времени” поставщики и поставки 861
Полностью хронологическая база данных поставщиков и поставок 863
22.4. Интервалы 867
22.5. Интервальные типы 869
22.6. Скалярные операторы для интервалов 871
22.7. Операторы обобщения для интервалов 873
22.8. Реляционные операторы для обработки интервалов 874
Содержание 19
22.9. Ограничения, включающие интервалы 881
22.10. Операторы обновления, включающие интервалы 885
22.11. Проектирование базы данных 887
Горизонтальная декомпозиция 887
Вертикальная декомпозиция 889
22.12. Резюме 891
Упражнения 892
Список литературы 893
Ответы к некоторым упражнениям 896
Глава 23. Логические системы управления базами данных 899
23.1. Введение 899
23.2. Обзор основных концепций 899
Дедуктивные аксиомы 901
23.3. Исчисление высказываний 902
Термы 903
Формулы 903
Правила вывода 904
Доказательства 905
23.4. Исчисление предикатов 907
Предикаты 907
Правильно построенные формулы 908
Интерпретации и модели 909
Стандартная форма 911
Использование правила резолюции 912
23.5. Базы данных с точки зрения доказательно-теоретического подхода 914
23.6. Дедуктивные СУБД 918
Язык Datalog 921
23.7. Обработка рекурсивных запросов 924
Унификация и резолюция 925
Наивное оценивание 926
Полунаивное оценивание 927
Статическое фильтрование 929
23.8. Резюме 930
Упражнения 932
Список литературы 934
Ответы к некоторым упражнениям 940
ЧАСТЬ VI
Объектные и объектно-реляционные базы данных 943
Глава 24. Объектные базы данных 944
24.1. Введение 944
Специальный пример 946
24.2. Объекты, классы, методы и сообщения 948
20
Содержание
Обзор объектной технологии 949
Переменные экземпляра 951
Идентификатор объекта 953
24.3. Еще раз об объектах и объектных классах 953
Еще раз об идентификаторе объекта 957
Классы, экземпляры и коллекции 958
Иерархии классов 961
24.4. Простой пример 962
Определение данных 963
Заполнение базы данных 966
Операции извлечения 970
Операции обновления 972
24.5. Дополнительные аспекты 973
Произвольные запросы 973
Целостность базы данных 974
Реализация связей 975
Языки программирования баз данных 977
Повышение производительности 978
Является ли объектная СУБД действительно СУБД? 980
24.6. Резюме 982
Упражнения 985
Список литературы 986
Ответы к некоторым упражнениям 996
Глава 25. Объектно-реляционные базы данных 999
25.1. Введение 999
25.2. Первая грубейшая ошибка 1002
Как возникла первая грубейшая ошибка 1010
25.3. Вторая грубейшая ошибка 1010
Как возникла вторая грубейшая ошибка 1012
25.4. Вопросы реализации 1013
Анализ запросов и проверка типа 1014
Оптимизация 1014
Структуры хранения 1015
25.5. Преимущества реального сближения двух технологий 1016
25.6. Резюме 1018
Список литературы 1018
Приложения 1027
Приложение А. Выражения языка SQL 1028
А. 1. Введение 1028
А.2. Табличные выражения 1028
Предложение SELECT 1030
Предложение FROM 1031
Предложение WHERE 1032
Предложение GROUP BY 1032
Содержание 21
Предложение HAVING 1033
Подробный пример 1033
А.З. Условные выражения 1035
Условие LIKE 1036
Условие MATCH 1038
Условие ALL или ANY 1038
Условие UNIQUE 1039
А.4. Скалярные выражения 1039
Оператор CASE 1040
Оператор CAST 1040
Приложение Б. Обзор языка SQL3 1041
Б. 1. Введение 1041
Б.2. Новые типы данных 1042
Встроенные скалярные типы данных 1042
Генерируемые типы 1043
Типы DISTINCT 1044
Структурированные типы 1045
Б.З. Наследование типов 1047
Б.4. Ссылочные типы 1049
Б.5. Подтаблицы и супертаблицы 1052
Б.6. Другие возможности 1054
Создание таблиц 1054
Табличные выражения 1054
Условные выражения 1055
Целостность 1056
Обновление представлений 1056
Управление транзакциями 1057
Безопасность 1057
Отсутствующая информация 1057
Поддержка принятия решений 1057
Приложение В. Сокращения и специальные символы 1058
Предметный указатель 1064
22
Содержание
Об авторе
К.Дж. Дейт (C.J. Date) — независимый публицист, лектор, ученый и консультант,
специализирующийся на технологии реляционных баз данных. Он живет в Хилдсбурге,
штат Калифорния.
Начиная с 1967 года Дейт несколько лет работал математиком-программистом и инст-
руктором по программированию в компании Leo Computers Ltd. (Лондон, Великобрита-
ния). После этого он работал в лаборатории IBM (UK) Development Laboratories над инте-
грацией функций баз данных в язык PL/1. В 1974 году он перешел в калифорнийский центр
IBM Systems Development Center, где отвечал за разработку языка баз данных, известного в
настоящее время как Unified Database Language (UDL). Впоследствии принимал участие в
техническом планировании и внешних проектах корпорации IBM для продуктов реляцион-
ных баз данных SQL/DS и DB2. В мае 1983 года он покинул компанию IBM.
Дейт работает в области баз данных почти 30 лет. Одним из первых он осознал осно-
вополагающее значение новаторской работы Э.Ф. Кодда (E.F. Codd) по реляционной мо-
дели. Дейт читал лекции по техническим вопросам (преимущественно по тематике баз
данных и, в частности, по реляционным базам данных) во всей Северной Америке, а
также в Европе, Австралии, Латинской Америке и на Дальнем Востоке. Он является ав-
тором или соавтором не только этой, но и других книг по базам данных: Foundation for
Object/Relational Databases: The Third Manifesto (1998), в которой даны развернутые
предложения по развитию данной области; Database: A Primer (1983), в которой базы
данных рассматриваются с точки зрения неспециалиста; серии книг Relational Database
Writings (1986, 1990, 1992, 1995 и 1998 годы), в которых фундаментально изложены раз-
личные вопросы реляционной технологии; а также другой серии книг, посвященной от-
дельным системам и языкам (A Guide to DB2 (4th edition, 1993), A Guide to SYBASE and
SQL Server (1992), A Guide to SQL/DS (1988), A Guide to INGRES (1987) и A Guide to the
SQL Standard (4th edition, 1997)'). Книги Дейта переведены на многие языки, в том числе
на греческий, датский, испанский, итальянский, китайский, корейский, немецкий, поль-
ский, португальский, русский, французский и японский. Кроме того, его книги изданы с
использованием шрифта Брайля для слепых.
Дейт опубликовал более 300 технических статей и научных работ и внес значитель-
ный вклад в теорию баз данных. Его работы постоянно публикуются в журналах
Database Programming & Design и Intelligent Enterprise. Профессиональные семинары по
технологии баз данных, проводимые им как в Северной Америке, так и за рубежом, при-
знаны непревзойденными по качеству представленного материала и ясности изложения.
Дейт с отличием закончил Кембриджский университет в Великобритании (1962—
1966) и получил диплом математика, а затем ученую степень доктора технических наук в
де Монфортском университете в Великобритании (1994).
Об авторе
23
Предисловие к седьмому
изданию
Настоящая книга представляет собой исчерпывающее введение в очень широкую в
настоящее время область теории баз данных. С ее помощью читатель сможет приобрести
фундаментальные знания в области технологии баз данных, а также ознакомиться с на-
правлениями, по которым эта область, вероятно, будет развиваться в будущем. Книга за-
думывалась как учебник, а не как справочник, но я надеюсь, что ее в какой-то мере мож-
но будет использовать и в качестве справочного руководства. В книге делается акцент на
усвоении сущности и глубоком понимании излагаемого материала, а не просто на его
формальном изложении.
Для кого предназначена эта книга
В ие юм, книга ориентирована на читателей, которые профессионально работают с
компьютерами в той или иной области и хотят получить общее представление о теории и
практическом использовании баз данных. Предполагается, что читатель имеет по край-
ней мере базовые знания в следующих областях:
средства управления памятью и файлами (индексация и т.д.) в современных ком-
пьютерных системах;
хотя бы один из языков программирования высокого уровня (например, С, Java,
Pascal, PL/I и т.д.).
Структура книги
Книга разделена на шесть частей.
1. Основные понятия.
2. Реляционная модель.
3. Проектирование базы данных.
4. Управление транзакциями.
5. Дополнительные аспекты.
6. Объектные и объектно-реляционные базы данных.
Каждая часть, в свою очередь, делится на несколько глав.
Часть I (четыре главы) — это обширное введение в теорию баз данных вообще и
реляционных баз данных в частности. Здесь также излагаются основы стандартно-
го языка баз данных SQL.
Часть II (пять глав) содержит детальное и весьма основательное описание реляци-
онной модели, которая является теоретической основой не только для собственно
реляционных систем, но фактически для всей технологии баз данных.
24
Предисловие к седьмому изданию
Часть III (четыре главы) включает обсуждение общих аспектов проектирования
баз данных. Три главы посвящены теории проектирования, а в четвертой рас-
сматривается семантическое моделирование и модель “сущность/связь”.
Часть IV (две главы) посвящена управлению транзакциями (т.е. обеспечению
процедур восстановления и поддержки параллельного доступа).
Часть V (восемь глав) — это некоторое “попурри”. Основное его назначение со-
стоит в описании применения реляционных понятий к различным аспектам техно-
логии баз данных, включая защиту данных, распределенные базы данных, хро-
нологические наборы данных, системы поддержки принятия решений ит.д.
Часть VI (две главы) содержит обсуждение объектной технологии и ее применения
в свете концепций баз данных. В последней главе книги, в частности, рассматрива-
ется возможность сближения между объектной и реляционной технологиями и об-
суждаются принципы построения объектно-реляционных систем.
Кроме того, в книге есть три приложения. В приложении А рассматриваются допол-
нительные возможности языка SQL, в приложении Б можно ознакомиться с концепция-
ми стандарта SQL3 (новой версии стандарта языка SQL, которая, по-видимому, уже бу-
дет утверждена как стандарт, когда эта книга выйдет в свет) и в приложении В перечис-
лены некоторые важные сокращения и аббревиатуры.
Замечание. Существует интерактивное руководство Instructor’s Manual, в котором
даны указания о том, как использовать эту книгу с целью преподавания учебного курса,
посвященного базам данных. В руководстве содержится множество замечаний, советов и
предложений по каждой главе и ее приложению, а также ответы к тем упражнениям, к
которым нет ответов в книге. Читатель найдет в нем и другие материалы, которые ока-
жут ему существенную помощь. Как получить доступ к этому руководству, можно узнать
в местном торговом представительстве издательства Addison-Wesley. Чтобы установить
местонахождение ближайшего представительства этого издательства, обращайтесь на
его Web-сайт по адресу http://hepg.awl.com/rep-locator.
Как читать эту книгу
В целом, книга рассчитана на последовательное чтение, но можно пропустить по-
следние главы и последние разделы внутри глав по своему усмотрению. Вот предлагае-
мый план чтения.
Бегло прочитайте главы 1 и 2.
Очень внимательно изучите главы 3 и 4.
Внимательно прочитайте главы 5, 6, 8 и 9, но пропустите главу 7 (за исключением,
может быть, раздела 7.7).
Бегло прочитайте главу 10.
Внимательно прочитайте главы 11 и 13, но пропустите главу 12.
Внимательно прочитайте главы 14 и 15.
Выборочно по своему желанию и интересам прочитайте последующие главы.
Как читать эту книгу
25
Каждая глава начинается введением и заканчивается заключением (резюме). Кроме
того, в большинство глав включены упражнения, обычно с ответами. Рекомендуется
просматривать ответы к упражнениям, так как в них часто содержится дополнительная
полезная информация по теме конкретной главы. Также в большинстве глав вы найдете
обширные списки литературы, которые обычно дополнены комментариями. Такая
структура книги позволяет усваивать материал на нескольких уровнях: наиболее важные
понятия и результаты приведены в основном тексте, а дополнительные вопросы и более
сложные аспекты исследования вынесены в соответствующие упражнения, ответы к ним
и комментарии к литературе.
Замечание. Ссылки обозначаются в тексте двойным номером в квадратных скобках.
Например, ссылка [3.1] означает первый пункт в списке литературы к главе 3, а имен-
но— статью Э.Ф. Кодда, опубликованную в журнале САСМ, Vol. 25, No. 2 в феврале
1982 года. (Объяснение сокращений, которые используются в ссылках, например,
“САСМ”, можно найти в приложении В.)
Сравнение с предыдущими изданиями
Ниже перечислены главные отличия настоящего издания от предшествующих.
Часть I. В главах 1-3 обсуждается примерно та же тема, что и в главах 1-3 пре-
дыдущего издания, но главы были переписаны и изложение нескольких тем было
переработано и улучшено. Глава 4 новая, хотя можно сказать, что частично она
основана на материале главы 8 предыдущего издания. В ней рассматриваются ос-
новы языка SQL и его отдельные аспекты, которые логически не связаны ни с ка-
кими другими главами в этой книге (в частности, привязка к базовому языку и ис-
пользование внедренных SQL-операторов).
Часть II. Главы 5-9, посвященные реляционной модели, представляют собой
полностью переписанные, значительно расширенные и существенно улучшенные
версии глав 4-7 и 17 предыдущего издания. В частности, коренным образом пере-
работаны разделы о типах (доменах), реляционных значениях и реляционных пе-
ременных, ограничениях целостности, предикатах и представлениях.
Замечание. Здесь необходимо дать некоторые пояснения. В предыдущих изданиях
язык SQL использовался для демонстрации реляционных понятий в надежде на то,
что студентам будет легче сначала разобраться в конкретных примерах, а затем
перейти к теории. Однако, к сожалению, в настоящее время пропасть между язы-
ком SQL и реляционной моделью настолько увеличилась, что стало очевидно сле-
дующее: использовать язык SQL с этой целью — значит, по сути, просто вводить
читателей в заблуждение. В действительности язык SQL в его современном виде
настолько далек от того, чтобы быть олицетворением реляционных принципов (он
страдает от множества недоделок и переделок), что я предпочел перенести его
описание в приложение. Однако язык этот настолько важен с коммерческой точки
зрения (каждый специалист, работающий с базами данных, обязательно должен
быть знаком с языком SQL), что обойтись с ним так бесцеремонно было бы недо-
пустимо. Поэтому я остановился на компромиссе — глава по основам языка SQL
помещена в часть I этой книги, а в другие главы (где это уместно) вставлены от-
26
Предисловие к седьмому изданию
дельные дополнительные разделы, содержащие описание тех аспектов языка SQL,
которые связаны с темой соответствующей главы.
Часть III. Главы 10-13 — это существенно переработанные версии глав 9-12, до-
полненные новым материалом по реляционно-значимым атрибутам, денормализа-
ции, ортогональному проектированию и альтернативным подходам к семантиче-
скому моделированию (включая бизнес-правила).
Замечание. И снова необходимы пояснения. Некоторые рецензенты предыдущих
изданий жаловались, что вопросы проектирования базы данных излагались слиш-
ком поздно. Но, по моему мнению, студенты будут не вполне готовы к проектиро-
ванию баз данных или не смогут правильно оценить результаты проектирования
до тех пор, пока не поймут, что собой представляют базы данных и как они ис-
пользуются. Другими словами, мне кажется, что следует предварительно потра-
тить некоторое время на реляционную модель и связанные с ней вопросы и лишь
затем приступить к изучению методов проектирования. Поэтому я по-прежнему
убежден, что часть III расположена в книге правильно.
Часть IV. Две главы данной части — это несколько пересмотренные и расширен-
ные версии глав 13 и 14 предыдущего издания.
Часть V. Главы 19 (о наследовании типов), 21 (о поддержке решений) и 22 (о
хронологических базах данных) новые. Главы 16 (о безопасности), 17 (об оптими-
зации), 18 (об отсутствующей информации) и 20 (о распределенных базах данных)
представляют собой расширенные и существенно пересмотренные версии глав 15,
18, 20 и 21 предыдущего издания соответственно. Глава 23 (о логических и дедук-
тивных базах данных) — это переработанная версия приложения Б.
Часть VI. Глава 24 является полностью переписанной и значительно улучшенной
версией глав 22-24. Глава 25 почти полностью обновлена.
И наконец, приложение А основано на части главы 8 предыдущего издания, а прило-
жения Б и В являются новыми.
Из этого издания исключены следующие темы.
Структуры хранения и методы доступа (приложение А предыдущего издания).
Подробное обсуждение системы DB2 (приложение Б предыдущего издания).
Особенности этой книги
Каждая представленная на рынке книга по базам данных имеет свои сильные и сла-
бые стороны, и каждый автор имеет своего “конька”. Один автор уделяет особое внима-
ние вопросам управления транзакциями, а другой делает акцент на построении моделей
типа “сущность-связь”. Один автор смотрит на все через призму языка SQL, а другой
рассматривает все с чисто объектной точки зрения. Многие авторы обсуждают все, что
касается баз данных, исключительно в терминах коммерческих продуктов, и т.д. И, ко-
нечно, я — не исключение из этого правила: я также имею своего “конька”, который мо-
жет называться основами. Я твердо верю, что мы в любом случае должны ясно усвоить
основы и обстоятельно в них разобраться, прежде чем пытаться что-либо на этих осно-
вах строить. Такое убеждение объясняет столь сильный акцент, сделанный в данной кни-
ге на реляционной модели. В частности, это объясняет и размеры второй части (наиболее
Особенности этой книги
27
важной части книги), в которой я представляю собственное понимание реляционной мо-
дели настолько тщательно, насколько это в моих силах. Меня интересуют основы, а не
причуды и мода.
В этой связи необходимо отметить следующее: я удовлетворен тем, что на протяже-
нии многих лет общий характер книги изменялся. Несколько первых изданий были, в ос-
новном, описательными по характеру; в них область баз данных описывалась так, как это
действительно имело место на практике, “без прикрас”. В отличие от предыдущих изда-
ний, это издание — более предписывающее', в нем обсуждается состояние, в котором об-
ласть баз данных должна находиться, и направления, по которым она должна развивать-
ся в будущем, если мы будем поступать разумно (иными словами, эта книга выражает
определенную позицию). И первая часть “разумных действий”, несомненно, заключается
в изучении этих разумных действий. Я надеюсь, что настоящее издание может оказать
существенную помощь в достижении подобной образовательной цели.
И еще одно, связанное с предыдущими рассуждениями, замечание. Некоторые чита-
тели, возможно, знают, что я со своим коллегой Хью Дарвеном (Hugh Darwen) недавно
опубликовал другую “предписывающую” книгу по технологии баз данных, которая на-
зывается The Third Manifesto [3.3]. В ней, исходя из реляционной модели, обстоятельно
излагаются технические предложения относительно будущих систем баз данных
(представленные здесь предложения — результат наших с Хью исследований и размыш-
лений по этой тематике). Поэтому неудивительно, что идеи Manifesto наполняют читае-
мую вами книгу. Многие подумают, что книга Manifesto была необходима для создания
данной книги, однако это не так. В то же время вопросы, рассматриваемые в книге
Manifesto, имеют непосредственное отношение почти ко всем темам, которые обсужда-
ется в данной книге, и часто в книге Manifesto можно найти дополнительную информа-
цию по многим затрагиваемым здесь темам.
Заключительное замечание
Свои вступительные замечания мне хотелось бы закончить следующей отредактиро-
ванной выдержкой из предисловия Бертрана Расселла (Bertrand Russell), приводимой
здесь с любезного разрешения автора, к его словарю The Bertrand Russell Dictionary of
Mind, Matter and Morals (ed. Lester E. Denonn; Citadel Press, 1993).
Меня обвинили в привычке менять свои суждения... Но я нисколько не пристыжен
этой привычкой. Разве мог бы физик, работающий с 1900 года, гордиться тем,
что его суждения не изменились за последние полстолетия?... Философия, кото-
рую я ценю и которой стараюсь следовать, научна в том смысле, что существу-
ют точные знания, которые необходимо получить, а новые открытия могут вы-
явить старые ошибки, неизбежные для любого беспристрастного разума. Когда
бы и что бы я ни говорил, я не претендую на полную истину так, как на нее пре-
тендуют теологи в своем учении. Я претендую только на то, что тогда было
благоразумно придерживаться высказанного мнения... Я был бы очень удивлен, ес-
ли бы дальнейшие исследования не показали, что его необходимо менять. Прежде
всего, моей целью была ясность.
Если читатели предыдущего издания будут изучать настоящее, они обнаружат, что я
тоже меняю свои мнения по некоторым вопросам (и, несомненно, буду продолжать это
делать). Я надеюсь, что высказанное выше замечание они сочтут достаточным оправда-
28
Предисловие к седьмому изданию
нием такого положения дел. Я разделяю понимание Бертраном Расселом того, что собой
представляет научное исследование, но он высказал его гораздо красноречивее, чем я
мог надеяться сделать это сам.
Благодарности
Хочу исполнить приятный долг и поблагодарить всех, кто прямо или косвенно прини-
мал участие в работе над этой книгой. Во-первых, я должен поблагодарить моих друзей
Дэвида Мак-Говерна (David McGoveran) и Хью Дарвена (Hugh Darwen) за их огромную
поддержку. Дэвид написал черновик главы 21 (о системах поддержки принятия решений), а
Хью — черновик главы 22 (о хронологических базах данных). Хью также очень тщательно
просмотрел большие фрагменты рукописи, в том числе все главы о реляционной модели и
приложение по языку SQL3. Во-вторых, текст книги был заметно улучшен благодаря заме-
чаниям слушателей семинаров, которые я веду уже на протяжении семи лет. Кроме того,
положительное влияние на ее текст оказали комментарии многих друзей и рецензентов, а
также мои дискуссии с ними. Вот далеко неполный их список: Чарли Бонтемпо (Charley
Bontempo), Дэклан Брэди (Declan Brady), Хью Дарвен (Hugh Darwen) (опять), Тим Хартли
(Tim Hartley), Эдриан Ларнер (Adrian Lamer), Чунг Ли (Chung Lee), Дэвид Ливингстон
(David Livingstone), Никос Лоренцос (Nicos Lorentzos), Хуижа Лу (Huizha Lu), Рамон Мата-
Толедо (Ramon Mata-Toledo), Нельсон Маттос (Nelson Mattos), Дэвид Мак-Говерн (David
McGoveran) (опять), Фабиан Паскаль (Fabian Pascal), Судха Рам (Cudha Ram), Рик ван дер
Ланс (Rick van der Lans), Йонгдонг Ванг (Yongdong Wang), Колин Вайт (Colin White) и
Квианг Жу (Qiang Zhu). Каждый из них просмотрел по крайней мере часть рукописи этого
издания, предоставил технический материал или как-то иначе помог мне найти ответы на
многие технические вопросы. Я весьма признателен им за это. Также хотелось бы снова
поблагодарить мою жену Линди (Lindy) за помощь в оформлении книги. И наконец, я, как
всегда, благодарен всем в издательстве Addison-Wesley, особенно— Майт Суарез-Ривас
(Maite Suarez-Rivas) и Кэтрин Харутуниан (Katherine Harutunian) за их поощрение и под-
держку во время работы над проектом, а также моему редактору Элидии Дэвис (Elydia
Davis) за ее безукоризненную работу.
Хилдсбург, Калифорния К. Дж. Дейт
1999
Благодарности
29
Часть I
Основные понятия
Часть I состоит из четырех вводных глав.
В главе 1 объясняются основные понятия: что такое базы данных и зачем они
нужны. Также в ней кратко излагаются различия между реляционными и другими
типами баз данных.
В главе 2 в общих чертах представляется архитектура баз данных — так называе-
мая архитектура ANSI/SPARC. На основе этого материала строятся все после-
дующие главы книги.
В главе 3 делается обзор реляционных систем, назначение которого состоит в по-
степенной подготовке читателя к более детальному обсуждению тех же вопросов в
части II и последующих частях данной книги. Здесь также рассматривается реаль-
ный пример — база данных поставщиков и деталей.
В главе 4 дается краткое введение в стандартный реляционный язык SQL.
31
Глава
Базы данных
и управление ими
1Л. Вводный пример
Система баз данных — это, по сути, не что иное, как компьютеризированная сис-
тема хранения записей. Саму же базу данных можно рассматривать как подобие элек-
тронной картотеки, т.е. хранилище или контейнер для некоторого набора занесенных в
компьютер файлов данных. Пользователям этой системы предоставляется возможность
выполнять множество различных операций над такими файлами, например:
добавлять новые пустые файлы в базу данных;
вставлять новые данные в существующие файлы;
получать данные из существующих файлов;
изменять данные в существующих файлах;
удалять данные из существующих файлов;
удалять существующие файлы из базы данных.
В качестве иллюстрации в табл. 1.1 приведена небольшая база данных, состоящая
всего из одного файла под названием CELLAR (погреб). В этом файле хранятся данные о
содержимом винного погреба. На рис. 1.1 показан пример выполнения операции выбор-
ки и данные, возвращаемые с помощью этой операции.
Таблица 1.1. Содержимое файла CELLAR
BIN# WINE PRODUCER YEAR BOTTLES READY
2 Chardonnay Buena Vista 1997 1 1999
3 Chardonnay Geyser Peak 1997 5 1999
6 Chardonnay Simi 1996 4 1998
12 Joh. Riesling Jekel 1998 1 1999
21 Fume Blanc Ch. St. Jean 1997 4 1999
22 Fume Blanc Robt. Mondavi 1996 2 1998
30 Gewurztraminer Ch. St. Jean 1998 3 1999
43 Cab. Sauvignon Windsor 1991 12 2000
45 Cab. Sauvignon Geyser Peak 1994 12 2002
48 Cab. Sauvignon Robt. Mondavi 1993 12 2004
32
Часть I. Основные понятия
Окончание табл. 1.1
BIN# WINE PRODUCER YEAR BOTTLE S READY
50 Pinot Noir Gary Farrell 1996 3 1999
51 Pinot Noir Fetzer 1993 3 2000
52 Pinot Noir Dehlinger 1995 2 1998
58 Me riot Clos du Bois 1994 9 2000
64 Zinfandel Cline 1994 9 2003
72 Zinfandel Rafanelli 1995 2 2003
Замечание. Операции над базами данных, имена файлов и т.п. в этой книге для на-
глядности пишутся прописными буквами, хотя на практике часто удобнее использовать
строчные. В большинстве СУБД допускаются оба варианта.
Выборка данных:
SELECT WINE, BIN#, PRODUCER
FROM CELLAR
WHERE READY = 2000 ;
Результат (выданный, например, на экран дисплея):
WINE BIN# PRODUCER
Cab. Sauvignon 43 Windsor
Pinot Noir 51 Fetzer
Merlot 58 Clos du Bois
Рис. 1.1. Пример выборки информации из базы данных
На рис. 1.2 приведены примеры операций вставки (INSERT), обновления (UPDATE) и
удаления (DELETE) для базы данных винного погреба. Эти примеры почти не требуют
пояснений. Далее, в главах 3, 4, 5 и некоторых других, будут приведены примеры добав-
ления и удаления файлов.
Вставка новых данных:
INSERT
INTO CELLAR ( BIN#, WINE, PRODUCER, YEAR, BOTTLES, READY )
VALUES ( 53, 'Pinot Noir', 'Saintsbury', 1997, 6, 2001 ) ;
Обновление существующих данных:
UPDATE CELLAR
SET BOTTLES = 4
WHERE BIN# = 3 ;
Удаление существующих данных:
DELETE
FROM CELLAR
WHERE BIN# = 2 ;
Рис. 1.2. Примеры операций вставки, обновления и удаления
Глава 1. Базы данных и управление ими
33
В завершение вводного раздела приведем несколько замечаний.
I. По очевидным причинам компьютерные файлы, такие как CELLAR в приведенном
выше примере, часто называют таблицами, а не файлами (точнее, реляционными
таблицами; подробности — в разделах 1.3 и 1.6).
2. Строки (row) подобных таблиц соответствуют записям файла, а столбцы
(columns) можно рассматривать как поля этих записей. В дальнейшем термины
“запись” и “поле” будут использоваться тогда, когда речь будет идти о базах дан-
ных вообще (в основном, в первых двух главах). Термины “строка” и “столбец” бу-
дут использоваться при рассмотрении реляционных систем (еще раз обратитесь к
разделам 1.3 и 1.6).
Замечание. В действительности, когда мы перейдем к более формальному рассмот-
рению реляционной модели в последующих частях книги, нам так или иначе при-
дется использовать более формальные термины.
3. Для простоты в этом примере мы предположили по умолчанию, что в столбцах
WINE и PRODUCER содержатся строковые данные, а во всех остальных столбцах —
целочисленные данные. Вопросы, касающиеся типов данных (data types) столб-
цов, более подробно будут обсуждаться в главах 3, 4 и особенно в главе 5.
4. Столбец BIN# является первичным ключом (primary key) таблицы CELLAR
(подразумевается, что любые две строки этой таблицы никогда не будут содержать
одно и то же значение поля BIN#). Для выделения в таблицах столбцов первичного
ключа мы обычно будем использовать двойное подчеркивание (см. табл. 1.1).
5. Примеры операций выборки, вставки, обновления и удаления на рис. 1.1 и 1.2 пред-
ставлены с помощью операторов (statement) SELECT, INSERT, UPDATE и DELETE специ-
ального языка баз данных, называемого SQL. Язык SQL поддерживается в настоящее
время большинством коммерческих СУБД, представленных на рынке, и является
официальным стандартом языка для работы с реляционными базами данных.
Замечание. Название “SQL” вначале было аббревиатурой, образованной от
Structured Query Language (язык структурированных запросрв), и его было принято
произносить как “сиквел”. Сейчас, когда язык стал стандартом, SQL — это уже не
аббревиатура, а обычное название, которое произносится как “эс-кью-эль”. В даль-
нейшем в этой книге предполагается именно такой вариант произношения.
6. Заметим, что в языке SQL для операции обновления используется ключевое слово
UPDATE, обозначающее именно операцию изменения (change). Это в некоторых случа-
ях может привести к недоразумениям, поскольку термин “обновить” (update) исполь-
зуется также по отношению к операциям вставки (INSERT), обновления (UPDATE) и
удаления (DELETE) в целом, как к группе. В данной книге мы будем различать эти два
понятия, используя строчные буквы при записи общего понятия и прописные буквы,
когда будет подразумеваться именно операция обновления UPDATE.
7. Как вам, наверное, известно, большая часть современных систем баз данных — ре-
ляционные (или в какой-то мере считающиеся реляционными; глава 4, раздел 4.7).
И это одна из причин, по которой в данной книге наибольшее внимание уделяется
именно реляционным системам.
34
Часть I. Основные понятия
И последнее замечание в настоящем разделе: понимание материала этой и следующей
глав имеет решающее значение для правильного восприятия средств и возможностей со-
временных систем баз данных. Однако нельзя не признать, что материал этих глав кое-где
несколько абстрактный и довольно сухой. Дополнительная сложность состоит в том, что
здесь рассматривается много понятий и терминов, которые могут быть вам еще неизвест-
ны. Следующая часть книги, особенно главы 3 и 4, менее абстрактна, поэтому, возможно,
она будет восприниматься лучше. Так что, может быть, стоит сначала лишь бегло прочи-
тать первые две главы, а позже внимательно перечитывать их по мере детального ознаком-
ления с темами, которые непосредственно связаны с материалом этих двух глав.
1.2. Что такое система баз данных
Как отмечалось выше, система баз данных — это компьютеризированная система
хранения записей, т.е. компьютеризированная система, основное назначение которой —
хранить информацию, предоставляя пользователям средства ее извлечения и модифика-
ции. К информации может относиться все, что заслуживает внимания отдельного поль-
зователя или организации, использующей систему, иначе говоря, все необходимое для
текущей работы данного пользователя или предприятия.
Замечание. Термины “данные” и “информация” трактуются в этой книге как синонимы.
Некоторые авторы предпочитают отличать эти два понятия, используя термин “данные” для
ссылки на значения, которые реально сохранены в базе данных, а термин “информация” для
пояснения смысла этих значений пользователю. Разница, безусловно, существенная, но пред-
почтительнее сделать ее более определенной там, где это уместно, вместо того, чтобы пола-
гаться на различные понятия между двумя по существу одинаковыми терминами.
На рис. 1.3 показана весьма упрощенная схема системы баз данных. Здесь отражено
четыре главных компонента системы, а именно: данные, аппаратное обеспечение,
программное обеспечение и пользователи. Каждый из этих компонентов кратко рас-
сматривается ниже. Далее они будут обсуждаться значительно подробнее (за исключени-
ем аппаратного обеспечения, поскольку большая часть аспектов его использования вы-
ходит за рамки этой книги).
Данные
Системы с базами данных существуют как на самых малых компьютерах, так и на
крупнейших мэйнфреймах. Нет необходимости говорить, что предоставляемые каждой
конкретной системой средства в некоторой мере зависят от мощности и возможностей
базовой машины. В частности, системы на больших машинах (“большие системы”), в
основном, многопользовательские, тогда как системы на малых машинах (“малые сис-
темы”), как правило, однопользовательские. Однопользовательская система (single-
user system) — это система, в которой одновременно к базе данных может получить
доступ не более одного пользователя, а многопользовательская система (multi-user
system) — это такая система, в которой к базе данных могут получить доступ сразу не-
сколько пользователей. Как и в схеме на рис. 1.3, исходя из соображений общности,
мы обычно будем подразумевать именно второй вид систем, хотя, с точки зрения
пользователей, между этими системами фактически не существует большого различия.
Основная задача большинства многопользовательских систем — позволить каждому
отдельному пользователю работать с ней так, как он мог бы работать с однополъзова-
Глава 1. Базы данных и управление ими
35
тельской системой. Различия между этими двумя видами систем проявляются в их
внутренней структуре, и потому практически не видны конечному пользователю (о
чем речь пойдет ниже).
Замечание. Обычно для упрощения предполагают, что все данные в системе хранятся
в одной базе данных. Мы также будем придерживаться этого предположения, поскольку
оно несущественно для всех дальнейших рассуждений. Однако на практике, даже при
использовании малых систем, могут быть серьезные причины для распределения инфор-
мации по нескольким отдельным базам данных. Эта тема еще будет затронута далее в
этой книге, в частности в главе 2.
В общем случае данные в базе данных (по крайней мере, в больших системах) явля-
ются интегрированными и разделяемыми. Как будет показано в разделе 1.4, эти два ас-
пекта, интеграция и разделение данных, представляют собой наиболее важные преиму-
щества использования систем баз данных на “большом” оборудовании и по меньшей ме-
ре один из них — интеграция — является преимуществом их использования на “малом”
оборудовании. Конечно, есть множество других преимуществ (даже на “малом” обору-
довании), но о них речь пойдет позже. Сначала следует объяснить, что понимается под
терминами интегрированный и разделяемый.
Под понятием интегрированности данных подразумевается возможность пред-
ставить базу данных как объединение нескольких отдельных файлов данных,
полностью или частично исключающее избыточность хранения информации.
Например, база данных может содержать файл EMPLOYEE, включающий имена
сотрудников, адреса, отделы, зарплату и т.д., и файл ENROLLMENT, содержащий
36
Часть I. Основные понятия
сведения о регистрации сотрудников на курсах обучения (рис. 1.4). Допустим,
что для контроля процесса обучения необходимо знать отдел каждого зачислен-
ного на курсы студента. Совершенно очевидно, что нет необходимости вклю-
чать такую информацию в файл ENROLLMENT, поскольку ее всегда можно полу-
чить из файла EMPLOYEE.
EMPLOYEE | NAME | ADDRESS | DEP ARMENT | SALARY |...
ENROLLMENT [NAME [COURSE |...
Рис. 1.4. Файлы EMPLOYEE и ENROLLMENT
Под понятием разделяемости данных подразумевается возможность использова-
ния отдельных элементов, хранимых в базе данных несколькими различными
пользователями. Имеется в виду, что каждый из пользователей сможет получить
доступ к одному и тому же элементу данных, возможно, для достижения различ-
ных целей. Как уже упоминалось, разные пользователи могут даже получать дос-
туп к одному и тому же элементу данных в одно и то же время (параллельный
доступ). В приведенном выше примере информация об отделе в файле EMPLOYEE
может разделяться пользователями отдела кадров и отдела обучения. Причем, как
подчеркивалось выше, эти две группы пользователей смогут применять такую ин-
формацию для разных целей, что обычно и происходит.
Замечание. Если база данных не является разделяемой, то ее иногда называют
личной или базой данных специального назначения.
Одним из следствий упомянутых выше характеристик базы данных (интегрированности
и разделяемости) является то, что каждый конкретный пользователь обычно имеет дело
лишь с небольшой частью всей базы данных, причем обрабатываемые различными пользо-
вателями части могут произвольным образом перекрываться. Иначе говоря, каждая база
данных воспринимается ее различными пользователями по-разному. Фактически даже те
два пользователя базы данных, которые работают с одними и теми же элементами данных,
могут иметь значительно отличающиеся представления о них. Более подробное обсужде-
ние этого вопроса приводится далее, в разделе 1.5 и в главах 2 и 3 (особенно — в главе 9).
В разделе 1.3 мы продолжим обсуждение свойств элементов данных, хранимых в
системе баз данных.
Аппаратное обеспечение
К аппаратному обеспечению системы относится следующее.
Тома вторичной (внешней) памяти (обычно это магнитные диски), используемые
для хранения информации, а также соответствующие устройства ввода-вывода
(дисководы и т.п.), контроллеры устройств, каналы ввода-вывода и т.д.
Аппаратный процессор (или процессоры) вместе с основной (первичной) памя-
тью, предназначенные для поддержки работы программного обеспечения системы
баз данных (подробности — в следующем разделе).
Глава 1. Базы данных и управление ими
37
Аппаратной части системы в данной книге уделяется мало внимания. Во-первых, эти
вопросы составляют достаточно обширную тему, которую нужно рассматривать отдель-
но. Во-вторых, проблемы, которые существуют в этой области, не являются специфиче-
скими исключительно для систем баз данных. И, в-третьих, эти проблемы достаточно
подробно освещаются в других источниках.
Программное обеспечение
Между собственно физической базой данных (т.е. данными, которые реально хра-
нятся) и пользователями системы располагается уровень программного обеспечения,
который можно называть по-разному: менеджер базы данных (database manager),
сервер базы данных (database server) или, что более привычно, система управления
базами данных, СУБД (database management system — DBMS). Все запросы пользо-
вателей на доступ к базе данных обрабатываются СУБД. Все имеющиеся средства до-
бавления файлов (или таблиц), выборки и обновления данных в этих файлах или таб-
лицах также предоставляет СУБД. Основная задача СУБД — предоставить пользова-
телю базы данных возможность работать с ней, не вникая в детали на уровне аппа-
ратного обеспечения. (Пользователь СУБД более отстранен от этих деталей, чем при-
кладной программист, применяющий языковую среду программирования.) Иными
словами, СУБД позволяет конечному пользователю рассматривать базу данных как
объект более высокого уровня по сравнению с аппаратным обеспечением, а также
предоставляет в его распоряжение набор операций, выражаемых в терминах языка вы-
сокого уровня (например, набор операций, которые можно выполнять с помощью язы-
ка SQL, упомянутого выше, в разделе 1.1). Далее в книге будут подробно обсуждаться
обе указанные функции СУБД.
Необходимо отметить еще две особенности.
СУБД — это наиболее важный, но не единственный программный компонент сис-
темы. Среди других компонентов — утилиты, средства разработки приложений,
средства проектирования, генераторы отчетов и менеджер транзакций (transaction
manager) или диспетчер выполнения транзакций (TP monitor). Эти компоненты
обсуждаются далее, в главе 2, 3 и (еще подробнее) в части IV.
Термин СУБД также часто используется в отношении конкретных программных
продуктов конкретных изготовителей, например такого, как СУБД IBM “DB2
Universal Database” для системы OS/390. Иногда, в тех случаях, когда конкретная
копия подобного продукта устанавливается для работы на определенном компью-
тере, используется термин экземпляр СУБД. Как вы, безусловно, понимаете, необ-
ходимо строго различать эти два понятия.
Замечание. Следует иметь в виду, что в среде изготовителей термин база данных
часто используется даже тогда, когда на самом деле подразумевается СУБД (в од-
ном из уже упомянутых толкований). Вот типичный пример: “База данных изгото-
вителя X превосходит по производительности базу данных изготовителя Y в два
раза”. Такое небрежное обращение с терминами предосудительно; тем не менее
оно очень широко распространено. (Проблема, естественно, заключается в том,
что если называть СУБД базой данных, то как же тогда называть саму базу дан-
ных?) Предостерегающий лектор.
38
Часть I. Основные понятия
Пользователи
Пользователей можно разделить на три большие и отчасти перекрывающиеся группы.
Первая группа— прикладные программисты, которые отвечают за написание
прикладных программ, использующих базу данных. Для этих целей применимы
такие языки, как COBOL, PL/I, C++, Java или какой-нибудь высокоуровневый
язык четвертого поколения (подробности — в главе 2). Прикладные программы
получают доступ к базе данных посредством выдачи соответствующего запроса к
СУБД (обычно это некоторый SQL-оператор). Подобные программы могут быть
простыми пакетными приложениями или же интерактивными приложениями,
предназначенными для поддержки работы конечных пользователей (см. следую-
щий абзац). В последнем случае они предоставляют пользователям непосредст-
венный оперативный доступ к базе данных через рабочую станцию или терминал.
Большинство современных приложений относится именно к этой категории.
Вторая группа— конечные пользователи, которые работают с системой баз
данных непосредственно через рабочую станцию или терминал. Конечный поль-
зователь может получать доступ к базе данных, применяя одно из интерактивных
приложений, упомянутых выше, или же интерфейс, интегрированный в про-
граммное обеспечение самой СУБД. Безусловно, подобный интерфейс также под-
держивается интерактивными приложениями, однако эти приложения не создают-
ся пользователями-программистами, а являются встроенными в СУБД. Большин-
ство СУБД включает по крайней мере одно такое встроенное приложение, а
именно — процессор языка запросов, позволяющий пользователю в диалоговом
режиме вводить запросы к базе данных (их часто иначе называют операторами
(statement) или командами (commands)), например SELECT или INSERT. Язык SQL,
упоминавшийся в разделе 1.1, — типичный пример языка запросов базы данных.
Замечание. Общепринятый термин “язык запросов” не совсем точно отражает
рассматриваемое понятие, поскольку слово “запрос” подразумевает лишь выборку
(retrieval) информации, в то время как с помощью этого языка выполняются также
операции обновления, вставки, удаления и др.
Кроме языка запросов, в большинстве систем дополнительно предоставляются
специализированные встроенные интерфейсы, в которых пользователь в яв-
ном виде не использует команд, подобных оператору SELECT. Работа с базой
данных осуществляется за счет выбора пользователем необходимых команд
меню или заполнения требуемых полей в предоставленных формах. Такие не-
командные интерфейсы, основанные на меню и формах, облегчают работу с
базами данных тех, кто не имеет опыта работы с информационными техноло-
гиями (ИТ; часто употребляется также сокращение ИС— информационные
системы; эти понятия практически эквивалентны). Командный интерфейс,
т.е. язык запросов, напротив, требует некоторого профессионального опыта
работы с ИТ (безусловно, не такого большого, какой необходим для написа-
ния прикладных программ на языке программирования, подобном COBOL).
Однако командный интерфейс более гибок, чем некомандный, к тому же язы-
ки запросов обычно включают определенные функции, отсутствующие в не-
командных интерфейсах.
Глава 1. Базы данных и управление ими
39
Третья группа (не показана на рис. 1.4)— администраторы базы данных, или
АБД. Обсуждение функций администраторов баз данных и связанных с ними (что
очень важно) функций администраторов данных отложим до раздела 1.4 и главы 2
(раздел 2.7).
На этом мы закончим предварительное описание основных аспектов систем баз дан-
ных и приступим к более детальному изучению соответствующих идей.
1.3. Что такое база данных
Перманентные данные
Обычно данные в базе данных называют перманентными или постоянными (хотя на
самом деле они могут недолго оставаться таковыми!). Под словом перманентные
(persistent) подразумеваются данные, которые отличаются от других, более изменчивых
данных, таких как промежуточные результаты, входные и выходные данные, управляю-
щие операторы, рабочие очереди, программные управляющие блоки и вообще все вре-
менные (transient) по своей сути данные. Точнее говоря, можно утверждать, что данные в
базе остаются “перманентными”, поскольку после того, как они были приняты средства-
ми СУБД для помещения в базу, удалить их из нее впоследствии можно лишь с помо-
щью соответствующего явного запроса к базе данных, но не как результат какого-либо
побочного эффекта от выполнения некоторой программы. Подобный взгляд на понятие
перманентности позволяет точнее определить термин “база данных”.
База данных— это некоторый набор перманентных (постоянных) данных, ис-
пользуемых прикладными системами какого-либо предприятия.
Здесь слово “предприятие” — это общий термин для относительно независимой ком-
мерческой, научной, технической или любой другой организации или предприятия.
Предприятие может состоять всего из одного человека (с небольшой частной базой дан-
ных), быть целой корпорацией или другой крупной организацией (с очень большой об-
щей базой данных) либо представлять собой нечто среднее между этими крайними слу-
чаями. Вот несколько примеров.
1. Промышленная компания.
2. Банк.
3. Больница.
4. Университет.
5. Министерство.
Любое предприятие неизбежно использует большое количество данных, связанных с
его деятельностью. Это и есть “перманентные данные”, о которых мы говорили выше.
Среди перманентных данных упомянутых предприятий обычно встречаются следующие.
I. Данные о продукции.
2. Данные о состоянии счетов.
3. Данные о пациентах.
4. Данные о студентах.
5. Данные о планируемой деятельности.
40
Часть I. Основные понятия
Замечание. В первых изданиях этой книги вместо термина “перманентные данные”
использовался термин “операционные данные”. Старый термин отражал первоначальное
особое значение операционных или производственных приложений баз данных, т.е.
рутинных, часто выполняющихся приложений, предназначенных для поддержки каждо-
дневной работы предприятия (например, приложений для поддержки депозитов или изъ-
ятия наличных денег в банковской системе). Для среды такого рода в последнее время
используется термин оперативная обработка транзакции (online transaction
processing — OLTP). Однако теперь базы данных все чаще используются и в приложени-
ях другого рода, например в приложениях поддержки принятия решений (decision
support), и термин “операционные данные” для них уже не подходит. На практике сего-
дняшние предприятия используют две отдельные базы данных: базу с операционными
данными и базу с данными для поддержки принятия решений, которую обычно называ-
ют хранилищем данных (data warehouse). В хранилищах данных часто содержится обоб-
щенная информация (например, итоговые и средние значения), которая, в свою очередь,
периодически (например, раз в день или раз в неделю) извлекается из операционной ба-
зы данных. Обсуждение баз данных и приложений поддержки принятия решений будет
продолжено в главе 21.
Сущности и связи
Рассмотрим пример некоторой промышленной компании (“KnowWare, Inc.”) более
детально. Обычно подобному предприятию требуется записывать информацию об
имеющихся проектах (Projects), используемых в этих проектах деталях (Parts), по-
ставщиках (Suppliers) деталей, складах (Warehouses), на которых хранятся детали,
служащих (Employees), работающих над проектами, и т.д. Проекты, детали, поставщики
и т.д. представляют собой основные сущности (entity), о которых компании KnowWare,
Inc. необходимо хранить информацию. Термин “сущность” обычно используется в тео-
рии баз данных для обозначения любого отличимого объекта, который может быть пред-
ставлен в базе данных.
Кроме собственно основных сущностей (в данном примере это поставщики, детали и
т.д.), существуют еще и связи (relationships) между ними, которые объединяют эти основ-
ные сущности. На рис. 1.5 связи представлены ромбами с соединительными линиями. На-
пример, между поставщиками и деталями существует связь SP: каждый поставщик постав-
ляет определенные детали, и, наоборот, каждая деталь поставляется определенными по-
ставщиками. (Точнее, каждый поставщик поставляет определенные виды деталей и каждый
вид деталей поставляется определенными поставщиками.) Аналогично детали используют-
ся в проектах, а для реализации проектов требуются детали (связь РJ); детали хранятся на
складах, а склады хранят детали (связь WP) и т.д. Обратите внимание, что эти связи двусто-
ронние, т.е. их можно рассматривать в обоих направлениях. В частности, используя связь
SP между поставщиками и деталями, можно ответить на следующие вопросы.
Задан поставщик, и требуется определить поставляемые им детали.
Задана деталь, и необходимо найти поставщиков, поставляющих такую деталь.
Очень важно то, что эта связь (как и другие связи, представленные на рис. 1.5) явля-
ется такой же частью данных предприятия, как и основные сущности. Поэтому связи
должны быть представлены в базе данных наравне с основными сущностями предметной
области.
Глава 1. Базы данных и управление ими
41
Рис. 1.5. Пример диаграммы “сущность-связь” (ER-диаграммы) для базы
данных компании Know Ware, Inc.
Замечание. В реляционных базах данных и основные сущности, и связи между ними
представляются с помощью таблиц, подобных табл. 1.1 (подробнее об этом речь пойдет
в главе 3).
Схема, представленная на рис. 1.5, называется (по очевидным причинам) диаграм-
мой “сущность-связь” (иначе ее называют ER-диаграммой). Более подробно такие схе-
мы рассматриваются в главе 13.
Отметим еще несколько важных моментов, проиллюстрированных на рис. 1.5.
1. Хотя большинство связей на этой диаграмме связывает два типа сущностей (т.е.
они являются бинарными), это вовсе не означает, что все связи должны быть би-
нарными. В примере есть одна связь (SPJ), связывающая три типа сущностей
(Suppliers, Parts и Projects). Это пример тернарной (тройной) связи. Интерпре-
тация данной связи такова: определенные поставщики поставляют определенные
детали для определенных проектов. Обратите особое внимание на то, что в общем
случае такая тернарная связь не эквивалентна простой комбинации из трех бинар-
ных связей: “поставщики поставляют детали”, “детали используются в проектах” и
“проекты снабжаются поставщиками”. В частности, приведенное ниже утвержде-
ние а говорит нам больше, чем последующие три утверждения.
а) “Смит поставляет разводные гаечные ключи для Манхэттенского проекта”;
б) “Смит поставляет разводные гаечные ключи”;
в) “Разводные гаечные ключи используются в Манхэттенском проекте”;
г) “Манхэттенский проект снабжается Смитом”.
Зная только утверждения б, в и г, мы не сможем доказать справедливость утвер-
ждения а. Точнее, зная утверждения б, в и г, мы можем лишь сделать заключение,
что Смит поставляет разводные гаечные ключи для какого-то проекта (скажем,
проекта Jz), что какой-то поставщик (скажем, поставщик Sx) поставляет разводные
42
Часть I. Основные понятия
гаечные ключи для Манхэттенского проекта и что Смит поставляет какую-то де-
таль (скажем, деталь PY) для Манхэттенского проекта. Однако мы не можем точно
утверждать, что поставщик Sx — это Смит, деталь PY — это разводной гаечный
ключ, а проект Jz — это Манхэттенский проект. Такие ложные выводы называются
ловушкой соединения (connection trap).
2. На схеме также есть одна связь (РР), которая связывает один тип сущности (Parts)
с самим собой. Эта связь означает, что одни детали содержат другие детали как
собственные компоненты (так называемая связь спецификации материалов). На-
пример, винт — это компонент шарнира, который тоже рассматривается как деталь
и, в свою очередь, может быть компонентом какой-либо более сложной детали, на-
пример колпака. Обратите внимание, что эта связь также бинарная; просто она свя-
зывает две сущности совпадающего типа (в данном случае — сущность Parts).
3. Вообще говоря, для заданного набора типов сущностей может существовать любое
количество связей. В представленной на рис. 1.5 диаграмме присутствуют две раз-
личные связи между сущностями Projects и Employees: первая (EJ) представляет
тот факт, что служащие заняты в проектах, а вторая (MJ) — что служащие управля-
ют проектами.
Теперь мы убедились, что связь можно понимать как сущность особого типа. Если
сущность определена как “нечто, о чем необходимо записывать информацию”, то поня-
тие связи вполне подходит под такое определение. Например, связь “деталь ' Р4' хранит-
ся на складе 'W8'” — это сущность, о которой может потребоваться записать некоторую
информацию, например соответствующее количество указанных деталей. Более того,
существуют некоторые преимущества (их описание выходит за рамки этой главы) в том,
что мы не делаем излишних различий между сущностями и связями. Поэтому в данной
книге связи будут рассматриваться как особый тип сущности.
Свойства
Как мы только что отметили, сущность — это то, о чем необходимо записывать ин-
формацию. Отсюда следует, что сущности (а значит, и связи) имеют некоторые свойст-
ва (properties), соответствующие тем данным о них, которые мы желаем записать. На-
пример, у поставщиков есть место расположения, у деталей — вес, у проектов — поря-
док очередности выполнения, закрепление служащих за проектами имеет начальную
дату и т.д. Именно эти свойства должны сохраняться в базе данных. Например, в базе
данных может быть таблица S, представляющая тип сущности “поставщики”, а в этой
таблице может присутствовать тип поля CITY (город), представляющий свойство “место
расположения”.
В общем случае свойства могут быть как простыми, так и сложными, причем на-
столько, насколько это потребуется. Например, свойство “место расположения постав-
щика” относительно простое: оно состоит только из названия города и может быть опи-
сано как простая символьная строка. В противоположность этому сущность “склад” мо-
жет иметь свойство “схема этажей” с достаточно сложной структурой, включающей ар-
хитектурный план здания, дополненный соответствующим текстовым описанием. На
момент написания этой книги большинство существующих СУБД лишь недавно начали
поддерживать работу со сложными свойствами, подобными изображениям с текстовым
описанием. Мы еще возвратимся к данному вопросу позже в этой книге (в частности, в
Глава 1. Базы данных и управление ими
43
главе 5 и части VI), а пока в большинстве случаев (за исключением тех моментов, когда
существуют отличия) будем предполагать, что все свойства являются простыми и их
можно представить простыми типами данных: числами, строками, датами, отметками
времени и т.п.
Данные и модели данных
Существует и другой, не менее важный, подход к пониманию данных и баз данных.
Слово “данные” (data) происходит от латинского слова “давать”, откуда следует, что
данные на самом деле являются заданными фактами, из которых можно логически полу-
чить другие факты. (Получение дополнительных фактов из заданных фактов — это в
'точности то, для чего используется СУБД, обслуживая запросы пользователя.)
“Заданный факт”, в свою очередь, соответствует тому, что в логике называется истин-
ным высказыванием1. Например, высказывание “Поставщик с номером 'S1' находится в
Лондоне” вполне может быть таким истинным высказыванием. Отсюда следует, что база
данных в действительности есть набор подобных истинных высказываний [1.2].
Одна из причин того, что реляционные системы баз данных стали доминирующими
(заметим, как в индустриальном, так и в академическом мире), состоит в их способности
поддерживать вышеупомянутую интерпретацию данных и баз данных напрямую
(фактически почти тривиально). Реляционные системы основаны на формальной теории,
называемой реляционной моделью данных, которая предполагает следующее.
Данные представлены посредством строк в таблицах, и эти строки могут быть не-
посредственно интерпретированы как истинные высказывания. Например, строку
с номером ячейки погреба (поле BIN#), равным 72 (см. табл. 1.1), можно очевид-
ным образом интерпретировать как следующее истинное высказывание.
“В ячейке 72 находятся две бутылки вина Zinfandel, выпущенные компанией
Rafanelli в 1995 году, которые будут готовы к употреблению в 2003 году.”
Для обработки строк данных предоставляются операторы, которые напрямую
поддерживают процесс логического получения дополнительных истинных выска-
зываний из существующих высказываний. Например, реляционный оператор про-
ецирования (раздел 1.6) позволяет получить из приведенного выше истинного вы-
сказывания, помимо прочих истинных высказываний, и такое.
“Некоторые бутылки вина Zinfandel будут готовы к употреблению в 2003 году.”
(Точнее, “Некоторые бутылки вина Zinfandel в некоторой ячейке, произведенные
некоторым производителем в некотором году, будут готовы к употреблению в
2003 году.”)
Однако реляционная модель — не единственная возможная модель данных. Сущест-
вуют и другие модели (раздел 1.6), хотя многие из них отличаются от реляционной мо-
дели только тем, что они в определенной степени приспособлены для специальных слу-
чаев, а не строго построены на формальной логике. Возникает вопрос, что же такое мо-
дель данных? Это понятие можно определить следующим образом.
1 Высказывание в логике — это нечто, что может быть недвусмысленно оценено как истина
или ложь. Например, "Вильям Шекспир написал Гордость и предубеждение” — это высказывание
(как видно, ложное).
44
Часть I. Основные понятия
Модель данных— это абстрактное, самодостаточное, логическое определение
объектов, операторов и прочих элементов, в совокупности составляющих абст-
рактную машину, с которой взаимодействует пользователь. Упомянутые объекты
позволяют моделировать структуру данных, а операторы — поведение данных.
Используя это определение, можно эффективно разделить модель данных и ее реали-
зацию.
Реализация (implementation) заданной модели данных — это физическое вопло-
щение на реальной машине компонентов абстрактной машины, которые в сово-
купности составляют эту модель.
Короче говоря, модель — это то, что пользователи должны знать, а реализация — это
то, чего пользователи не должны знать.
Замечание. Как можно видеть, различие между моделью и ее реализацией в действи-
тельности является просто частным случаем (очень важным частным случаем) знакомого
отличия логического от физического. Однако, как это ни прискорбно, многие современ-
ные системы баз данных (даже системы, которые претендуют на то, чтобы называться
реляционными) не проводят такого четкого различия, как требуется. Действительно, по-
видимому, это весьма распространенный недостаток, состоящий в непонимании таких
различий и важности их проведения. И вследствие этого все чаще наблюдается расхож-
дение между принципами построения баз данных (указывающими, какими системы баз
данных должны быть) и практикой их реализации (какие они есть на самом деле). В этой
книге нас интересуют, в первую очередь, принципы, но честнее будет заранее предупре-
дить читателя, что его могут поджидать сюрпризы (в основном, неприятные), когда дело
дойдет до использования конкретных коммерческих продуктов.
В завершение этого раздела необходимо отметить, что в действительности термин мо-
дель данных используется в литературе в двух различных смыслах. Первое значение терми-
на описано выше. Второе значение относится к модели перманентных данных некоторого
конкретного предприятия (например, промышленной компании KnowWare, Inc., упоми-
наемой выше в этом разделе). Различие между этими двумя значениями можно описать так.
Модель данных в первом смысле подобна языку программирования (причем дос-
таточно абстрактному), конструкции которого могут быть использованы для ре-
шения широкого круга конкретных задач, но который сам по себе не имеет ника-
кой связи с какой-либо из этих конкретных задач.
Модель данных во втором смысле подобна конкретной программе, написанной на
таком языке. Иначе говоря, модель данных во втором смысле использует средства,
предоставляемые некоторой моделью в первом смысле, и применяет их для реше-
ния конкретной проблемы. Ее можно рассматривать как некоторое конкретное
приложение некоторой модели в первом смысле.
В данной книге термин модель данных начиная с этого момента будет использоваться
только в первом смысле, кроме случаев явного указания на противоположное.
1.4. Назначение баз данных
Почему используются системы с базами данных? Какие преимущества получает
пользователь при работе с ними? В некоторой степени ответ зависит от того, о какой
системе идет речь — однопользовательской или многопользовательской (точнее будет
Глава 1. Базы данных и управление ими
45
сказать, что существуют многочисленные дополнительные преимущества использова-
ния многопользовательских систем). Сначала рассмотрим случай однопользователь-
ской системы.
Вернемся к нашей базе данных винного погреба (см. табл. 1.1), которую можно
рассматривать как типичный пример однопользовательской базы данных. Она на-
столько мала и проста, что на ее примере сразу увидеть все потенциальные преимуще-
ства невозможно. Но представьте себе такую базу данных для большого ресторана,
имеющего запас, возможно, из тысяч бутылок, который постоянно обновляется, или,
скажем, для винного магазина, опять же с большим запасом, который находится в по-
стоянном обороте. Преимущества системы с базой данных по сравнению с традицион-
ным “бумажным” методом ведения учета для этих примеров вполне очевидны. Отме-
тим некоторые из них.
Компактность. Нет необходимости в создании и ведении многотомных бумаж-
ных картотек.
Скорость. Компьютер может выбирать и обновлять данные гораздо быстрее че-
ловека. В частности, с его помощью можно быстро получать ответы на произволь-
ные вопросы, возникающие в процессе работы (например, “Какого вина у нас сей-
час больше — Zinfandel или Pinot Noir?”), не затрачивая времени на визуальный
поиск или поиск вручную.
Низкие трудозатраты. Нет необходимости в утомительной работе над картоте-
кой вручную. Механическую работу машины всегда выполняют лучше.
Актуальность. В случае необходимости под рукой в любой момент имеется точ-
ная свежая информация.
Эти преимущества приобретают еще большее значение в многопользовательской
среде, где база данных, вероятно, больше и сложнее однопользовательской. Кроме то-
го, многопользовательская среда имеет дополнительное преимущество: система баз
данных предоставляет предприятию средства централизованного управления его
данными (именно возможность такого управления является наиболее ценным свойст-
вом базы данных). Представьте себе противоположную ситуацию: предприятие не ис-
пользует систему баз данных, в которой для каждого отдельного приложения создают-
ся свои файлы, чаще всего размещаемые на отдельных магнитных лентах или дисках,
в результате чего данные оказываются разрозненными. Систематически управлять та-
кими данными очень сложно.
Администрирование данных и администрирование
базы данных
Рассмотрим более подробно концепцию централизованного управления. Предпо-
лагается, что при централизованном управлении на предприятии, использующем ба-
зу данных, есть человек, который несет основную ответственность за данные пред-
приятия. Это администратор данных, или АД, уже упоминавшийся в этой главе. В
связи с тем, что данные (как было отмечено выше) — это одна из главных ценностей
предприятия, администратор должен разбираться в них и понимать нужды предпри-
ятия по отношению к данным на уровне высшего управляющего звена в руководстве
предприятием. Сам АД также должен относиться к этому звену. В обязанности ад-
46
Часть I. Основные понятия
министратора данных входит принятие решений о том, какие данные необходимо
вносить в базу данных в первую очередь, а также выработка требований по сопро-
вождению и обработке данных после их занесения в базу данных. Примером подоб-
ных требований может служить распоряжение о том, кто и при каких обстоятельст-
вах имеет право выполнять конкретные операции над теми или иными данными.
Другими словами, АД должен обеспечивать защиту данных (подробнее об этом
речь пойдет ниже).
Очень важно помнить, что администратор данных относится к управляющему звену,
а не к техническим специалистам (хотя он, конечно, должен иметь хорошее представле-
ние о возможностях баз данных на техническом уровне). Технический специалист, ответ-
ственный за реализацию решений администратора данных, — это администратор базы
данных, или АБД. Администратор базы данных, в отличие от администратора данных,
должен быть профессиональным специалистом в области информационных технологий.
Работа АБД заключается в создании самих баз данных и организации технического кон-
троля, необходимого для осуществления решений, принятых администратором данных.
АБД также несет ответственность за обеспечение необходимого быстродействия систе-
мы и ее техническое обслуживание. Обычно у АБД есть штат из системных программи-
стов и технических ассистентов (т.е. на практике функции АБД выполняются командой
из нескольких человек, а не одним служащим). Однако для простоты удобнее считать,
что администратор базы данных — один человек. Более подробно функции АБД обсуж-
даются в главе 2.
Преимущества централизованного подхода к управлению
данными
В заключение отметим преимущества использования баз данных, связанные с нали-
чием централизованного управления.
Возможность совместного доступа к данным
Этот вопрос уже обсуждался в разделе 1.2, но для полноты обсудим его еще раз.
Совместный доступ к данным означает не только возможность доступа к ним не-
скольких существующих приложений базы данных, но и возможность разработки
новых приложений для работы с этими же данными Другими словами, требова-
ния новых приложений по доступу к данным могут быть удовлетворены без необ-
ходимости добавления новых данных в базу.
Сокращение избыточности данных
В системах, не использующих базы данных, каждое приложение имеет свои фай-
лы. Это часто приводит к избыточности хранимых данных и, следовательно, к
расточительству пространства вторичной памяти. Например, как приложение, свя-
занное с учетом персонала, так и приложение, связанное с учетом обучения слу-
жащих, могут иметь собственные файлы с ведомственной информацией о служа-
щих. Как отмечено выше, эти два файла можно объединить с устранением избы-
точности (одинаковой информации) при условии, что администратор данных зна-
ет о том, какие данные нужны для каждого приложения, т.е. что на предприятии
осуществляется необходимое общее управление.
Глава 1. Базы данных и управление ими
47
В данном случае мы не имеем в виду, что избыточность данных может или должна
быть устранена полностью. Иногда веские практические или технические причины
требуют наличия нескольких копий хранимых данных. Однако такая избыточность
должна строго контролироваться, т.е. учитываться в СУБД. Кроме того, в подоб-
ном случае должна быть предусмотрена возможность “распространения обновле-
ний” (подробности приводятся ниже).
Устранение противоречивости данных (до некоторой степени)
В действительности это следствие предыдущего пункта. Возьмем пример из
жизни. Пусть служащий с номером ' ЕЗ', работающий в отделе с номером 'D8',
представлен двумя различными записями в базе данных. Предположим, что в
СУБД не учтено это раздвоение (т.е. избыточность данных не контролируется).
Тогда рано или поздно обязательно возникнет ситуация, при которой эти две за-
писи перестанут быть согласованными, когда одна из них будет изменена, а
другая — нет. В этом случае база данных станет противоречивой. Ясно, что
противоречивая база данных способна предоставлять пользователю неправиль-
ную, противоречивую информацию.
Также очевидно, что если какой-либо факт представлен одной записью (т.е.
при отсутствии избыточности), то противоречий возникнуть не может. Проти-
воречий можно также избежать, если не удалять избыточность, а контролиро-
вать ее (соответствующим образом известив об этом СУБД). Тогда СУБД
сможет гарантировать, что, с точки зрения пользователя, база данных нико-
гда не будет противоречивой. Данная гарантия обеспечивается тем, что если
обновление вносится в одну запись, то оно автоматически будет распростра-
нено на все остальные. Этот процесс называется распространением обнов-
лений (propagating updates).
Возможность поддержки транзакций
Транзакция (transaction) — это логическая единица работы, обычно включаю-
щая несколько операций базы данных (в частности, несколько операций изме-
нения). Стандартный пример — передача суммы денег со счета А на счет В.
Очевидно, что в данном случае необходимы два изменения: изъятие денег со
счета А и их внесение на счет В. Если пользователь укажет, что оба изменения
входят в одну и ту же транзакцию, то система сможет реально гарантировать,
что либо оба эти изменения будут выполнены, либо не будет выполнено ни одно
из них, даже если до завершения процесса изменений в системе произойдет
сбой (скажем, из-за перерыва в подаче электроэнергии).
Замечание. Упомянутое выше свойство атомарности (неделимости) транзакций —
это не единственное преимущество от поддержки транзакций. Однако в отличие от
прочих оно вполне применимо даже в однопользовательской среде2. Полное описа-
ние различных преимуществ поддержки транзакций и способы их достижения обсу-
ждаются в главах 14 и 15.
2 С другой стороны, часто в однопользовательских системах поддержка транзакций совсем
не предоставляется, а подобные проблемы просто перекладываются на плечи пользователя.
48
Часть I. Основные понятия
Обеспечение целостности данных
Задача обеспечения целостности заключается в гарантированной поддержке кор-
ректности данных в базе. Противоречивость между двумя записями, представ-
ляющими один “факт”, является примером утраты целостности данных (см. обсу-
ждение этого вопроса выше в данном разделе). Конечно, эта конкретная проблема
может возникнуть лишь при наличии избыточности в хранимых данных. Но даже
если избыточность отсутствует, база данных может содержать некорректную ин-
формацию. Например, в базе данных может быть указано, что сотрудник отрабо-
тал 400 рабочих часов в неделю вместо 40, или зафиксирована его принадлеж-
ность к отделу, которого не существует. Централизованное управление базой дан-
ных позволяет избежать подобных проблем (насколько их вообще возможно из-
бежать). Для этого администратор данных определяет (а АБД реализует) ограни-
чения целостности (integrity constraints), иначе называемые бизнес-правилами,
которые будут применяться при любой попытке внести какие-либо изменения в
соответствующие данные.
Отметим также, что целостность данных для многопользовательских систем баз
данных даже более важна, чем для среды с “частными файлами”, причем именно
по той причине, что такая база данных поддерживает совместный доступ. При от-
сутствии должного контроля один пользователь вполне может некорректно обно-
вить данные, от чего пострадают многие другие ни в чем не повинные пользовате-
ли. Следует также сказать, что в большинстве существующих коммерческих
СУБД поддержка ограничений целостности развита слабо, хотя в настоящее время
в этом направлении наблюдаются некоторые улучшения. Приходится констатиро-
вать тот печальный факт, что, как мы увидим в главе 8, ограничения целостности
имеют значительно более фундаментальное и критически важное значение, чем
это обычно признается на текущий момент.
Организация защиты данных
Благодаря полному контролю над базой данных АБД (безусловно, в соответствии с
указаниями администратора данных) может обеспечить доступ к ней только через
определенные каналы. Для этой цели могут устанавливаться ограничения защиты
(security constraints) или правила, которые будут проверяться при любой попытке
доступа к уязвимым данным. Можно установить различные правила для разных ти-
пов доступа (выборка, вставка, удаление и т.д.) к каждому из элементов информации
в базе данных. Однако следует заметить, что при отсутствии таких правил безопас-
ность данных подвергается большему риску, чем в обычной (разобщенной) файло-
вой системе. Следовательно, централизованная природа системы баз данных в опре-
деленном смысле требует наличия надежной системы защиты.
Возможность балансировки противоречивых требований
Зная общие требования всего предприятия (а не требования каждого отдельного
пользователя), АБД (опять же, в соответствии с указаниями администратора дан-
ных) может структурировать базу данных таким образом, чтобы обслуживание
было наилучшим для всего предприятия. Например, он может выбрать такое фи-
зическое представление данных во вторичной памяти, которое обеспечит быстрый
доступ к информации для наиболее важных приложений (возможно, с потерей
производительности для некоторых других приложений).
Глава 1. Базы данных и управление ими
49
Возможность введения стандартизации
Благодаря централизованному управлению базой данных АБД (по указаниям ад-
министратора данных) может обеспечить соблюдение всех подходящих стандар-
тов, регламентирующих представление данных в системе. Стандарты могут быть
частными, корпоративными, ведомственными, промышленными, национальными
и интернациональными. Стандартизация представления данных наиболее важна с
точки зрения обмена и пересылки данных между системами. (Наибольшую акту-
альность этот вопрос приобретает в случае распределенных систем, речь о кото-
рых пойдет в главах 2 и 20.) Кроме того, стандарты именования и документирова-
ния данных важны как в отношении их совместного использования, так и в отно-
шении их углубленного понимания.
Большинство перечисленных выше преимуществ достаточно очевидно. Однако есть
еще одно преимущество, которое необходимо добавить к этому списку и которое не
столь очевидно (хотя косвенно и охватывает несколько преимуществ). Речь идет об
обеспечении независимости данных. (Строго говоря, это, скорее, цель создания систем
баз данных, а не обязательное их преимущество.) Концепция независимости настолько
важна, что ей посвящен целый раздел, представленный ниже.
1.5. Независимость данных
Независимость данных может быть реализована на двух уровнях: физическом и логиче-
ском [1.3], [1.4]. Однако сейчас нас интересует только физическая независимость. Поэтому
неуточненный термин “независимость данных” мы пока будем понимать лишь как физиче-
скую независимость данных, а логическую независимость данных рассмотрим позднее, в
главах 2 и 3. Непосредственное отношение к этому вопросу имеет также глава 9.
Замечание. Пожалуй, необходимо отметить, что термин “независимость данных” не
совсем подходящий (он не отражает достаточно точно сущность происходящего). Но по-
скольку именно этот термин традиционно используется, мы последуем общему правилу.
Проще всего разобраться в понятии независимости данных на примере его про-
тивоположности. Приложения, реализованные в старых системах (“дореляционные”
или созданные даже до появления систем баз данных), в той или иной мере зависи-
мы от данных. Это означает, что способ организации данных во вторичной памяти и
способ доступа к ним диктуются требованиями приложения. Более того, сведения об
организации данных и способе доступа к ним встроены в саму логику и программ-
ный код приложения.
Пример. Предположим, у нас есть приложение, обрабатывающее файл EMPLOYEE
(см. рис. 1.4). Исходя из соображений эффективности примем, что этот файл про-
индексирован по полю имени работника (NAME). В старых системах в этом прило-
жении учитывалось бы, что такой индекс существует и что последовательность
записей в файле определена данным индексом. На основе этих сведений была бы
построена вся внутренняя структура приложения. В частности, избранный способ
реализации процедур доступа и обработки исключительных ситуаций в значи-
тельной степени зависел бы от особенностей интерфейса, предоставляемого про-
граммами управления данными.
50
Часть I. Основные понятия
Приложения, подобные описанному в этом примере, мы называем зависимыми
от данных, так как невозможно изменить физическое представление (т.е. способ
физического размещения данных во вторичной памяти) или метод доступа (т.е. кон-
кретный способ доступа к данным), не изменив самого приложения (возможно, ра-
дикально). Например, невозможно заменить индексированный файл в нашем приме-
ре хешированным файлом, не внеся в приложение значительных изменений. Более
того, изменению в подобных случаях подлежат те части приложения, которые взаи-
модействуют с программами управления данными. Трудности, возникающие при
этом, не имеют никакого отношения к проблеме, для решения которой было написа-
но данное приложение; это трудности, внесенные используемой структурой интер-
фейса управления данными.
Однако для системы баз данных крайне нежелательно, чтобы приложение зависело от
данных, и на то есть по меньшей мере две причины.
1. Для разных приложений требуются разные представления одних и тех же данных.
Например, предположим, что до перехода к интегрированной базе данных пред-
приятие имело два приложения, А и В. Каждое из них работало с собственным
файлом, содержащим поле “баланс заказчика”. Предположим также, что приложе-
ние А записывает значение этого поля в десятичном формате, а приложение В — в
двоичном. Эти два файла все еще можно интегрировать, а существующую избы-
точность устранить, если в СУБД есть возможность выполнить все необходимые
преобразования между форматом представления данных (формат представления
может быть десятичным, двоичным или любым другим) и форматом, необходимым
для приложения. Например, если принято решение сохранять значения поля в деся-
тичном формате, каждое обращение к приложению В потребует преобразования
значений в двоичный формат или из двоичного формата.
Это довольно простой пример различий, которые могут существовать в системе баз
данных между формой представления данных в приложении и формой их физиче-
ского хранения. Многие другие возможные различия будут рассмотрены ниже.
2. Администратор базы данных должен иметь неограниченные возможности изме-
нять физическое представление или метод доступа к данным в случае изменения
требований, причем без необходимости модифицировать существующие прило-
жения. Например, к базе данных могут быть добавлены новые виды данных, на
предприятии могут быть приняты новые стандарты, могут быть изменены при-
оритеты приложений (а следовательно, и связанные с ними требования к произ-
водительности), могут появиться новые типы запоминающих устройств и т.д. Ес-
ли приложения зависят от данных, то перечисленные изменения потребуют вне-
сения изменений в программы, а значит, дополнительных усилий программистов,
которые можно было бы направить на создание новых приложений. До сих пор
подобные проблемы не являются исключением. И сегодня случается, что значи-
тельная часть рабочего времени программистов (вспомните хотя бы проблему
2000-го года!) тратится на подобную работу, а это, конечно, бесполезная трата
дефицитных и ценных ресурсов.
Таким образом, обеспечение независимости данных — важнейшая цель создания
систем баз данных. Независимость данных можно определить как иммунитет при-
ложений к изменениям в физическом представлении данных и в методах дос-
Глава 1. Базы данных и управление ими
51
тупа к ним, а это означает, что рассматриваемые приложения не зависят от любых
конкретных способов физического представления информации или выбранных ме-
тодов доступа к ним. В главе 2 будет описана архитектура систем баз данных, обес-
печивающая основу для достижения этой цели. Однако прежде давайте более де-
тально рассмотрим некоторые примеры тех видов изменений, в выполнении кото-
рых у АБД может возникнуть необходимость и к которым, следовательно, должны
быть невосприимчивы приложения.
Начнем с определения трех новых терминов: хранимое поле, хранимая запись и хра-
нимый файл (рис. 1.6).
Файл PFILE, хранящий записи
типа "деталь" __________-
Два экземпляра
хранимой записи
типа "деталь"
Номер Название Цвет Вес
Номер Название Цвет Вес
детали детали детали детали
Рис. 1.6. Хранимые поля, записи и файлы
Хранимое поле— это наименьшая единица хранимых данных. Типичная база
данных содержит множество экземпляров (occurence или instance) каждого из
нескольких описанных в ней типов или хранимых полей. Например, база дан-
ных, содержащая информацию о деталях, может включать тип хранимого поля с
именем “номер детали” и для каждого описанного в базе данных вида детали
(винта, шарнира, колпака и т.д.) будет существовать отдельный экземпляр этого
хранимого поля.
52
Часть I. Основные понятия
Замечание. На практике часто опускают квалификаторы “тип” и “экземпляр”, по-
лагая, что точный смысл ясен по контексту. Хотя и существует небольшая вероят-
ность путаницы, это удобная практика, и мы будем ей время от времени следо-
вать. (Это замечание также относится к хранимым записям, речь о которых пойдет
в следующем абзаце.)
Хранимая запись — это набор связанных хранимых полей. И снова мы различа-
ем для них тип и экземпляр. В данном случае экземпляр хранимой записи состоит
из группы связанных экземпляров хранимых полей. Например, экземпляр храни-
мой записи в базе данных деталей состоит из экземпляров каждого из следующих
хранимых полей: “номер детали”, “название детали”, “цвет детали” и “вес детали”.
Мы говорим, что база данных содержит множество экземпляров хранимой записи
типа “деталь” (опять же, один экземпляр для каждой конкретной детали).
И наконец, хранимый файл — это набор всех существующих в настоящий мо-
мент экземпляров хранимых записей одного и того же типа.
Замечание. Для упрощения предполагается, что любой заданный хранимый файл
может содержать хранимые записи только одного типа. Это упрощение не окажет
существенного влияния на последующие рассуждения.
В современных системах, отличных от баз данных, логическая запись (с точки зрения
приложения) обычно совпадает с соответствующей хранимой записью. Как было показа-
но выше, в базах данных это вовсе не обязательно, поскольку АБД в любой момент мо-
жет потребоваться внести изменения в структуру хранения данных (т.е. в хранимые поля,
записи, файлы), в то время как структура данных с точки зрения приложения должна ос-
таться неизменной. Например, поле DEPARTMENT в файле EMPLOYEE для экономии памяти
может быть сохранено в двоичном формате, тогда как приложение, написанное на языке
COBOL, может рассматривать это поле в качестве символьной строки. А позже может
понадобиться изменить двоичную форму представления этого поля на десятичную, со-
хранив для приложения возможность обрабатывать поле в символьном формате.
Как утверждалось ранее, такие различия потребуют преобразования типа данных по-
добного поля при каждом обращении к нему, хотя в целом эти различия можно считать
сравнительно незначительными. Однако, в принципе, разница между тем, что видит при-
ложение, и тем, что сохраняется на самом деле, может быть довольно значительна. Раз-
вивая это замечание, перечислим те аспекты структур хранения данных в базах, которые
могут подвергаться изменениям. Читателю предлагается самостоятельно подумать над
тем, что должна сделать СУБД для защиты приложения от таких изменений (и всегда ли
такую защиту можно обеспечить).
Представление числовых данных
Числовое поле может храниться во внутренней арифметической форме (например,
в упакованном десятичном формате) или в виде символьной строки. В каждом
случае АБД должен определить подходящее основание системы счисления
(например, двоичную или десятичную систему), масштаб (число с фиксированной
или плавающей запятой), тип (действительное число или комплексное) и точность
(количество цифр). Каждый из этих параметров может быть изменен с целью по-
вышения производительности, при введении нового стандарта или по некоторым
другим причинам.
Глава 1. Базы данных и управление ими
53
Представление символьных данных
Поле в формате символьной строки может сохраняться с использованием любого из
существующих наборов кодировки символов (например, ASCII, EBCDIC, Unicode).
Единицы измерения для числовых данных
Единицы измерения числовых полей могут быть изменены, например дюймы могут
быть' изменены на сантиметры, если приложение связано с процессами измерения.
Кодирование данных
В некоторых ситуациях может понадобиться представлять данные в хранилище
кодированными значениями. В частности, поле “цвет детали”, которое представ-
лено в приложении как символьная строка (“красный”, “голубой”, “зеленый”),
может храниться в виде десятичной цифры в соответствии с некоторой таблицей
перекодировки, например 1 = “красный”, 2 = “голубой” и т.д.
Овеществление данных
Используемое приложением логическое поле обычно действительно соответст-
вует некоторому определенному хранимому полю (хотя, как мы видели ранее,
могут существовать различия в типе данных, единицах и т.д.). В этом случае
процесс овеществления (materialization), т.е. построения экземпляра логического
поля из соответствующего экземпляра хранимого поля и его передачи приложе-
нию, можно назвать прямым. Однако иногда логическое поле может не иметь
соответствующего эквивалентного хранимого поля, а его значение будет овеще-
ствляться посредством некоторых вычислений, выполняемых над набором из
нескольких экземпляров хранимых полей. Например, значение логического по-
ля “общее количество” можно определить путем суммирования нескольких хра-
нимых значений поля “количество”. Поле “общее количество” — это пример
виртуального (virtual) поля; процесс определения его значения называют не-
прямым. Заметим, однако, что пользователь может отличить реальное поле от
виртуального, так как экземпляр виртуального поля нельзя добавить или изме-
нить (по крайней мере, непосредственно).
Структура хранимых записей
Две существующие хранимые записи можно объединить в одну. Например, хра-
нимые записи
| Номер детали | Цвет детали | и | Номер детали | Вес детали |
можно представить в форме
| Номер детали | Цвет детали | Вес детали ~|
Такие изменения могут выполняться, когда в систему баз данных интегрируются
некоторые ранее существовавшие приложения. При этом предполагается, что ло-
гическая запись приложения может состоять из определенного подмножества по-
лей соответствующей хранимой записи, т.е. некоторые поля хранимой записи бу-
дут “невидимы” для рассматриваемого приложения.
И наоборот, одна хранимая запись может быть разделена на две. Воспользуемся
записями из предыдущего примера. Тогда хранимую запись
54
Часть I. Основные понятия
| Номер детали | Цвет детали | Вес детали |
можно разбить на две:
| Номер детали | Цвет детали [ и | Номер детали | Вес детали |
Такое разделение позволяет переместить редко используемые части исходной за-
писи в другое место, например на более медленное устройство. При этом неявно
предполагается, что логическая запись приложения может содержать поля из не-
скольких отдельных хранимых записей, т.е. логическая запись является расшире-
нием любой из этих хранимых записей.
Структура хранимых файлов
Определенный хранимый файл может физически сохраняться в памяти разными
способами. Например, его можно разместить на одном томе памяти (скажем, на
одном диске) или распределить на нескольких томах, возможно, разных типов
устройств. Он может быть физически упорядочен в соответствии со значениями
некоторого хранимого поля либо быть упорядоченным каким-либо иным спосо-
бом, например с помощью одного либо нескольких индексов или встроенных це-
почек указателей, или же доступ к его записям может быть организован по методу
хеширования. Хранимые записи могут быть (а могут и не быть) физически объе-
динены в блоки (по нескольку в одной физической записи). Но ни один из этих
факторов не должен каким-либо образом влиять на приложение (за исключением,
конечно, эффективности его выполнения).
Этим мы ограничим перечень аспектов структуры хранения данных, которые могут
подвергаться изменениям. Здесь среди всего прочего предполагается, что база данных
может расти (grow) и развиваться, не оказывая влияния на приложения. В действитель-
ности возможность развития базы данных без логического ущерба для существующих
приложений является одним из наиболее важных мотивов обеспечения независимости
данных. Например, можно было бы расширить существующий тип хранимой записи, до-
бавив новые хранимые поля, которые обычно представляют дополнительную информа-
цию о некоторых существующих типах сущностей (скажем, к хранимой записи “деталь”
можно добавить поле “цена”). Такие новые поля будут невидимы для существующих
приложений. Точно так же можно добавить новые типы хранимых записей (а следова-
тельно, новые хранимые файлы), не изменяя существующих приложений. Подобные за-
писи обычно представляют собой новые типы сущностей (например, к базе данных
“детали” можно добавить тип записи “поставщик”). Эти изменения также будут незамет-
ны для существующих приложений.
Теперь легко понять, что независимость данных — одна из причин разделения моде-
ли данных и ее реализации, как уже указывалось в конце раздела 1.3. И очень важно от-
метить, что чем больше будет такое разделение, тем большая независимость данных бу-
дет обеспечена. Недостаточное разделение модели и ее реализации — широко распро-
страненный недостаток, свойственный, в частности, современным системам, исполь-
зующим язык SQL, что особенно огорчает.
Замечание. Последнее замечание (относительно использующих язык SQL совре-
менных систем) вовсе не означает, что в подобных системах совершенно не обеспе-
чена независимость от данных. Оно лишь указывает, что эти системы обеспечивают
независимость данных в значительно меньшей степени, чем теоретически возможно
Глава 1. Базы данных и управление ими
55
в реляционных системах. Иными словами, независимость данных — понятие отно-
сительное. Различные системы обеспечивают ее в разной мере или не обеспечивают
вообще. Системы, базирующиеся на языке SQL, более развиты в этом направлении,
чем старые системы, однако, как мы увидим в последующих главах, все они еще да-
леки от совершенства.'
1.6. Реляционные и другие системы
Как уже упоминалось в конце раздела 1.3, СУБД, базирующиеся на реляционной мо-
дели данных (“реляционные системы”), в настоящее время стали преобладающими на
рынке баз данных. Более того, подавляющее большинство научных исследований в об-
ласти баз данных в течение последних 30 лет было посвящено (иногда косвенно) именно
этой модели. Фактически введение реляционной модели в 1969 и 1970 годах было, несо-
мненно, наиболее важным событием в истории развития теории баз данных. По этим
причинам, а также учитывая то, что реляционная модель основана на определенных ма-
тематических и логических принципах и, следовательно, идеально подходит для изложе-
ния теоретических концепций систем баз данных, основное внимание в настоящей книге
уделяется (как уже отмечалось в разделе 1.1) именно реляционным системам и реляци-
онному подходу.
Что мы подразумеваем под реляционной системой? К сожалению, на данном этапе
обсуждения невозможно дать полный ответ на этот вопрос. Однако можно (и нужно!)
дать хотя бы приблизительный ответ, который в дальнейшем будет существенно уточ-
нен. Итак, кратко и не совсем точно реляционная система — это система, основанная на
следующих принципах.
1. Данные передаются пользователю в виде таблиц (и никак иначе).
2. Пользователю предоставляются операторы (например, для выборки данных), по-
зволяющие генерировать новые таблицы на основании уже существующих. Напри-
мер, в системе обязательно должны присутствовать оператор ограничения, предна-
значенный для получения подмножества строк заданной таблицы, и оператор про-
екции, позволяющий получить подмножество ее столбцов. Однако подмножество
строк и подмножество столбцов некоторой таблицы, безусловно, можно рассмат-
ривать как новые таблицы.
Замечание. Причина, по которой такие системы называют реляционными, состоит в
том, что английский термин “relation” (отношение), по сути, представляет собой приня-
тое математическое название для таблицы. Поэтому на практике термины отношение и
таблица в большинстве случаев можно считать синонимами, по крайней мере для не-
формальных целей. (Обсуждение этого вопроса будет продолжено в главах 3 и 5.) Воз-
можно, следует добавить, что причина, несомненно, заключается не в том, что термин
отношение (relation) “по существу— просто математическое название для” связи
(relationship) в терминах диаграмм “сущность-связь” (см. раздел 1.3). На самом деле ме-
жду реляционными системами и подобными диаграммами существует совсем незначи-
тельная прямая связь, что будет показано в главе 13.
Как уже отмечалось, в дальнейшем будет дано более точное определение, а сейчас мы
будем использовать приведенное выше. На рис. 1.7 представлен пример структуры дан-
ных и операторов, используемых в реляционных системах. Данные (рис. 1.7, а) пред-
56
Часть I. Основные понятия
ставлены одной таблицей под названием CELLAR (в действительности это еще одна вер-
сия таблицы CELLAR (см. табл. 1.1), просто уменьшенная для того, чтобы с ней было лег-
че работать). На рис. 1.7, б показаны два примера выборки данных: один — с получени-
ем подмножества строк (оператор ограничения}, а другой — с получением подмножества
столбцов (оператор проекции).
Замечание. Оба варианта выборки осуществляются с помощью оператора SELECT
языка SQL, упомянутого выше в этой главе.
Теперь мы можем различать реляционные и не реляционные системы по следую-
щим признакам. Как уже отмечалось, пользователь реляционной системы видит дан-
ные в виде таблиц и никак иначе. Пользователь не реляционной системы, напротив,
видит данные, представленные в других структурах: либо вместо таблиц реляционной
системы, либо наряду с ними. Для работы с этими другими структурами применяются
другие операции. В частности, в иерархической системе (например, IMS фирмы IBM)
данные представляются пользователю в форме набора древовидных структур
(иерархий), а среди операций работы с иерархическими структурами есть операции
перемещения по иерархическим указателям (навигации) вверх и вниз по ветвям де-
ревьев. (Реляционные системы, как мы видели, не имеют таких указателей, и это очень
важная их отличительная особенность.)
а) Дана таблица: CELLAR WINE YEAR BOTTLES
Chardonnay 1996 4
Fume Blanc 1996 2
Pinet Noir 1993 3
Zinfandel 1994 9
б) Примеры операторов:
1. Подмножество строк: Результат: WINE YEAR BOTTLES
SELECT WINE, YEAR, BOTTLES Chardonnay 1996 4
FROM CELLAR Fume Blanc 1996 2
WHERE YEAR > 1995 ;
2. Подмножество столбцов: Результат: WINE BOTTLES
SELECT WINE, BOTTLES Chardonnay 4
FROM CELLAR ; Fume Blanc 2
Pinet Noir 3
Zinfandel 9
Рис. 1.7. Структура данных и операторы в реляционной системе (примеры)
Рассмотрим этот вопрос немного подробнее. На практике системы баз данных мо-
гут быть легко распределены по категориям в соответствии со структурами данных и
операторами, которые они предоставляют пользователю. Прежде всего, старые (доре-
ляционные) системы можно разделить на три большие категории, а именно: системы
инвертированных списков (inverted list), иерархические (hierarchic) и сетевые
Глава 1. Базы данных и управление ими
57
(network)3. В данной книге мы не будем подробно рассматривать эти категории, по-
скольку, по крайней мере с точки зрения технологии, их можно считать устаревшими.
(Учебное описание всех трех систем можно найти в [1.5], если вас это интересует.)
Кроме того, необходимо отметить, что термин сетевая (система) в данном случае не
имеет ничего общего с коммуникационной сетью, а относится лишь к структуре дан-
ных и операторам, которые поддерживаются данной системой.
Замечание. Сетевые системы иногда называют системами CODASYL или система-
ми DBTG по имени группы, которая их предложила— Data Base Task Group (DBTG)
of the Conference on Data Systems Languages (CODASYL). Пожалуй, наиболее извест-
ной из таких систем была IDMS корпорации Computer Associates International, Inc. По-
добно иерархическим системам (но в отличие от реляционных), все такие системы,
кроме всего прочего, предоставляли в распоряжение пользователя внутренние указа-
тели на элементы данных.
Первые реляционные продукты начали появляться в конце 1970-х и начале 1980-х
годов. Во время написания этой книги преобладающее большинство СУБД были реля-
ционными и предназначались для работы на практически любой программной и аппа-
ратной компьютерной платформе. Среди них ведущими (в алфавитном порядке) явля-
лись следующие: DB2 (всевозможные версии) корпорации IBM; Ingres II корпорации
Computer Associates International, Inc.; Informix Dynamic Server корпорации Informix
Software, Inc.; Microsoft SQL Server корпорации Microsoft; Oracle 8i корпорации Oracle и
Sybase Adaptive Server компании Sybase, Inc.
Замечание. Если нам придется ссылаться на эти продукты ниже в настоящей книге,
мы будем называть их (как это делается в большинстве случаев) сокращенными имена-
ми: DB2, Ingres, Informix, SQL Server, Oracle и Sybase.
В последнее время стали появляться объектно-ориентированные и объектно-
реляционные продукты4. Большинство объектно-реляционных СУБД основывается на
совместимых снизу вверх расширениях оригинальных реляционных продуктов, как это
случилось с DB2 или Informix. Существующие объектно-ориентированные системы
представляют собой попытки сделать что-то совершенно отличное, как это имеет место в
случае с системой GemStone корпорации GemStone Systems, Inc. и системой Versant
ODBMS компании Object Technology. Мы рассмотрим эти новые системы в части VI.
В дополнение к различным уже упоминавшимся выше подходам в течение несколь-
ких лет проводились исследования множества альтернативных схем, включая много-
мерный (multi-dimensional) подход и логический (logic-based) подход, называемый еще
дедуктивным или экспертным. Мы рассмотрим многомерные системы в главе 21, а ло-
гические — в главе 23.
3 По аналогии с реляционной моделью в ранних изданиях книги использовались термины мо-
дель инвертированных списков, иерархическая модель и сетевая модель (они также использова-
лись в других книгах). Однако это не совсем верно, поскольку по сравнению с реляционной моде-
лью "модели” инвертированного списка, иерархическая и сетевая были определены после свер-
шившегося факта, т.е. соответствующие коммерческие продукты были реализованы раньше, а
"модели ” были определены впоследствии "по индукции ” (в этом контексте изящный термин для
приблизительной оценки) из уже существующих реализаций.
4 Термин объект здесь имеет довольно специфическое значение, которое будет подробно по-
яснено в части VI. А пока мы будем использовать этот термин в его обычном общем смысле,
кроме случаев явного указания на противоположное.
58
Часть I. Основные понятия
1.7. Резюме
В заключение этой вводной главы подведем итог обсуждению основных вопросов.
Систему баз данных можно рассматривать как компьютеризированную систему хране-
ния записей. Такая система включает сами по себе данные (сохраняемые в базе дан-
ных), аппаратное обеспечение, программное обеспечение (в частности, систему
управления базами данных, или СУБД), а также пользователей (что наиболее важно).
Пользователи, в свою очередь, подразделяются на прикладных программистов, ко-
нечных пользователей и администраторов баз данных, или АБД. Последние отвеча-
ют за администрирование базы данных и всей системы баз данных в соответствии с тре-
бованиями, устанавливаемыми администратором данных.
Базы данных являются интегрированными и чаще всего совместно используемы-
ми. Они применяются для хранения перманентных данных. Можно считать (хотя это и
не совсем точно), что эти данные представляют собой сущности и существующие между
сущностями связи, хотя сами связи — это, по сути, просто специальный вид сущности.
Очень кратко мы рассмотрели понятие диаграмм “сущность-связь”.
Система баз данных имеет ряд преимуществ, наиболее важным из которых является
физическая независимость данных. Независимость данных может быть определена как
иммунитет прикладных программ к изменениям способа хранения данных и используе-
мых методов доступа. Среди всего прочего для независимости данных требуется строгое
разделение между моделью данных и ее реализацией. (По ходу напоминаем, что тер-
мин модель данных, к нашему сожалению, имеет два различных значения.)
Системы баз данных обычно поддерживают транзакции или логические единицы
работы. Основное преимущество транзакций заключается в том, что они гарантируют
атомарность выполняемых действий (все или ничего), несмотря на возможные сбои сис-
темы, имевшие место до завершения выполнения транзакции.
И наконец, система баз данных может быть основана на нескольких различных под-
ходах. Реляционные системы базируются на формальной теории, называемой реляци-
онной моделью, в соответствии с которой данные представляются в виде строк в табли-
цах (и интерпретируются как истинные высказывания), а пользователям предоставля-
ются операторы, обеспечивающие поддержку процесса получения дополнительных ис-
тинных высказываний в виде следствий из существующих данных. И с экономической, и
с теоретической точек зрения можно считать, что реляционные системы являются наи-
более важным сегментом рынка (и это положение дел, по-видимому, в обозримом буду-
щем не изменится). Мы рассмотрели несколько примеров использования языка SQL —
стандартного языка для работы с реляционными системами (в частности, были приведе-
ны примеры операторов SELECT, INSERT, UPDATE и DELETE этого языка). Материал дан-
ной книги в значительной мере ориентирован на реляционные системы и по причинам,
указанным в предисловии, в меньшей мере — на собственно язык SQL.
Упражнения
1.1. Дайте определения следующим терминам.
АБД параллельный доступ
администрирование данных перманентные данные
база данных свойство
Глава 1. Базы данных и управление ими
59
бинарная связь
диаграмма “сущность-связь”
защита
избыточность
интеграция
интерактивное приложение
командный интерфейс
многопользовательская система
независимость данных
некомандный интерфейс (меню)
некомандный интерфейс (формы)
связь
система баз данных
совместное использование данных
СУБД
сущность
транзакция
хранимая запись
хранимое поле
хранимый файл
целостность
язык запросов
1.2. Каковы преимущества использования системы баз данных?
1.3. Каковы недостатки использования системы баз данных?
1.4. Как вы понимаете термин реляционная система? Назовите различия между реля-
ционной и не реляционными системами.
1.5. Как вы понимаете термин модель данных? Объясните различие между моделью
данных и ее реализацией. Почему так важно это различие?
1.6. Приведите результат выполнения следующих SQL-операторов выборки информа-
ции из базы данных винного погреба, представленной в табл. 1.1.
a) SELECT WINE, PRODUCER
FROM CELLAR
WHERE BIN# = 72 ;
6) SELECT WINE, PRODUCER
FROM CELLAR
WHERE YEAR > 1996 ;
в) SELECT BIN#, WINE, YEAR
FROM CELLAR
WHERE READY < 1999 ;
r) SELECT WINE, BIN#, YEAR
FROM CELLAR
WHERE PRODUCER = 'Robt. Mondavi'
AND BOTTLES > 6 ;
1.7. Дайте собственную словесную интерпретацию типичной строки по каждому из от-
ветов к упр. 1.6, представив ее в виде истинного высказывания.
1.8. Приведите результат выполнения следующих SQL-операторов внесения изменений
в базу данных винного погреба, представленную в табл. 1.1.
a) INSERT
INTO CELLAR (BIN#, WINE, PRODUCER, YEAR, BOTTLES, READY )
VALUES (80, 'Syrah', 'Meridian', 1994, 12, 1999 );
60
Часть L Основные понятия
6) DELETE
FROM CELLAR
WHERE READY > 2000 ;
в) UPDATE CELLAR
SET BOTTLES = 5
WHERE BIN# = 50 ;
r) UPDATE CELLAR
SET BOTTLES = BOTTLES + 2
WHERE BIN# = 50 ;
1.9. Напишите SQL-оператор для выполнения следующих операций в базе данных вин-
ного погреба.
а) Выберите номер ячейки (BIN#), наименование вина и количество бутылок для
всех вин производства 'Geyser Peak'.
б) Выберите номер ячейки (BIN#) и наименование вина для всех вин, запас кото-
рых составляет более пяти бутылок.
в) Выберите номер ячейки (BIN#) для всех красных вин.
г) Добавьте три бутылки (BOTTLES) в ячейку (BIN#) с номером 30.
д) Удалите из всего запаса все вина производства компании 'Chardonnay'.
е) Добавьте данные нового поступления (12 бутылок): производитель— 'Gary
Farrell', сорт— 'Merlot', ячейка номер 55, год выпуска— 1996, будет гото-
во в 2001 году.
1.10. Предположим, что у вас есть коллекция записей классической музыки, содер-
жащаяся на компакт-дисках, пластинках и/или аудиокассетах, и вы хотите по-
строить базу данных, которая позволит находить записи определенного компо-
зитора (например, Сибелиуса), дирижера (например, Симона Ратла), солиста
(например, Артура Грюмикса), произведения (например, Пятой симфонии Бет-
ховена), оркестра (например, NYPO), вида произведения (например, концерта
для виолончели) или камерной группы (например, квартета Кронус). Начерти-
те диаграмму “сущность-связь” для этой базы данных по образцу, представ-
ленному на рис. 1.5.
Список литературы
1.1. Codd E.F. Data Models in Databases Management // Proc. Workshop on Data
Abstraction, Database and Conceptual Modelling. — Pingree Park, Colo, June, 1980.
(ACM SIGART Newsletter. — January, 1981, №74; ACM SIGMOD Record 11.—
February, 1981, №2; ACM SIGPLAN Notices 16. —January, 1981, № 1.)
Кодд является создателем реляционной модели, которую он впервые описал в
[5.1]. Однако в этой работе он на самом деле не дал определения термину модель
данных как таковому, оно было дано (гораздо позже) лишь в данной работе. В ней
рассматривается вопрос “Каково назначение моделей данных вообще и реляцион-
ной модели в частности?”, а также приводятся факты, подтверждающие, что во-
преки распространенному мнению реляционная модель фактически стала первой
Глава 1. Базы данных и управление ими
61
моделью данных, которая вообще была определена. (Иначе говоря, у Кодда есть
право называться создателем концепции модели данных вообще, а также реляци-
онной модели в частности.)
1.2. Darwen Н. What a Database Really Is: Predicates and Propositions // Date C.J., Darwen
H., and McGoveran D. Relational Database Writings 1994-1997.— Reading, Mass.:
Addison-Wesley, 1998.
В этой статье дается неформальное, но точное объяснение идеи (которая кратко
обсуждалась в конце раздела 1.3), содержащей утверждение, что базу данных луч-
ше представлять как набор истинных высказываний.
1.3. Date C.J. and Hopewell Р. Storage Structures and Physical Data Independence // Proc.
ACM SIGFIDET Workshop on Data Definition, Access, and Control. — San Diego,
California, November, 1971.
1.4. Date C.J. and Hopewell P. File Definition and Logical Data Independence // Proc. ACM
SIGFIDET Workshop on Data Definition, Access, and Control. — San Diego,
California, November, 1971.
Статьи [1.3], [1.4] являются первыми письменными работами, в которых было оп-
ределено различие между физической и логической независимостью данных.
1.5. Date C.J. Relation Database Writtings 1991-1994. — Reading, Mass.: Addison-Wesley, 1995.
Ответы к некоторым упражнениям
1.3. Перечислим некоторые недостатки.
Без надлежащего контроля защита данных может оказаться ослабленной.
Целостность данных может быть подвергнута риску (без надлежащего контроля).
Может потребоваться дополнительное аппаратное обеспечение.
Дополнительная нагрузка на вычислительную систему может оказаться весьма
значительной.
Успешное выполнение операции становится критически важным (предприятие
может оказаться весьма уязвимым по отношению к сбоям системы).
Система, вероятно, будет сложной (хотя такие сложности должны быть скрыты
от конечного пользователя).
1.6. Вариант а:
WINE |PRODUCER
Zinfandel | Rafanelli
Вариант б:
WINE PRODUCER
Chardonnay Buena Vista
Chardonnay Geyser Peak
Jo. Riesling Jekel
Fumft Blanc Ch. St. Jean
Gewurztraminer Ch. St. Jean
62
Часть I. Основные понятия
Вариант в:
BIN# WINE YEAR
6 Chardonnay 1996
22 Fume Blanc 1996
52 Pinot Noir 1995
Вариант г:
WINE BIN# YEAR
Cab. Sauvigon 48 1993
1.7. Приведем решение только для п. а: “Компания Rafaneili является изготовителем
вина Zinfandel” или, более точно, “Некоторые ячейки содержат некоторые бутылки
с вином Zinfandel, которое было изготовлено компанией Zinfandel в некотором го-
ду, и они будут готовы к употреблению в некотором году”.
1.8. Вариант а: добавление в таблицу CELLAR строки со значением 80 в поле BIN#.
Вариант б: удаление из таблицы CELLAR строк со значениями 45, 48, 64 и 72 в поле BIN#.
Вариант в: количество бутылок (поле BOTTLES) устанавливается равным пяти для
строки со значением 50 в поле BIN#.
Вариант г: то же, что и вариант в.
Кстати, обратите внимание, как удобно обращаться к строкам по их первичному
ключу (первичный ключ для таблицы CELLAR— поле BIN#) (подробности приво-
дятся в главе 8).
1.9. Ниже приведены соответствующие операторы.
a) SELECT BIN#, WINE, BOTTLES
FROM CELLAR
WHERE PRODUCER = 'Geyser Peak' ;
6) SELECT BIN#, WINE
FROM CELLAR
WHERE BOTTLES > 5 ;
в) SELECT BIN#
FROM CELLAR
WHERE WINE = 'Cab. Sauvignon'
OR WINE = 'Pinot Noir'
OR WINE = 'Zinfandel'
OR WINE = 'Syrah'
OR........... ;
На этот вопрос нет краткого ответа, так как цвет вина не записан в базе данных
в явном виде, и поэтому СУБД не знает, что, например, вино 'Pinot Noir'
красное.
Глава 1. Базы данных и управление ими
63
г) UPDATE CELLAR
SET BOTTLES = BOTTLES + 3
WHERE BIN# = 30 ;
д) DELETE
FROM CELLAR
WHERE WINE = 'Chardonnay' ;
e) INSERT
INTO CELLAR (BIN#, WINE, PRODUCER, YEAR, BOTTLES, READY )
VALUES (55, 'Merlot', 'Gary Farrell', 1996, 12, 2001 );
64
Часть I. Основные понятия
Глава 2
Архитектура системы
баз данных
2.1. Введение
Теперь, после изучения вводной главы, можно познакомиться с архитектурой систе-
мы баз данных. Наша цель — заложить фундамент, на котором будет строиться даль-
нейшее изложение. Именно на этот фундамент мы будем опираться при описании общих
понятий и объяснении структуры специфических систем баз данных. Однако это вовсе
не означает, что каждая система баз данных обязательно должна отвечать конкретному
фундаменту или что предложенная конкретная архитектура является единственно воз-
можным вариантом. Например, “малые” системы (см. главу 1), весьма вероятно, не бу-
дут поддерживать все аспекты предложенной архитектуры. Тем не менее рассматривае-
мая архитектура с достаточной точностью описывает большинство систем (и не только
реляционных). Более того, она практически полностью согласуется с архитектурой,
предложенной исследовательской группой ANSI/SPARC (Study Group on Data
Management Systems), — так называемой архитектурой ANSI/SPARC [2.1], [2.2]. Однако
здесь мы не будем придерживаться терминологии ANSI/SPARC во всех деталях.
Замечание. Материал этой главы подобен материалу предыдущей в том смысле, что
он является основой, необходимой для полного понимания структуры и возможностей
современных систем баз данных. По этой причине он также носит несколько абстракт-
ный характер, а следовательно, он достаточно “сухой”. Учитывая это, как и в случае изу-
чения главы 1, предварительно можно бегло просмотреть настоящую главу, а затем, по
мере освоения излагаемого в книге материала, возвращаться к отдельным ее разделам,
непосредственно связанным с той или иной изучаемой вами темой.
2.2. Три уровня архитектуры
Архитектура ANSI/SPARC включает три уровня: внутренний, внешний и концепту-
альный (рис. 2.1). В общих чертах они представляют собой следующее.
Внутренний уровень (также называемый физическим) наиболее близок к физи-
ческому хранилищу информации, т.е. связан со способами сохранения информа-
ции на физических устройствах.
Внешний уровень (также называемый пользовательским логическим) наиболее
близок к пользователям, т.е. связан со способами представления данных для от-
дельных пользователей.
Концептуальный уровень (также называемый общим логическим или просто ло-
гическим) является “промежуточным” уровнем между двумя первыми.
Глава 2. Архитектура системы баз данных
65
Рис. 2.1. Три уровня архитектуры ANS1/SPARC
Если внешний уровень связан с индивидуальными представлениями пользователей, то
концептуальный уровень связан с обобщенным представлением пользователей. Иначе
говоря, может существовать несколько внешних представлений, каждое из которых со-
стоит из более или менее абстрактного представления определенной части базы данных,
и только одно концептуальное представление, состоящее из абстрактного представления
базы данных в целом1. (Вспомните, что большинство пользователей интересует не вся
база данных, а лишь ее некоторая ограниченная часть.) Также существует единственное
внутреннее представление, отражающее способ физического хранения всей базы данных.
Для лучшего понимания этих идей рассмотрим пример, представленный на рис. 2.2.
Здесь отображено концептуальное представление простой базы данных о персонале, а
также соответствующие ему внутреннее и два внешних представления (одно — для поль-
зователя, применяющего язык PL/I, а другое — для пользователя, применяющего язык
COBOL). Конечно, этот пример полностью гипотетичен и мало похож на реальные сис-
темы, поскольку в нем умышленно опущены многие не относящиеся к делу детали.
Рассматриваемый здесь пример нуждается в пояснениях.
На концептуальном уровне база данных содержит информацию о типе сущности с
именем EMPLOYEE (служащий). Каждый экземпляр сущности EMPLOYEE включает
атрибуты номера служащего EMPLOYEE NUMBER (длиной шесть символов), номера
отдела DEPARTMENT NUMBER (длиной четыре символа) и зарплаты служащего
SALARY (пять десятичных цифр).
На внутреннем уровне служащие представлены типом хранимой записи
STORED_EMP, длина которой составляет 20 байт. Запись STORED_EMP содержит че-
тыре хранимых поля: шестибайтовый префикс (возможно, содержащий управ-
ляющую информацию, такую как флаги или указатели) и три поля данных, соот-
ветствующие трем свойствам сущности, которая представляет служащего. Кроме
того, записи STORED_EMP индексированы по полю EMP# с помощью индекса ЕМРХ,
определение которого не показано.
1 Называя некоторое представление абстрактным, мы имеем в виду лишь то, что оно включа-
ет логические конструкции, ориентированные на пользователя (например, логические записи или
поля), и не включает машинно-ориентированные конструкции (например, биты или байты).
66
Часть 1. Основные понятия
Внешний (PL/I) Внешний (COBOL)
DCL 1 ЕМРР, 2 EMP# CHAR(6), 3 SAL FIXED BIN(31); 01 EMPC. 02 EMPNO PIC X(6). 02 DEPTNO PIC X(4).
Концептуальный EMPLOYEE EMPLOYEE NUMBER CHARACTER (6) CHARACTER (4) DEPARTMENT NUMBER SALARY " NUMERIC (5)
Внутренний STORED_EMP BYTES=20 PREFIX TYPE=BYTE(6), OFFSET=0 EMP# TYPE=BYTE(6), OFFSET=6, INDEX=EMPX DEPT# TYPE=BYTE(4), OFFSET=12 PAY TYPE=FULLWORD, OFFSET=16
Рис. 2.2. Пример трех уровней представления базы данных
Пользователь, применяющий язык PL/I, имеет дело с соответствующим внеш-
ним представлением базы данных. В нем каждый сотрудник представлен за-
писью на языке PL/I, содержащей два поля (номера отделов не представляют
интереса для данного пользователя, поэтому в представлении они опущены).
Тип записи определен с помощью обычной структуры, соответствующей пра-
вилам языка PL/I.
Аналогично пользователь, применяющий язык COBOL, имеет дело с собст-
венным внешним представлением базы данных, в котором каждый сотрудник
представлен записью на языке COBOL, содержащей, опять же, два поля (в
данном случае опущен размер оклада). Тип записи определен с помощью
обычного описания на языке COBOL в соответствии с принятыми в нем стан-
дартными правилами.
Обратите внимание, что в каждом случае соответствующие элементы данных могут
иметь различные имена. Например, к номеру сотрудника обращаются, как к полю ЕМР# в
представлении для языка PL/I и как к полю EMPNO в представлении для языка COBOL.
Этот же атрибут в концептуальном представлении имеет имя EMPLOYEE NUMBER, а во
внутреннем представлении— имя ЕМР#. Конечно, системе должны быть известны все
эти соответствия. Например, она должна знать, что поле EMPNO в представлении для язы-
ка COBOL образовано из концептуального поля EMPLOYEE_NUMBER, которое, в свою оче-
редь, отвечает хранимому полю EMP# во внутреннем представлении. Такие соответствия,
или отображения (mapping), явно не показаны на рис. 2.2 (дальнейшее обсуждение этих
вопросов будет продолжено в разделе 2.6).
В данном случае не имеет особого значения, является ли рассматриваемая система
реляционной или какой-нибудь иной. Но было бы полезно вкратце рассказать, как эти
три уровня архитектуры обычно реализуются именно в реляционных системах.
Глава 2. Архитектура системы баз данных
67
Во-первых, концептуальный уровень в такой системе определенно будет реля-
ционным в том смысле, что видимые на этом уровне объекты являются реляци-
онными таблицами, а используемые операторы будут реляционными операто-
рами (в частности, включая операторы выборки строк и столбцов, кратко рас-
смотренные в главе 1).
Во-вторых, каждое внешнее представление, как правило, также будет реляцион-
ным или достаточно близким к нему. Например, объявления записей в PL/I и
COBOL, представленные на рис. 2.2, упрощенно можно считать аналогами объяв-
ления реляционной таблицы в реляционной системе.
Замечание. Между прочим, следует иметь в виду, что термин “внешнее представ-
ление” (часто— просто “представление”) имеет, к сожалению, довольно специ-
фический смысл в реляционном контексте, который не полностью совпадает со
смыслом, приписанным ему в этой главе. Выяснение реляционного смысла данно-
го термина и его обсуждение приводятся в главах 3 и 9.
В-третьих, внутренний уровень не будет реляционным, поскольку объекты на
этом уровне не будут реляционными таблицами (сохраняемыми); наоборот, они
будут объектами такого же типа, как и находящиеся на внутреннем уровне объ-
екты любой другой системы (сохраняемые записи, указатели, индексы, хеширо-
ванные значения и т.п.). В действительности реляционная модель как таковая не
может сказать ничего существенного о внутреннем уровне. Она, как уже от-
мечалось в главе 1, имеет отношение лишь к тому, как воспринимает базу дан-
ных пользователь.
Теперь перейдем к более детальному исследованию трех уровней архитектуры, начи-
ная с внешнего уровня. На рис. 2.3 показаны основные компоненты архитектуры и их
взаимосвязь. На этот рисунок мы будем часто ссылаться в данной главе.
2.3. Внешний уровень
Внешний уровень — это индивидуальный уровень пользователя. Как было сказано в
главе 1, пользователь может быть прикладным программистом или конечным пользова-
телем с любым уровнем профессиональной подготовки. (Особое место среди пользова-
телей занимает администратор базы данных (АБД). В отличие от остальных пользовате-
лей, АБД интересует также концептуальный и внутренний уровни. Об этом еще будет
говориться в следующих двух разделах.)
У каждого пользователя есть свой язык общения.
Для прикладного программиста это либо один из распространенных языков про-
граммирования (например, PL/I, C++ или Java), либо специальный язык рассмат-
риваемой системы. Такие оригинальные языки называют языками четвертого по-
коления на том (не вполне определенном!) основании, что машинный код, язык
ассемблера и такие языки, как PL/I, можно считать языками трех первых
“поколений”, а оригинальные языки модернизированы по сравнению с языками
третьего поколения так же, как языки третьего поколения улучшены по сравнению
с языком ассемблера.
68
Часть I. Основные понятия
Для конечного пользователя это или специальный язык запросов, или язык
специального назначения, который может быть основан на использовании
форм и меню, разработан специально с учетом требований пользователя и ин-
терактивно поддерживаться некоторым оперативным приложением (как ука-
зывалось в главе 1).
Для нашего обсуждения важно, что все эти языки включают подъязык данных,
т.е. подмножество операторов всего языка, связанное только с объектами баз дан-
ных и операциями с ними. Иначе говоря, подъязык данных встроен в базовый
язык, который дополнительно обеспечивает различные не связанные с базами дан-
ных возможности (такие, как локальные (временные) переменные, вычислительные
операции, логические операции и т.д.). Система может поддерживать любое количе-
ство базовых языков и любое количество подъязыков данных. Однако существует
один язык, который поддерживается практически всеми сегодняшними системами.
Это язык SQL, который кратко был представлен в главе 1. Большинство систем по-
зволяет использовать язык SQL и интерактивно, как самостоятельный язык запро-
сов, и посредством внедрения его операторов в другие языки программирования, та-
кие как PL/I и Java. (Подробности приводятся в главе 4.)
Хотя с точки зрения архитектуры удобно различать подъязык данных и включаю-
щий его базовый язык, на практике они могут быть неразличимы настолько, насколько
это имеет отношение к пользователю. Безусловно, с точки зрения пользователя пред-
почтительнее, чтобы они были неразличимы. Если они неразличимы или трудноразли-
чимы, их называют сильно связанными. Если они ясно и легко различаются, говорят,
что эти языки слабо связаны. В то время как некоторые коммерческие системы
(особенно объектные системы; см. главу 24) поддерживают сильную связь, большин-
ство систем, в частности системы SQL, обычно поддерживают лишь слабую связь.
Системы с сильной связью могли бы предоставить пользователю более унифициро-
ванный набор возможностей, но, очевидно, они требуют больше усилий со стороны
системных проектировщиков и разработчиков, которые, вероятно, рассчитывают на
сохранение статус-кво.
В принципе, любой подъязык данных является на самом деле комбинацией по
крайней мере двух подчиненных языков — языка определения данных (data
definition language — DDL), который поддерживает определения или объявления
объектов базы данных, и языка обработки данных (data manipulation language —
DML), который поддерживает операции с такими объектами или их обработку. На-
пример, рассмотрим пользователя языка PL/I (см. рис. 2.2). Подъязык данных этого
пользователя включает определенные средства языка PL/I, применяемые для орга-
низации взаимодействия с СУБД.
Язык определения данных включает некоторые описательные структуры языка
PL/I, необходимые для объявления объектов базы данных. Это сам оператор
DECLARE (DCL), определенные типы данных языка PL/I, а также возможные специ-
альные дополнения для языка PL/I, предназначенные для поддержки новых объек-
тов, которые не поддерживаются существующей версией языка PL/I.
Язык обработки данных состоит из тех выполняемых операторов языка PL/I, ко-
торые передают информацию в базу данных и из нее; опять же, возможно, вклю-
чая новые специальные операторы.
Глава 2. Архитектура системы баз данных
69
Пользователь А1 Пользователь А2
Пользователь Б1
Пользователь Б2 Пользователь БЗ
Рис. 2.3. Детальная схема архитектуры системы баз данных
Замечание. Из соображений точности следует отметить, что современный язык PL/I
на самом деле вообще не включает никаких особых средств для работы с базами данных.
Оператор “языка обработки данных” (оператор CALL), в частности, обычно просто обра-
щается к СУБД (хотя такие обращения могут быть синтаксически скрыты, чтобы сделать
их более дружественными по отношению к пользователю). Разговор о внедрении опера-
торов языка SQL будет продолжен в главе 4.
Вернемся к архитектуре. Как уже отмечалось, отдельного пользователя интересу-
ет лишь некоторая часть всей базы данных. Кроме того, представление пользователя
об этой части будет, безусловно, чем-то абстрактным по сравнению с выбранным
способом физического хранения данных. В соответствии с терминологией
ANSI/SPARC представление отдельного пользователя называется внешним пред-
ставлением. Таким образом, внешнее представление— это содержимое базы дан-
ных, каким его видит определенный пользователь (т.е. для каждого пользователя
внешнее представление и есть та база данных, с которой он работает). Например,
пользователь из отдела кадров может рассматривать базу данных как набор записей
с информацией об отделах плюс набор записей с информацией о служащих и ничего
не знать о записях с информацией о материалах и их поставщиках, с которыми рабо-
тают пользователи в отделе снабжения.
В общем случае внешнее представление состоит из некоторого множества экземп-
ляров каждого из многих типов внешних записей (которые вовсе не обязательно
должны совпадать с хранимыми записями)2. Предоставляемый в распоряжение поль-
зователя подъязык данных всегда определяется в терминах внешних записей. Напри-
мер, операция выборки языка обработки данных осуществляет выборку экземпляров
внешних, а не хранимых записей.
Замечание. Теперь мы видим, что термин “логическая запись”, употреблявшийся в
главе 1, на самом деле относится к внешним записям. Поэтому в дальнейшем мы бу-
дем избегать его использования.
Каждое внешнее представление определяется посредством внешней схемы,
которая, в основном, состоит из определений записей каждого из типов, присутст-
вующих в этом внешнем представлении (см. рис. 2.2). Внешняя схема записывает-
ся с помощью языка определения данных, являющегося подмножеством подъязы-
ка данных пользователя. (Поэтому язык определения данных иногда называют
внешним языком определения данных.) Например, тип внешней записи о работни-
ке можно определить как шестисимвольное поле с номером работника, плюс поле
из пяти десятичных цифр, предназначенное для его зарплаты, и т.д. Кроме того,
может потребоваться определить отображение между внешней и исходной кон-
цептуальной схемами (подробности — в следующем разделе). Это отображение
рассматривается в разделе 2.6.
2 В данном случае предполагается, что вся информация на внешнем уровне представлена в
форме записей. Но некоторые системы позволяют представлять информацию иначе: либо вме-
сто записей, либо совместно с ними. Для использующих такие альтернативные методы систем
все определения и пояснения этого раздела требуют соответствующих изменений. Это замеча-
ние касается также концептуального и внутреннего уровней. Детальное обсуждение подобных
вопросов в этой части книги было бы преждевременным, поэтому мы вернемся к ним позднее, в
главах 13 (в особенности — в разделе "Список литературы ”) и 24.
Глава 2. Архитектура системы баз данных
71
2.4. Концептуальный уровень
Концептуальное представление — это представление всей информации базы
данных в несколько более абстрактной форме (как и в случае внешнего представления)
по сравнению с физическим способом хранения данных. Однако концептуальное пред-
ставление существенно отличается от представления данных каким-либо отдельным
пользователем. Вообще говоря, концептуальное представление — это представление
данных такими, какими они являются на самом деле, а не такими, какими их вынужден
видеть пользователь в рамках, например, определенного языка или используемого ап-
паратного обеспечения.
Концептуальное представление состоит из некоторого множества экземпляров
каждого из существующих типов концептуальных записей. Например, оно может
состоять из набора экземпляров записей, содержащих информацию об отделах, на-
бора экземпляров записей, содержащих информацию о поставщиках, набора экземп-
ляров записей, содержащих информацию о материалах, и т.д. Концептуальная за-
пись вовсе не обязательно должна совпадать с внешней записью, с одной стороны, и
с хранимой записью — с другой.
Концептуальное представление определяется с помощью концептуальной схе-
мы, включающей определения для каждого существующего типа концептуальных
записей (см. рис. 2.2). Концептуальная схема использует другой язык определения
данных— концептуальный. Чтобы добиться независимости данных, нельзя вклю-
чать в определения концептуального языка какие-либо указания о структурах хране-
ния или методах доступа. Определения концептуального языка должны относиться
только к содержанию информации. Это означает, что в концептуальной схеме не
должно быть никакого упоминания о представлении хранимого файла, упорядочен-
ности хранимых записей, индексировании, хеш-адресации, указателях или других
подробностях хранения данных или доступа к ним. Если концептуальная схема дей-
ствительно обеспечивает независимость данных в этом смысле, то внешние схемы,
определенные на основе концептуальной (раздел 2.6), заведомо будут обеспечивать
независимость данных.
Концептуальное представление — это представление всего содержимого базы дан-
ных, а концептуальная схема — это определение такого представления. Однако было
бы ошибкой полагать, что концептуальная схема представляет собой не более чем на-
бор определений, весьма напоминающих простые определения записей в программе на
языке COBOL (или каком-либо другом языке). Определения в концептуальной схеме
могут включать большое количество различных дополнительных аспектов обработки
данных, например таких, как ограничения защиты или требования поддержки целост-
ности данных, упомянутые в главе 1. Более того, некоторые авторитетные специали-
сты предлагают в качестве конечной цели создания концептуальной схемы описание
всего предприятия — не только самих его данных, но и того, как эти данные исполь-
зуются, как они перемещаются внутри предприятия, для чего используются в каждом
конкретном месте, какая проверка и иные типы контроля применяются к ним в каждом
отдельном случае и т.д. [2.3]. Однако необходимо подчеркнуть, что ни одна сегодняш-
няя система реально не поддерживает такого концептуального уровня, который хотя
бы немного приблизился к указанной выше степени развитости. В большинстве суще-
ствующих систем концептуальная схема в действительности представляет собой не-
72
Часть I. Основные понятия
что, что лишь немного больше простого объединения всех независимых внешних схем
с привлечением дополнительных средств безопасности и поддержкой правил обеспе-
чения целостности. Вероятно, со временем системы будут гораздо “интеллектуальнее”
в поддержке концептуального уровня.
2.5. Внутренний уровень
Третьим уровнем архитектуры является внутренний уровень. Внутреннее представ-
ление — это низкоуровневое представление всей базы данных как базы, состоящей из
некоторого множества экземпляров каждого из существующих типов внутренних запи-
сей. Термин “внутренняя запись” относится к терминологии ANSI/SPARC и означает
конструкцию, иначе называемую хранимой записью (в дальнейшем мы будем использо-
вать именно этот термин). Внутреннее представление, так же как внешнее и концепту-
альное, отделено от физического уровня, поскольку в нем не рассматриваются физиче-
ские записи, обычно называемые блоками или страницами, и физические области уст-
ройства хранения, такие как цилиндры и дорожки. Другими словами, внутреннее пред-
ставление предполагает наличие бесконечного линейного адресного пространства. Осо-
бенности методов отображения этого адресного пространства на физические устройства
хранения в значительной степени зависят от используемой операционной системы и по
этой причине не включены в общую архитектуру.
Замечание. Блоки (или страницы) устройства ввода-вывода — это количество дан-
ных, передаваемых из вторичной памяти (памяти накопителя) в основную (оперативную)
память за одну операцию ввода-вывода. Обычно страницы имеют размер 1, 2 или
4 Кбайт (1 Кбайт = 1024 байт).
Внутреннее представление описывается с помощью внутренней схемы, которая
определяет не только различные типы хранимых записей, но также существующие
индексы, способы представления хранимых полей, физическую упорядоченность
хранимых записей и т.д. (И снова за простым примером обратитесь к рис. 2.2.)
Внутренняя схема описывается с использованием еще одного языка определения
данных — внутреннего.
Замечание. В этой книге вместо терминов “внутреннее представление” и
“внутренняя схема” обычно будут использоваться интуитивно более понятные терми-
ны “хранимая структура” или “хранимая база данных” и “определение структуры хра-
нения” соответственно.
В заключение отметим, что в некоторых исключительных ситуациях прикладные
программы, в частности те, которые называются утилитами (о чем подробнее будет
рассказано в разделе 2.11), могут выполнять операции непосредственно на
внутреннем, а не на внешнем уровне. Конечно, использовать такую практику не реко-
мендуется, поскольку она связана с определенным риском с точки зрения безопасно-
сти (правила безопасности игнорируются) и сохранения целостности данных (правила
целостности тоже игнорируются). К тому же такая программа будет зависеть от обра-
батываемых данных. Однако иногда подобный подход может быть единственным спо-
собом реализации требуемой функции или достижения необходимого быстродействия
(так же, как пользователю языка высокого уровня иногда по тем же причинам необхо-
димо прибегнуть к языку ассемблера).
Глава 2. Архитектура системы баз данных
73
2.6. Отображения
Представленная на рис. 2.3 архитектура, кроме элементов самих трех уровней, вклю-
чает определенные отображения: отображение концептуального уровня на внутренний и
несколько отображений внешних уровней на концептуальный.
Отображение “концептуальный-внутренний” устанавливает соответствие между
концептуальным представлением и хранимой базой данных, т.е. описывает, как кон-
цептуальные записи и поля представлены на внутреннем уровне. При изменении
структуры хранимой базы данных (т.е. при внесении изменений в определение
структуры хранения) отображение “концептуальный-внутренний” также изменяется,
причем таким образом, чтобы концептуальная схема осталась неизменной. (Выпол-
нение подобных изменений входит в обязанности администратора базы данных.)
Иначе говоря, чтобы обеспечить независимость данных, результаты внесения любых
изменений в схему хранения не должны быть видны на концептуальном уровне.
Отображение “внешний-концептуальный” определяет соответствие между некоторым
внешним представлением и концептуальным представлением. В целом, различия, ко-
торые могут существовать между этими двумя уровнями, подобны различиям между
концептуальным представлением и хранимой базой данных. Например, данные полей
могут быть разных типов, названия полей и записей могут быть изменены, несколько
концептуальных полей могут быть объединены в одно (виртуальное) внешнее поле и
т.д. В одно и то же время может существовать любое количество внешних представле-
ний, причем одно и то же внешнее представление может принадлежать нескольким
пользователям, а разные внешние представления могут перекрываться.
Замечание. Очевидно, что как отображение “концептуальный-внутренний” является
ключом к физической независимости данных, так и отображения “внешний-
концептуальный” являются ключом к логической независимости данных. Как было по-
казано в главе 1, система обеспечивает физическую независимость данных [2.3], если
пользователи и пользовательские программы обладают иммунитетом к изменениям в фи-
зической структуре хранимой базы данных. Аналогично система обеспечивает логическую
независимость данных [1.4], если пользователи и пользовательские программы обладают
иммунитетом к изменениям в логической структуре базы данных (подразумеваются изме-
нения на концептуальном или “общем логическом” уровне). Этот важный вопрос будет об-
суждаться в главах 3 и 9.
Интересно отметить, что большинство систем позволяет выражать определение одно-
го внешнего представления через другое (по существу, с помощью отображения
“внешний-внешний ”), не требуя обязательного явного определения отображения каждо-
го внешнего представления на концептуальный уровень. Эта возможность очень полезна,
если несколько представлений схожи между собой. В частности, подобная возможность
присутствует во многих реляционных СУБД.
2.7. Администратор базы данных
Как уже отмечалось в главе 1, администратор данных (АД)— это человек, отвечаю-
щий за стратегию и политику принятия решений, связанных с данными предприятия, а
администратор базы данных (АБД) — это человек, обеспечивающий необходимую тех-
74
Часть I. Основные понятия
ническую поддержку с целью реализации принятых решений. Таким образом, АБД отве-
чает за общее управление системой на техническом уровне. Теперь опишем функции
АБД более подробно.
Определение концептуальной схемы
Администратор данных решает, какая именно информация должна храниться в ба-
зе данных, т.е. указывает те типы сущностей, в которых заинтересовано предпри-
ятие, а также определяет диапазон информации об этих сущностях, которую необ-
ходимо записывать. Этот процесс обычно называют логическим (или концепту-
альным') проектированием базы данных. После того как содержимое базы дан-
ных на абстрактном уровне будет определено администратором данных, АБД соз-
дает соответствующую концептуальную схему, используя концептуальный язык
определения данных. Объектная (откомпилированная) форма этой схемы будет
использоваться СУБД для получения ответов на запросы, связанные с доступом к
данным. Исходная (не откомпилированная) форма будет играть роль справочного
документа для пользователей системы.
Замечание. На практике редко все происходит точно по описанной выше схеме.
Иногда сам АД создает концептуальную схему, а иногда АБД занимается логиче-
ским проектированием.
Определение внутренней схемы
Администратор базы данных должен также решить, как данные будут пред-
ставлены в хранимой базе данных. Этот процесс обычно называют физиче-
ским проектированием базы данных3. После завершения физического проек-
тирования АБД создает соответствующие структуры хранения, используя
внутренний язык определения данных (т.е. описывает внутреннюю схему).
Кроме того, он определяет соответствующее отображение между внутренней
и концептуальной схемами. На практике концептуальный и внутренний языки
определения данных (особенно первый) могут включать в себя средства опре-
деления этого отображения, однако две данные функции (создание схемы и
определение отображений) должны быть четко разделены. Как и концепту-
альная схема, внутренняя схема и соответствующее отображение будут суще-
ствовать в исходной и объектной формах.
Взаимодействие с пользователями
В обязанности АБД также входит взаимодействие с пользователями для пре-
доставления им необходимых данных и написания требуемых внешних схем
(или оказания помощи пользователям в их написании) с применением при-
кладного внешнего языка определения данных. (Как уже отмечалось, СУБД
может поддерживать несколько различных языков определения данных.)
Кроме того, необходимо определить отображение между каждой созданной
внешней и концептуальной схемами. На практике внешний язык определения
данных может включать средства определения этого отображения, но, опять
3 Обратите внимание на последовательность: сначала необходимо определить, какие данные
требуются, а затем решить, как эти данные следует представить в памяти. Физическое про-
ектирование всегда должно выполняться после логического проектирования.
Глава 2. Архитектура системы баз данных
75
же, схемы и отображения должны быть четко разделены между собой. Каждая
внешняя схема и соответствующее ей отображение будет существовать в ис-
ходной и объектной формах.
Другие аспекты взаимодействия с пользователями включают консультации по
разработке приложений, обеспечение требуемого технического образования, пре-
доставление помощи в выявлении и устранении возникающих проблем и прочие
виды связанного с системой профессионального обслуживания.
Определение требований защиты и обеспечения целостности данных
Как уже отмечалось, требования защиты и поддержания целостности данных рас-
сматриваются как часть концептуальной схемы. Концептуальный язык определе-
ния данных должен включать в себя средства определения этих требований.
Определение процедур резервного копирования и восстановления
После того как предприятие доверит хранение своих данных системе баз данных, оно
станет критически зависимым от бесперебойного функционирования этой системы. В
случае повреждения какой-либо части базы данных вследствие ошибки человека, отка-
за оборудования или сбоя программ операционной системы очень важно иметь воз-
можность восстановить утраченные данные с минимальной задержкой и с наимень-
шим воздействием на остальную часть системы. В идеале, данные, которые не были
повреждены, совсем не должны затрагиваться. АБД должен разработать и реализовать
подходящую схему восстановления, включающую периодическую выгрузку (или по-
лучение “дампа”) базы данных на устройство резервного копирования и процедуры за-
грузки базы данных с последнего созданного дампа в случае необходимости.
Помимо всего прочего, требование быстрого восстановления поврежденных дан-
ных является одной из тех причин, по которым желательно организовать хранение
данных не в каком-либо одном месте, а распределить их в нескольких отдельных
базах данных. Каждая из таких баз данных будет представлять собой оптимальный
объект выгрузки или перезагрузки. В этой связи отметим, что терабайтные сис-
темы4 (т.е., грубо говоря, коммерческие системы, хранящие более триллиона бай-
тов данных) уже существуют, а в будущем системы будут еще больше. Понятно,
что такие системы очень больших баз данных (VLDB — very large database) тре-
буют тщательного и продуманного администрирования, в особенности если необ-
ходимо обеспечить для пользователей постоянный доступ к базе данных (а часто
именно так и бывает). Однако для простоты рассуждений будем по-прежнему
подразумевать, что мы имеем дело с единственной базой данных.
Управление производительностью и реагирование на изменяющиеся требования
Как отмечалось выше, в главе 1, АБД отвечает за такую организацию системы,
при которой можно получить производительность, оптимальную для всего пред-
приятия в целом, а также за коррекцию работы системы (т.е. ее настройку) в со-
4 1024 байт = 1 Кбайт (килобайт); 1024 Кбайт = 1 Мбайт (мегабайт); 1024 Мбайт =
1 Гбайт (гигабайт); 1024 Гбайт - 1 Тбайт (терабайт); 1024 Тбайт = 1 Пбайт (петабайт);
1024 Пбайт = 1 Ебайт (эксабайт). Отметим, что, поскольку гигабайт равен приблизительно
миллиарду (billion) байтов, вместо сокращения "Мбайт” иногда используют сокращение
“Кбайт ”. Кстати, вопреки распространенному мнению, английское слово gigabyte произносится
с мягким начальным g (“jigabyte ”).
76
Часть I. Основные понятия
ответствии с изменяющимися требованиями. Например, может возникнуть необ-
ходимость в периодической реорганизации хранимой базы данных с целью полу-
чения гарантий того, что производительность системы всегда будет поддержи-
ваться на приемлемом уровне. Как уже упоминалось, любые изменения на уровне
физического хранения данных (внутреннем уровне) должны сопровождаться соот-
ветствующими изменениями в определении его отображения на концептуальный
уровень, что позволит сохранить концептуальную схему неизменной.
Конечно, перечисленное выше— отнюдь не исчерпывающий список обязанностей
АБД, а лишь попытка высказать некоторые соображения об их существе и диапазоне.
2.8. Система управления базой данных
Система управления базой данных (СУБД) представляет собой программное обеспе-
чение, которое управляет всем доступом к базе данных. Концептуально это происходит
следующим образом (см. рис. 2.3).
1. Пользователь выдает запрос на доступ к данным, применяя определенный подъя-
зык данных (обычно это язык SQL).
2. СУБД перехватывает этот запрос и анализирует его.
3. СУБД просматривает внешнюю схему (ее объектную версию) для этого пользователя,
соответствующее отображение “внешний-концептуальный”, концептуальную схему,
отображение “концептуальный-внутренний” и определение структуры хранения.
4. СУБД выполняет необходимые операции в хранимой базе данных.
В качестве примера рассмотрим, как осуществляется выборка экземпляра опреде-
ленной внешней записи. В общем случае поля этой записи будут выбираться из не-
скольких экземпляров концептуальных записей, которые, в свою очередь, будут за-
прашивать поля из нескольких экземпляров хранимых записей. Концептуально СУБД
сначала должна выбрать все требуемые экземпляры хранимых записей, затем постро-
ить требуемые экземпляры концептуальных записей и после этого сформировать эк-
земпляр внешней записи. На каждом этапе могут потребоваться преобразования типов
данных или другие преобразования.
Конечно, описание предыдущего примера весьма упрощено; в частности, в данном
случае предполагается, что весь процесс является интерпретируемым (т.е. анализ
запроса, проверка различных схем и другие процедуры осуществляются непосредствен-
но во время выполнения). Однако интерпретация обычно характеризуется невысокой
производительностью, поскольку на ее выполнение затрачивается много времени. На
практике обычно существует возможность предварительно скомпилировать запрос на
доступ к данным до начала его выполнения; в частности, в современных SQL-системах
применяется именно такой подход (см. аннотации к [4.12] и [4.26] в главе 4).
Теперь рассмотрим функции СУБД немного подробнее. Они обязательно будут
включать поддержку работы компонентов базы данных, показанных на рис. 2.4.
Определение данных
СУБД должна предоставлять средства определения данных (внешних схем, кон-
цептуальной схемы, внутренней схемы, а также всех необходимых отображений) в
виде исходной формы и преобразования этих определений в соответствующую
Глава 2. Архитектура системы баз данных
77
объектную форму. Иначе говоря, СУБД должна включать в себя компоненты
процессора ЯОД или компилятора ЯОД для каждого из поддерживаемых ею
языков определения данных. СУБД должна также понимать синтаксис языка оп-
ределения данных, например, в том смысле, что ей должно быть понятно, что
внешние записи EMPLOYEE включают поле SALARY. Это понимание она должна ис-
пользовать при анализе и выполнении запросов обработки данных (например, та-
ких: “Найти всех служащих с зарплатой, составляющей менее $50 000”).
Реализация
ограничений
защиты и
поддержки
целостности
данных
Рис. 2.4. Основные функции и компоненты типичной СУБД Запросы на ЯМЛ разделя-
ются на планируемые и непланируемые.
78
Часть I. Основные понятия
Обработка данных
СУБД должна уметь обрабатывать запросы пользователя на выборку, изменение или
удаление данных, уже существующих в базе, или на добавление в нее новых данных.
Другими словами, СУБД должна включать в себя компонент процессора ЯМЛ или
компилятора ЯМЛ, обеспечивающего поддержку языка манипулирования данными.
а) Планируемый запрос — это запрос, необходимость выполнения которого была
предусмотрена заранее. Администратор базы данных, возможно, должен будет
построить физический проект базы данных таким образом, чтобы гарантировать
достаточное быстродействие выполнения подобных запросов.
б) Непланируемый запрос — это, наоборот, некоторый произвольный запрос, не-
обходимость выполнения которого не была предусмотрена заранее и возникла по
какой-то особой причине. Физический проект базы данных может подходить, а
может и не подходить для выполнения конкретного произвольного запроса.
Согласно терминологии, введенной в разделе 1.3, планируемые запросы более ха-
рактерны для операционных приложений, а непланируемые— для приложений
поддержки принятия решений. Более того, планируемые запросы обычно выдают-
ся из написанных заранее приложений, а непланируемые запросы по определению
вводятся интерактивно, с помощью процессора языка запросов.
Замечание. В главе 1 уже отмечалось, что на самом деле процессор языка запро-
сов — это встроенное интерактивное приложение, а не какая-то часть самой
СУБД. Мы показали этот компонент на рис. 2.4 исключительно из соображений
полноты общей картины.
Оптимизация и выполнение
Запросы ЯМД, планируемые или непланируемые, должны быть обработаны таким
компонентом, как оптимизатор, назначение которого состоит в поиске достаточ-
но эффективного способа выполнения каждого из запросов. Оптимизация подроб-
но обсуждается в главе 17. Оптимизированные запросы затем выполняются под
управлением менеджера времени выполнения (run-time manager).
Замечание. На практике менеджер времени выполнения, возможно, будет использо-
вать что-то подобное менеджеру доступа к файлам для получения доступа к храни-
мым данным. Менеджеры файлов кратко обсуждаются в конце этого раздела.
Защита и сохранение целостности данных
СУБД должна контролировать пользовательские запросы и пресекать любые попыт-
ки нарушения ограничений защиты и сохранения целостности данных, определен-
ные АБД (см. предыдущий раздел). Этот контроль может осуществляться во время
компиляции, во время выполнения или на обоих этих этапах обработки запроса.
Восстановление данных и поддержка параллельности
СУБД или другой связанный с ней программный компонент, обычно называе-
мый менеджером транзакций или диспетчером выполнения транзакций,
должен обеспечивать необходимый контроль над восстановлением данных и
управлением параллельностью обработки. Детали реализации этих функций
системы выходят за рамки данной главы — подробное обсуждение указанных
тем можно найти в части IV.
Глава 2. Архитектура системы баз данных
79
Замечание. Менеджер транзакций не показан на рис. 2.4, поскольку обычно он не
является частью самой СУБД.
Словарь данных
СУБД должна поддерживать функцию ведения словаря данных. Сам словарь дан-
ных вполне можно считать самостоятельной базой данных (но не пользовательской,
а системной). Словарь содержит “данные о данных” (иногда называемые метадан-
ными или дескрипторами), т.е. определения других объектов системы, а не просто
обычные данные. В частности, в словаре данных будут сохранены исходные и объ-
ектные формы всех существующих схем (внешних, концептуальной и т.д.) и ото-
бражений, а также установленные ограничения защиты и сохранения целостности
данных. Расширенный словарь может также включать большой объем дополнитель-
ной информации, например, показывающей, какие из программ используют ту или
иную часть базы данных, какие отчеты требуются каждому из пользователей и т.д.
Словарь может быть (а фактически просто должен быть) интегрирован в определяе-
мую им базу данных, а значит, должен содержать описание самого себя. Конечно,
должна существовать возможность обращения к словарю с запросами, как к любой
другой базе данных, например, для того, чтобы узнать, какие программы и/или поль-
зователи будут затронуты при предполагаемом внесении изменения в систему.
Дальнейшее обсуждение этого вопроса приводится в главе 3.
Замечание. Здесь мы коснулись области, в которой может возникнуть путаница из-за
используемой терминологии. То, что мы называем словарем, иногда называют ди-
ректорием или каталогом, потому что директории и каталоги в некотором смысле
хуже настоящего словаря, а термин “словарь” зарезервирован для специального
(важного) вида инструментов разработки приложений. Также встречаются и другие
термины — репозиторий данных (глава 13) и энциклопедия данных.
Производительность
Очевидно, что СУБД должна выполнять все указанные функции с максимально
возможной эффективностью.
Подводя итог сказанному, можно сделать вывод, что, в целом, назначением СУБД яв-
ляется предоставление пользовательского интерфейса с системой баз данных. Пользо-
вательский интерфейс может быть определен как существующий в системе ограничи-
тельный уровень, ниже которого для пользователя все остается невидимым. Следова-
тельно, по определению пользовательский интерфейс находится на внешнем уровне. Тем
не менее в главе 8 мы увидим, что иногда внешнее представление едва ли значительно
отличается от соответствующей ему части основного концептуального представления
(по крайней мере, в современных коммерческих SQL-продуктах).
В заключение вкратце сопоставим описанную здесь типовую СУБД с системой управ-
ления файлами (также для краткости — с менеджером файлов или файловым сервером). В
своей основе система управления файлами является компонентом базовой операционной
системы, предназначенной для управления хранимыми файлами. Проще говоря, она распо-
ложена “ближе к диску”, чем СУБД. (В действительности СУБД обычно строится на базе
некоторого варианта файлового сервера.) Таким образом, пользователь системы управле-
ния файлами может создавать и уничтожать хранимые файлы, а также выполнять простые
операции выборки и обновления хранимых записей в созданных им файлах. Однако в срав-
нении с СУБД системе управления файлами свойственны следующие недостатки.
80
Часть I. Основные понятия
Система управления файлами ничего не знает о внутренней структуре хранимых
записей и, следовательно, не способна обрабатывать запросы, предполагающие
знание этой структуры.
Как правило, эти системы предоставляют слабую поддержку ограничений защиты
и поддержки целостности данных или же не предоставляют ее вовсе.
Как правило, эти системы предоставляют недостаточную поддержку управления
восстановлением данных и параллельным доступом к ним или же не предостав-
ляют ее вовсе.
На уровне менеджера файлов не существует концепции настоящего словаря данных.
Как правило, эти системы обеспечивают независимость данных гораздо хуже,
чем СУБД.
Как правило, отдельные файлы не “интегрированы” или не “разделяемы” в том
смысле, который вкладывается в эти понятия применительно к базам данных.
(Обычно они являются собственными файлами пользователя или приложения.)
2.9. Система управления передачей данных
В этом разделе вкратце рассматривается передача данных. Запросы к базе данных от
конечных пользователей в действительности передаются от рабочей станции пользовате-
ля (которая может быть физически удалена от самой системы баз данных) к некоторому
интерактивному приложению (встроенному или нет), а от него — к СУБД в форме ком-
муникационных сообщений. Более того, ответы пользователю (от СУБД и оперативного
приложения к станции пользователя) также передаются в форме подобных сообщений.
Передача таких сообщений происходит под управлением другого программного компо-
нента — менеджера передачи данных.
Менеджер передачи данных не является частью СУБД; он представляет собой авто-
номную систему со своими правами. Однако, поскольку очевидно, что от менеджера пе-
редачи данных и СУБД требуется согласованная совместная работа, они иногда рассмат-
риваются как равноправные партнеры в компоненте более высокого уровня, называемо-
го системой базы данных и передачи данных. В этой системе СУБД отвечает за рабо-
ту с базой данных, а менеджер передачи данных обрабатывает все сообщения, посту-
пающие в СУБД и из нее, а точнее говоря, в то приложение, которое использует СУБД,
и из него. Однако в этой книге об обработке сообщений нам осталось сказать относи-
тельно немного (поскольку такая обширная тема вполне заслуживает самостоятельного
обсуждения). В разделе 2.12 кратко рассматриваются вопросы передачи данных между
отдельными системами (т.е. между отдельными машинами в сети передачи данных, по-
добной Internet), но это уже совсем другая тема.
2.10. Архитектура “клиент/сервер”
В предыдущих разделах этой главы подробно обсуждалась так называемая архитек-
тура ANSI/SPARC для систем баз данных. Ее упрощенная схема приведена на рис. 2.3. В
настоящем разделе мы посмотрим на базу данных с несколько иной точки зрения. Общее
назначение систем баз данных— это, конечно, поддержка разработки и выполнения
приложений баз данных. Поэтому на высоком уровне систему баз данных можно рас-
Глава 2. Архитектура системы баз данных
81
сматривать как систему с очень простой структурой, состоящей из двух частей — серве-
ра {внутреннего компонента или машины базы данных} и набора клиентов (внешнего
компонента или внешнего интерфейса}, как показано на рис. 2.5.
Сервер — это сама СУБД. Он поддерживает все ос-
новные функции СУБД, которые обсуждались в
разделе 2.8, а именно: определение данных, обра-
ботку данных, защиту данных, поддержание цело-
стности данных и т.д. В частности, он предоставля-
ет полную поддержку внешнего, концептуального и
внутреннего уровней, обсуждавшихся в разде-
лах 2.3-2.6. Поэтому “сервер” в этом контексте —
это просто другое название для СУБД.
Клиенты — это различные приложения, которые вы-
полняются поверх СУБД: как приложения, написан-
ные пользователями, так и встроенные приложения,
предоставляемые поставщиками СУБД или некото-
рыми сторонними поставщиками программного
обеспечения. Конечно, с точки зрения сервера разни-
цы между встроенными приложениями и приложе-
ниями, написанными пользователем, нет: все они ис-
пользуют один и тот же интерфейс сервера, а имен-
но — интерфейс внешнего уровня, который уже рас-
сматривался в разделе 2.3.
Рис. 2.5. Архитектура
“клиент/сервер ”
Замечание. Некоторые специальные “служебные” приложения могут оказаться ис-
ключениями. Как упоминалось выше, они иногда работают непосредственно на
внутреннем уровне системы (см. раздел 2.5). Подобные утилиты правильнее отно-
сить к встроенным компонентам СУБД, а не к приложениям в обычном смысле. В
следующем разделе утилиты обсуждаются более подробно.
Приложения, в свою очередь, делятся на несколько четко определенных категорий.
Приложения, написанные пользователями. В основном, это обычные прикладные
программы, чаще всего написанные либо на популярном языке программирова-
ния, подобном С или COBOL, либо на специализированных языках четвертого по-
коления, хотя в обоих случаях эти языки должны как-то связываться с соответст-
вующим подъязыком данных (см. раздел 2.3).
Приложения, предоставляемые поставщиками (часто называемые инструмен-
тальными средствами). В целом, назначение таких средств— содействовать
процессу создания и выполнения других приложений, т.е. приложений, которые
разрабатываются специально для решения некоторой специфической задачи. Час-
то эти создаваемые приложения могут выглядеть вовсе не так, как приложения в
общепринятом смысле. И это понятно, поскольку само назначение инструмен-
тальных средств состоит в предоставлении пользователям, особенно конечным,
возможности создавать приложения без написания традиционных программ. На-
пример, одно из предоставляемых поставщиком СУБД инструментальных средств
может быть генератором отчетов, с помощью которого конечный пользователь
82
Часть I. Основные понятия
сможет получить отформатированный отчет, выполнив обычный запрос к
системе. Каждый такой запрос является, по существу, ни чем иным, как неболь-
шим специальным приложением, написанным на языке очень высокого уровня (со
специфическим назначением), а именно — на языке выдачи отчетов.
Поставляемые инструментальные средства, в свою очередь, делятся на несколько
самостоятельных классов.
а) Процессоры языков запросов.
б) Генераторы отчетов.
в) Графические бизнес-подсистемы.
г) Электронные таблицы.
д) Процессоры обычных языков.
е) Статистические пакеты.
ж) Средства управления копированием или средства извлечения данных.
з) Генераторы приложений (включая процессоры языков четвертого поколения).
и) Другие средства разработки приложений, включая CASE-инструменты (CASE
или Computer-Aided Software Engineering— автоматизация разработки про-
граммного обеспечения), и т.д.
Подробное обсуждение этих приложений выходит за рамки данной книги, однако
следует отметить, что (как утверждалось ранее) главная задача системы баз дан-
ных — поддержка создания и выполнения приложений. Поэтому качество имею-
щихся клиентских инструментальных средств должно быть главным учитываемым
фактором при выборе СУБД, наиболее подходящей для конкретного заказчика.
Другими словами, СУБД сама по себе — не единственный и необязательно важ-
нейший фактор, который нужно учитывать в этом случае.
Завершим настоящий раздел ссылкой на последующий материал. Так как система в
целом может быть четко разделена на две части (сервер и клиенты), появляется возмож-
ность работы этих двух частей на разных машинах. Иначе говоря, существует возмож-
ность организации распределенной обработки. Распределенная обработка предпола-
гает, что отдельные машины можно соединить какой-нибудь коммуникационной сетью
таким способом, что выполнение одной задачи обработки данных можно будет распре-
делить на несколько машин этой сети. Как показала практика, эта возможность настоль-
ко заманчива по различным соображениям (главным образом, экономическим), что тер-
мин “клиент/сервер” стал применяться почти исключительно в тех случаях, когда клиен-
ты и сервер действительно находятся на разных машинах. Более подробно распределен-
ная обработка данных рассматривается ниже, в разделе 2.12.
2.11. Утилиты
Утилиты — это программы, разработанные для АБД и используемые им при реше-
нии различных административных задач. Как упоминалось выше, некоторые утилиты
выполняются на внешнем уровне системы и потому представляют собой не что иное,
как приложения специального назначения. Одни из них могут быть созданы даже не
поставщиком данной СУБД, а определенными сторонними разработчиками программ-
Глава 2. Архитектура системы баз данных
83
ного обеспечения. Однако другие утилиты выполняются непосредственно на внутрен-
нем уровне (т.е. действительно являются частью сервера) и поэтому должны предос-
тавляться поставщиками СУБД.
Ниже приводится несколько примеров утилит различных типов, которые часто при-
меняются на практике.
Инструменты загрузки, применяемые для создания исходной версии базы данных
из одного или более файлов операционной системы.
Инструменты выгрузки-перезагрузки, применяемые для выгрузки базы данных
или ее части, создания резервных копий хранимых данных и восстановления базы
данных из этих копий. (Безусловно, утилита перезагрузки, по существу, идентична
упомянутой выше утилите загрузки.)
Инструменты реорганизации, применяемые для перераспределения данных
в хранимой базе данных, которое выполняется по различным причинам
(обычно с целью повышения производительности). В частности, это может
быть процедура группирования данных на диске некоторым специальным
образом или освобождение пространства, занятого ранее данными, которые
больше не используются.
Статистические инструменты, применяемые для вычисления различных стати-
стических показателей и показателей производительности, таких как сведения о
размерах файлов или значениях данных, счетчики операций ввода-вывода и т.п.
Инструменты анализа, применяемые для анализа упомянутой выше статистиче-
ской информации.
Этот список охватывает лишь небольшую часть функциональных возможностей,
обычно предоставляемых доступными утилитами. Помимо перечисленных, существует
множество других функций.
2.12. Распределенная обработка
Как мы определили в разделе 2.10, термин “распределенная обработка” означает, что
разные машины можно соединить в коммуникационную сеть (например, Internet) для ор-
ганизации совместного решения одной задачи обработки данных на нескольких машинах
сети. (Термин “параллельная обработка” используется практически для того же, но в
“параллельных” системах взаимодействующие машины с физической точки зрения рас-
положены рядом, тогда как для распределенной системы это вовсе необязательно и от-
дельные машины могут быть достаточно удалены географически.) Взаимодействие меж-
ду различными машинами осуществляется с помощью специального программного
обеспечения, предназначенного для управления сетью. Оно может быть некоторым рас-
ширением менеджера передачи данных (см. раздел 2.9), но чаще всего является отдель-
ным программным компонентом.
Распределенная обработка может быть самой разнообразной и осуществляться на
разных уровнях. Как отмечалось в разделе 2.10, один из простейших случаев, представ-
ленный на рис. 2.6, — это случай, когда сервер СУБД запускается на одной машине, а
клиентское приложение — на другой.
84
Часть I. Основные понятия
Рис. 2.6. Вариант распре-
деленной обработки, в
котором клиент и сер-
вер запускаются на
разных машинах
Как уже отмечалось в конце раздела 2.10, термин “клиент/сервер”, несмотря на то что
он, строго говоря, является чисто архитектурным, фактически стал синонимом изобра-
женной на рис. 2.6 структуры, в соответствии с которой клиент и сервер запускаются на
разных машинах. И действительно, существует множество
аргументов в пользу подобной схемы.
Главный аргумент связан с возможностью организа-
ции параллельной обработки. В этом случае для ре-
шения общей задачи применяется сразу несколько
процессоров, поскольку работа сервера (базы данных)
и клиента (приложения) осуществляется параллельно.
В результате показатели времени реакции системы на
запрос и ее производительности должны улучшиться.
Кроме того, машина сервера может быть изготовле-
на по специальному заказу и специально приспособ-
лена для работы с СУБД (“машина базы данных”).
Такое решение позволяет дополнительно повысить
производительность СУБД.
Аналогично машина клиента может представлять со-
бой персональную рабочую станцию, максимально
приспособленную к потребностям конкретного ко-
нечного пользователя, что позволит предоставить ему
наиболее удобный интерфейс и гарантировать высо-
кий уровень готовности, быструю реакцию системы и
другие дополнительные удобства при использовании.
К одной и той же машине сервера могут иметь
доступ несколько разных машин клиентов (что
чаще всего и имеет место). Поэтому одна база
данных может совместно использоваться не-
сколькими различными клиентскими системами,
как показано на рис. 2.7.
К сказанному выше можно добавить, что работа сервера и клиента на отдельных
машинах отвечает принципам работы многих предприятий. Вполне типичный способ
функционирования отдельных предприятий (например, банков) заключается в исполь-
зовании многих компьютеров, причем данные для одной части предприятия сохраня-
ются на одном компьютере, а данные для другой части — на другом. Несомненно, что
пользователям одного компьютера, пусть лишь иногда, обязательно потребуется дос-
туп к данным, хранящимся на другом компьютере. Следуя примеру банка, можно с
высокой степенью вероятности утверждать, что пользователям одного отделения бан-
ка иногда потребуется доступ к данным, сохраняемым в другом его отделении. Из это-
го можно сделать вывод, что на машинах клиентов могут сохраняться их данные, а
машина сервера может иметь собственные приложения. Поэтому, вообще говоря, каж-
дая машина будет выступать в роли сервера для одних пользователей и в роли клиента
для других, образуя систему, представленную на рис. 2.8. Иными словами, в этом слу-
чае каждая машина будет поддерживать полную систему баз данных в смысле, кото-
рый вкладывался в это понятие в предыдущих разделах главы.
Глава 2. Архитектура системы баз данных
85
Машины
клиентов
Рис. 2.7. Система с одним сервером и несколькими клиентами
Отметим последнее преимущество, которое состоит в том, что отдельная машина
клиента может иметь доступ к нескольким машинам серверов (случай, противополож-
ный показанному на рис. 2.7). Это полезная возможность, поскольку, как уже упомина-
лось, предприятие обычно выполняет обработку данных таким образом, что полный на-
бор всех данных сохраняется не на одной машине, а распределяется на нескольких раз-
личных машинах, причем в приложениях иногда необходим доступ к данным сразу не-
скольких машин. Такой доступ предоставляется, в основном, двумя способами.
Клиент может получать доступ к любому количеству серверов, но лишь к одному
из них в каждый момент времени (т.е. каждый запрос к базе данных может быть
направлен только к одному серверу). В такой системе невозможно за один запрос
получить комбинированные данные от двух или более серверов. Кроме того, поль-
зователь в такой системе должен знать, на какой именно машине содержится кон-
кретная часть данных.
Клиент может получать доступ к любому количеству серверов одновременно (т.е.
за один запрос можно получить комбинированные данные двух или более серве-
ров). В этом случае серверы рассматриваются клиентом как единый сервер (с ло-
гической точки зрения) и пользователь может не знать, на какой именно машине
содержится та или иная часть данных.
Второй случай — это пример системы, которую обычно называют распределенной
системой баз данных. Тема распределенных баз данных сама по себе весьма
обширна. Подводя сказанное к некоторому логическому завершению, отметим сле-
86
Часть I. Основные понятия
дующее: полная поддержка распределенных баз данных означает, что отдельное при-
ложение может “прозрачно” обрабатывать данные, распределенные между множест-
вом различных баз данных, управление которыми осуществляют разные СУБД, рабо-
тающие на соединенных коммуникационными сетями машинах разных типов с раз-
личными операционными системами. Здесь понятие “прозрачно” означает, что прило-
жение выполняет обработку данных с логической точки зрения так, как будто управ-
ление данными полностью осуществляется одной СУБД, работающей на единственной
машине. Предоставление такой возможности может показаться невероятно трудной
задачей, но весьма желанной с практической точки зрения. Производители СУБД на-
пряженно работают, чтобы сделать подобные системы реальностью. Подробнее рас-
пределенные базы данных рассматриваются в главе 20.
Рис. 2.8. Система, в которой каждая машина одновременно яв-
ляется и клиентом, и сервером
Глава 2. Архитектура системы баз данных
87
2.13. Резюме
В этой главе системы баз данных рассматривались с точки зрения их общей архитекту-
ры. Здесь была описана архитектура ANSI/SPARC, которая делит систему баз данных на
три уровня следующим образом: внутренний уровень, наиболее близкий к физическому
хранению (т.е. рассматривающий способ, с помощью которого данные сохраняются физи-
чески); внешний уровень, наиболее близкий к пользователям (т.е. имеющий отношение к
способу представления данных для отдельных пользователей); концептуальный уровень,
который является промежуточным между двумя предыдущими (он предоставляет обоб-
щенное представление данных). Восприятие данных на каждом из уровней описывается с
помощью схемы (или нескольких схем в случае внешнего уровня). Отображения описы-
вают соответствие между заданной внешней схемой и концептуальной схемой, а также ме-
жду концептуальной и внутренней схемами. Эти отображения служат основой для соответ-
ственно логической и физической независимости данных.
Пользователи, т.е. конечные пользователи и прикладные программисты, работающие на
внешнем уровне, взаимодействуют с данными с помощью подъязыка данных, который
включает по крайней мере два компонента: язык определения данных и язык манипу-
лирования данными. Подъязык данных встроен в базовый язык программирования.
Замечание. Границы, разделяющие базовый язык и подъязык данных, а также язык
определения данных и язык обработки данных по своей природе, в основном, умозри-
тельны. В идеале, они должны быть прозрачны для пользователя.
Здесь также детально рассматривались функции администратора базы данных и
СУБД. Кроме всего прочего, АБД несет ответственность за создание внутренней схемы
(физическое проектирование базы данных). В противоположность этому за создание
концептуальной схемы (логическое или концептуальное проектирование базы данных)
несет ответственность администратор данных. В функции СУБД входит также реализа-
ция запросов пользователей, написанных на языке определения данных или языке обра-
ботки данных. Функцией СУБД является и поддержка словаря данных.
Системы баз данных удобно рассматривать как простую структуру, состоящую из
сервера (собственно СУБД) и набора клиентов (приложений). Клиент и сервер могут
выполняться и зачастую выполняются на отдельных машинах, обеспечивая таким обра-
зом простейший вариант распределенной обработки данных. В общем случае каждый
сервер может обслуживать много клиентов, а каждый клиент может работать со многими
серверами. Если система обеспечивает полную прозрачность доступа (т.е. клиент рабо-
тает так, как будто он имеет дело с одним сервером на единственной машине, невзирая
на реальное физическое положение дел), то в таком случае мы имеем настоящую рас-
пределенную систему баз данных.
Упражнения
2.1. Начертите схему архитектуры системы баз данных, представленной в этой главе
(архитектуры ANSI/SPARC).
2.2. Дайте определения следующим терминам.
базовый язык отображение “концептуальный-
внутренний”
88
Часть I Основные понятая
внешний интерфейс
внешний язык определения, схема,
представление
внутренний язык определения, схема,
представление
выгрузка-перезагрузка
загрузка данных
клиент
концептуальный язык определения,
схема, представление
логический проект базы данных
машина базы данных
менеджер передачи данных
непланируемый запрос
определение структуры памяти
отображение “внешний-
концептуальный”
планируемый запрос
подъязык данных
пользовательский интерфейс
распределенная база данных
распределенная обработка
реорганизация
сервер
система базы данных и передачи дан-
ных
словарь данных
утилита
физический проект базы данных
язык манипулирования данными
язык определения данных
2.3. Опишите последовательность шагов, применяемых при выборке определенного эк-
земпляра внешней записи.
2.4. Перечислите главные функции, выполняемые СУБД.
2.5. Укажите различия между логической и физической независимостью от данных.
2.6. Как вы понимаете термин метаданные?
2.7. Перечислите главные функции, выполняемые АБД.
2.8. Укажите различия между СУБД и системой управления файлами.
2.9. Приведите несколько примеров инструментальных средств, предоставляемых раз-
личными поставщиками.
2.10. Приведите несколько примеров утилит базы данных.
2.11. Проанализируйте любую доступную вам систему баз данных. Попытайтесь пред-
ставить ее в соответствии с архитектурой ANSI/SPARC, как описано в этой
главе. Полностью ли она поддерживает три уровня архитектуры? Как определе-
ны отображения между уровнями? С чем схожи различные языки определения
данных (внешний, концептуальный и внутренний)? Какой подъязык данных под-
держивает система? Какой язык является базовым? Кто выполняет функции
АБД? Имеются ли какие-нибудь средства организации защиты и поддержания
целостности данных? Существует ли в системе словарь? Описывает ли он сам
себя? Какие приложения, предоставляемые поставщиками, поддерживает систе-
ма? Какие утилиты входят в состав системы? Есть ли в системе отдельный ком-
понент менеджера передачи данных? Имеются ли какие-либо возможности рас-
пределенной обработки?
Глава 2. Архитектура системы баз данных
89
Список литературы
Хотя некоторые из перечисленных ниже изданий были выпущены давно, в них
можно найти полезную информацию, которая касается понятий, представленных в
этой главе.
2.1. ANSI/X3/SPARC Study Group on Data Base Management Systems. Interim Report //
FDT (ACM SIGMOD bulletin). — 1975. — 7, № 2.
2.2. Dionysios C. Tsichritzis D.C. and Klug A. (eds). The ANSI/X3/SPARC Framework:
Report of the Study Group on Data Base Management Systems // Information
Systems. — 1978. — 3.
Эти два документа [2.1], [2.2] — соответственно предварительный и окончательный
отчеты группы ANSI/X3/SPARC Study Group. Группа ANSI/X3/SPARC (полное на-
звание— Study Group on Data Base Management Systems) была организована в
1972 году комитетом Standards Planning and Requirements Committee (SPARC) инсти-
тута American National Standards Institute on Computers and Information Processing
(ANSI/X3). В задачи группы входило определение того, нуждаются ли какие-либо
области технологии баз данных в стандартизации (если нуждаются, то какие именно),
и выработка набора рекомендуемых действий в каждой из этих областей. В процессе
работы над поставленными задачами группа пришла к выводу, что единственный
подходящий объект стандартизации — интерфейсы, и в соответствии с этим опреде-
лила общую архитектуру, или фундамент, системы баз данных, а также указала на
важную роль подобных интерфейсов. В окончательном отчете представлено подроб-
ное описание архитектуры и некоторых из 42 (!) указанных интерфейсов. Предвари-
тельный отчет — это более ранний документ, который представляет определенный
интерес, так как в нем отдельные вопросы рассмотрены более детально.
2.3. Van Griethuysen J.J. (ed.). Concepts and Terminology for the Conceptual Schema and
the Information Base // International Organization for Standardization (ISO) Technical
Report ISO/TR 9007. — July, 1987.
Этот документ представляет собой отчет рабочей группы Международной органи-
зации по стандартизации (International Standard Organization — ISO), в который
включено “определение понятий для языков концептуальных схем”. В отчете ра-
бочей группы предложено три альтернативных подхода (точнее, три группы под-
ходов) к формализации концептуальной схемы. Каждый из подходов был приме-
нен к стандартному примеру, связанному с деятельностью гипотетического управ-
ления регистрацией машин. Три группы — это подходы “сущность-атрибут-
связь”, подходы “бинарных связей” и подходы “интерпретируемой предикатной
логики”. В отчете обсуждаются фундаментальные понятия, лежащие в основе по-
нятия концептуальной схемы, а также излагаются принципы реализации системы,
которая должным образом поддерживает концептуальную схему. Это достаточно
сложный, однако очень важный документ для всех, кто серьезно интересуется кон-
цептуальным уровнем системы.
2.4. Kent W. Data and Reality.— Amsterdam, Netherlands: North-Holland; New York,
N.Y.: Elsevier Science, 1978.
Искусственное и немного раздражающее описание природы информации, в част-
ности концептуальной схемы. “Эта книга представляет философию, по которой
жизнь и действительность являются, в сущности, аморфными, беспорядочными,
90
Часть I. Основные понятия
противоречивыми, непоследовательными, нерациональными и нерепрезентатив-
ными” (цитата из последней главы). Книгу можно рассматривать как краткое руко-
водство по решению реальных проблем, с которыми трудно справиться из-за су-
ществующего формализма в базах данных, в частности из-за формализма в струк-
турах, подобных записям, используемым в реляционном подходе. Рекомендуется
ознакомиться.
2.5. Odysseas G. Tsatalos, Marvin Н. Solomon, and Yannis E. loannidis. The GMAP: A
Versatile Tool for Phisical Data Independence. Proc. 20th Int. Conf. On Very Large Data
Bases. — Santiago, Chile. — September, 1994.
Сокращение GMAP означает обобщенный многоуровневый путь доступа
(Generalized Multi-Level Access Path). Авторы статьи справедливо отмечают, что
современные продукты баз данных “вынуждают пользователей составлять запросы
в терминах логической схемы, которая непосредственно связана с физическими
структурами” и поэтому усиливают зависимость от физических данных. В этой
статье предлагается язык отображения “концептуальный-внутренний” (по терми-
нологии данной главы), который можно использовать для значительно большего
количества видов отображений, чем обычно обеспечивается в современных про-
дуктах. Предоставляются конкретная “логическая схема” и язык, основанный на
реляционной алгебре (см. главу 6), и, следовательно, описательный, а не проце-
дурный по своей природе, что позволяет описать множество физических схем, ко-
торые формально образуются из такой логической схемы. Кроме всего прочего,
подобные физические схемы могут включать вертикальное и горизонтальное раз-
деления (глава 20), произвольное количество путей физического доступа, группи-
рование и контроль избыточности.
В статье также приводится алгоритм преобразования пользовательских операций
над логической схемой в эквивалентные операции над физической схемой. Прото-
тип реализации показывает, что АБД может настроить физическую схему, чтобы
“достичь значительно более высокой производительности по сравнению с той, ко-
торой можно достичь обычными методами”.
Глава 2. Архитектура системы баз данных
91
Глава 3
Введение в реляционные
базы данных
ЗЛ. Введение
Как отмечалось в главе 1, в этой книге основное внимание сконцентрировано на ре-
ляционных системах. В части II подробно описаны теоретические основы таких систем,
а точнее — реляционная модель данных. Эта глава является лишь предварительным и
весьма неформальным введением в материал, подробно изложенный в части II (и в неко-
торой степени в материал последующих глав), которое послужит основой для лучшего
понимания последующих частей книги. Большинство затронутых здесь тем рассматрива-
ется в дальнейшем более формально и значительно детальнее.
3.2. Реляционная модель
Как уже неоднократно отмечалось, реляционные системы базируются на формальных
основах, или теории, которая называется реляционной моделью данных. Интуитивно понят-
но, что, кроме всего прочего, в такой системе выполняются как минимум три условия.
Структурный аспект. Данные в базе воспринимаются пользователем, как таблицы (и
никак иначе).
Аспект целостности. Эти таблицы удовлетворяют определенным условиям целостно-
сти (что мы еще обсудим в конце раздела).
Аспект обработки. В распоряжении пользователя имеются операторы манипулирова-
ния данными (например, выборки информации), которые генерируют новые таблицы на
основании уже имеющихся и среди которых есть по крайней мере операторы выборки
(restrict), проекции (project) и объединения (join).
На рис. 3.1 показан простой пример реляционной базы данных отделов (таблица DEPT) и
служащих (таблица ЕМР). Как видите, эта база данных действительно “воспринимается, как
набор таблиц” (мы полагаем, что смысл этих таблиц не требует пояснений).
На рис. 3.2 показаны некоторые примеры операций SELECT, PROJECT и JOIN для этой
базы данных. Ниже приведены (очень нестрогие!) определения этих операций.
Операция выборки SELECT (или RESTRICT) предназначена для извлечения опре-
деленных строк из таблицы.
Операция проекции PROJECT предназначена для извлечения определенных
столбцов из таблицы.
Операция объединения JOIN предназначена для соединения двух таблиц на основе
общих значений в общих столбцах.
92
Часть I. Основные понятия
DEPT
DEPT# DNAME BUDGET
D1 Marketing 10M
D2 Development 12M
D3 Research 5M
EMP
EMP# ENAME DEPT# SALARY
El Lopez DI 40K
E2 Cheng DI 42K
E3 Finzi D2 30K
E4 Saito D2 35K
Рис. 3.1. База данных отделов и служащих (значения взяты для примера)
SELECT (RESTRICT): Результат: DEPT# DNAME BUDGET
Выборка строк из DEPT, где BUDGET > 8M DI Marketing 10M
D2 Development 12M
PROJECT: Результат: DEPT# BUDGET
Извлечение столбцов DEPT#, BUDGET DI D2 D3 10M 12M 5M
JOIN:
Соединение DEPT и ЕМР на основе столбца DEPT#
Результат: DEPT# DNAME BUDGET EMP# ENAME SALARY
DI Marketing 10M El Lopez 40K
DI Marketing 10M E2 Cheng 42K
D2 Development 12M E3 Finzi 30K
D2 Development 12M E4 Saito 35K
Рис. 3.2. Примеры выполнения операций SELECT, PROJECT и JOIN
Из трех приведенных здесь примеров в комментариях, по-видимому, нуждается толь-
ко операция JOIN. Прежде всего, обратите внимание на то, что в таблицах DEPT и ЕМР
есть общий столбец DEPT#, а следовательно, для этих таблиц можно выполнить операцию
соединения на основе общих значений в этом столбце.
При выполнении данной операции строка таблицы DEPT соединяется со строкой таб-
лицы ЕМР и образуется более длинная строка, но подобное происходит тогда и только то-
гда, когда у этих двух строк одинаковое значение поля DEPT#. Например, можно соеди-
нить в результирующую строку следующие строки таблиц DEPT и ЕМР (названия столбцов
приведены для наглядности).
Глава 3. Введение в реляционные базы данных
93
DEPT# DNAME BUDGET
D1 Marketing ЮМ
EMP# ENAME DEPT# SALARY
El Lopez DI 40K
Это возможно, так как в общем столбце у данных строк одно и то же значение ' D1'.
Вот эта результирующая строка.
DEPT# DNAME BUDGET EMP# ENAME SALARY
DI Marketing 10M El Lopez 40K
Общий результат состоит из множества всех таких соединенных строк. Обратите
внимание, что столбец DEPT# в каждой результирующей строке встречается один
раз, а не два. Обратите также внимание на то, что, поскольку в поле DEPT# таблицы
ЕМР нет значения ' D3' (т.е. нет служащих, работающих в отделе ' D3'), нет и резуль-
тирующих строк со значением 'D3' в этом поле, хотя строка со значением 'D3' в
таблице DEPT присутствует.
Необходимо отметить один важный момент, очевидный из рис. 3.2: результат
выполнения каждой из трех представленных операций — это еще одна таблица
(другими словами, эти операторы — фактически такие “операторы, которые порож-
дают таблицы из таблиц”, что мы подчеркивали ранее). Это реляционное свойство
замкнутости. Оно имеет очень большое значение и, главным образом, потому, что
результатом выполнения операции является объект того же рода, что и объект, над
которым производилась операция, а именно — таблица. Но это значит, что над ре-
зультатом операции можно вновь проделать какую-либо операцию. Например,
можно выбрать столбцы (операция PROJECT) из результата соединения таблиц
(операция JOIN) или соединить два результата выполнения операции SELECT и т.д.
Другими словами, можно использовать вложенные выражения, т.е. выражения, в
которых операнды представлены выражениями, а не простыми именами таблиц. В
данной и последующих главах вы увидите, что этот факт имеет, в свою очередь,
множество важных следствий.
Кстати, когда мы говорим, что результатом выполнения каждой операции является
таблица, мы имеем в виду, что это таблица с концептуальной точки зрения. Мы не хо-
тим сказать, что система обязательно должна полностью овеществлять результат каж-
дой отдельной операции. Предположим, например, что понадобилось выбрать строки
(операция SELECT) из соединения таблиц. В этом случае как только строка требуемого
соединения будет сформирована, система может немедленно применить к ней задан-
ное ограничение и проверить, будет ли она принадлежать конечному результату. Если
это не так, система может немедленно отбросить данную строку. Иначе говоря, про-
межуточный результат, который создается операцией соединения, возможно, никогда
и не будет существовать в виде полной овеществленной таблицы как таковой. На
практике, как правило, каждая система настойчиво стремится избежать полного ове-
ществления промежуточных результатов по вполне понятной причине — с целью по-
вышения производительности.
Замечание. Если промежуточные результаты полностью овеществлены, стратегия
вычисления выражения в целом называется (что неудивительно) овеществленными вы-
числениями', если промежуточные результаты передаются последующей операции по
частям, то этот подход называется конвейерными вычислениями.
94
Часть I. Основные понятия
Другой момент, который также недвусмысленно проиллюстрирован на рис. 3.2, за-
ключается в том, что операции применяются сразу ко всему множеству строк, а не к
отдельной строке за один раз, т.е. операндами и результатами являются не отдельные
строки, а целые таблицы, которые содержат множество строк. (Таблица, содержащая
множество из одной строки, конечно, тоже допустима, как и пустая таблица, в которой
совсем нет строк.) Например, операция JOIN на рис. 3.2 применяется к двум таблицам,
состоящим из трех и четырех строк соответственно, а в результате возвращает таблицу
из четырех строк. В противоположность этому операции нереляционных систем обычно
за одно обращение обрабатывают только одну строку или запись. Таким образом, воз-
можность обработки множеств— главная отличительная характеристика реляцион-
ных систем (обсуждение этого вопроса будет продолжено в разделе 3.5).
Давайте вновь вернемся к рис. 3.1. Есть несколько замечаний, которые можно сде-
лать на основе примера базы данных, приведенного на этом рисунке.
Во-первых, отметим, что определение реляционной системы требует, чтобы
база данных только воспринималась пользователем как набор таблиц. Табли-
цы в реляционной системе являются логическими, а не физическими струк-
турами. На самом деле на физическом уровне система может использовать
любую из существующих структур памяти (последовательный файл, индекси-
рование, хеширование, цепочку указателей, сжатие и т.п.), лишь бы существо-
вала возможность отображать эти структуры в виде таблиц на логическом
уровне. Данное положение можно сформулировать и по-другому: таблицы
представляют собой абстракцию способа физического хранения данных, в
которой множество деталей на уровне памяти (размещение хранимых записей,
последовательность хранимых записей, кодировка хранимых данных, префик-
сы хранимых записей, хранимые структуры доступа, такие как индексы, и т.д.)
скрыто от пользователя.
В данном случае термин “логическая структура” в терминологии ANSI/SPARC
относится как к концептуальному, так и к внешнему уровням. Дело в том, что,
как объяснялось в главе 2, и концептуальный, и внешний уровни в реляцион-
ной системе являются одинаково реляционными и лишь внутренний или фи-
зический уровень не является таковым. На самом деле реляционная теория
вообще ничего не может сказать о внутреннем уровне. Она, как уже отмеча-
лось, определяет то, как база данных представлена пользователю^. Повторим,
единственное требование состоит в следующем: какая бы физическая струк-
тура не была выбрана, она должна полностью реализовывать существующую
логическую структуру.
Во-вторых, у реляционных баз данных есть одно замечательное свойство, назы-
ваемое информационным принципом', все информационное содержимое базы
данных представлено одним и только одним способом, а именно — явным зада-
I К сожалению, приходится констатировать, что большинство современных SQL-продуктов
не обеспечивает должной поддержки этого аспекта теории. А точнее, они обычно в определен-
ной степени поддерживают только отображения “концептуальный-внутренний ” для операций
выборки (как правило, отображают одну логическую таблицу непосредственно в один хранимый
файл). И вследствие этого они не обеспечивают независимость от физических данных в той ме-
ре, в какой это теоретически предусмотрено в реляционной технологии.
Глава 3. Введение в реляционные базы данных
95
нием значений, помещенных в позиции столбцов в строках таблицы. Этот метод
представления единственно возможный для реляционных баз данных (естествен-
но, на логическом уровне). В частности, нет никаких указателей, связывающих
одну таблицу с другой. Например, на рис. 3.1 существует определенная связь ме-
жду строкой 'D1' в таблице DEPT и строкой ' Е1' в таблице ЕМР, указывающая, что
служащий с номером 'Е1' работает в отделе с номером 'D1'; но эта информация
представлена не указателем, а наличием значения 'D1' в столбце DEPT# строки
'Е1' в таблице ЕМР. В нереляционных системах (например, в IMS и IDMS), напро-
тив, такая информация обычно представляется (о чем шла речь в главе 1) неким
указателем, который пользователь видит явно.
Замечание. Когда мы говорим, что в реляционной системе нет указателей, мы не
имеем в виду, что в ней не может быть указателей на физическом уровне’, наобо-
рот, они, конечно, могут быть на этом уровне и в действительности наверняка
есть. Но, как уже объяснялось, подобные детали физического хранения в реляци-
онных системах скрываются от пользователя.
На этом закончим с вопросами, связанными со структурой и обработкой данных в ре-
ляционной модели, и перейдем к рассмотрению аспекта целостности. Еще раз восполь-
зуемся базой данных отделов и сотрудников, приведенной на рис. 3.1. На практике для
такой базы данных потребовалось бы определить несколько ограничений поддержки це-
лостности базы. Например, зарплата служащих не должна выходить за пределы диапазо-
на, скажем, от 25 до 95 тыс. долларов в год, а бюджет отдела должен быть, например, в
пределах от 1 до 15 млн долларов и т.д. Некоторые из таких правил имеют настолько
важное практическое значение, что получили специальные названия. Рассмотрим их.
1. Каждая строка в таблице DEPT должна включать уникальное значение столбца
DEPT#; аналогично каждая строка в таблице ЕМР должна включать уникальное
значение столбца ЕМР#. Говорят, что столбцы DEPT# в таблице DEPT и EMP# в таб-
лице ЕМР являются первичными ключами для своих таблиц. (Вспомните, что в
главе 1 мы условились отмечать на рисунках столбцы первичных ключей двой-
ным подчеркиванием.)
2. Каждое значение столбца DEPT# в таблице ЕМР должно существовать как значе-
ние столбца DEPT# в таблице DEPT для отражения того факта, что каждый слу-
жащий должен быть приписан к существующему отделу. Говорят, что столбец
DEPT# в таблице ЕМР является внешним ключом, ссылающимся на первичный
ключ таблицы DEPT.
Завершим этот раздел определением реляционной модели, чтобы в дальнейшем на
него можно было ссылаться (хотя на данном этапе такое определение будет несколько
абстрактным и не очень вразумительным). В первом приближении реляционная модель
состоит из следующих пяти компонентов.
1. Неограниченный набор скалярных типов (включая, в частности, логический тип
или значение истины).
2. Генератор типов отношений и соответствующая интерпретация для таких сгене-
рированных типов отношений.
96
Часть I. Основные понятия
3. Возможность определения переменных отношений для таких сгенерированных
типов отношений.
4. Операция реляционного присвоения для присвоения реляционных значений та-
ким переменным отношений.
5. Неограниченный набор общих реляционных операторов для получения значений
отношений из других значений отношений.
Как видите, реляционная модель— это нечто большее, чем просто “таблицы плюс
выборка, проекция и соединение”, хотя ее неформально довольно часто характеризуют
именно таким образом.
Замечание. Вас, возможно, удивило то, что в предыдущем определении отсутствует
явное упоминание о правилах целостности. Однако на самом деле такие правила пред-
ставляют собой просто приложения (хотя и очень важные), использующие реляционные
операторы. Иначе говоря, такие правила формулируются (во всяком случае, концепту-
ально) в терминах реляционных операторов, как мы сможем убедиться в главе 8.
3.3. Отношения и переменные-отношения
Если предположить, что реляционная база данных — это, по существу, просто база
данных, в которой данные представлены в виде таблиц (а это так и есть), то возникает
резонный вопрос: почему же мы называем такую базу данных именно реляционной, а не,
скажем, табличной? Ответ прост (фактически он был дан еще в главе 1): термин
“relation” (отношение) — это математическое название таблицы (точнее, определенного
вида таблиц; подробности приводятся в главе 5). Например, можно сказать, что база
данных отделов и служащих, представленная на рис. 3.1, содержит два отношения.
В настоящее время в неформальном контексте термины “отношение” и “таблица”
принято считать синонимами. На практике в подобном контексте термин “таблица” ис-
пользуется гораздо чаще, чем термин “отношение”. На обсуждении этого вопроса стоит
немного задержаться, чтобы выяснить, почему все-таки термин “отношение” поставлен
на первое место. Вкратце это объясняется следующим.
Как уже отмечалось, реляционные системы основаны на реляционной модели. Ре-
ляционная модель, в свою очередь, — это абстрактная теория данных, основанная
на некоторых положениях математики (в основном, теории множеств и логики
предикатов).
Принципы реляционной модели были изначально заложены в 1969 и 1970 годах
Е.Ф. Коддом (E.F. Codd), который в то время был исследователем, работавшим в
корпорации IBM. В конце 1968 года Кодд, математик по образованию, впервые
пришел к заключению, что математические дисциплины можно использовать для
привнесения в область управления базами данных строгих принципов и точности.
Именно этих качеств недоставало данной области в то время. Идеи Кодда впервые
подробно были изложены в ставшей классической статье “A Relational Model of
Data for Large Shared Data Banks” (cm. [5.1] в главе 5).
С того времени эти идеи стали общепринятыми и оказали весьма существенное влия-
ние на все аспекты технологии баз данных, а также на другие области, такие как искус-
ственный интеллект, обработка естественных языков и разработка аппаратных систем.
Глава 3. Введение в реляционные базы данных
97
В реляционной модели, как она изначально была сформулирована Коддом, умышленно
применялись определенные термины. Например, сам термин “отношение” практически не
использовался в то время в теории информационных технологий, хотя такое понятие ино-
гда употреблялось в других областях. Суть заключалась в том, что многие распространен-
ные тогда термины были очень нечеткими — им не хватало точности, необходимой для
такой формальной теории, которую предложил Кодд. Например, рассмотрим термин
“запись”. В разное время и в различных контекстах он мог означать экземпляр записи или
тип записи, логическую запись или физическую запись, хранимую запись или виртуальную
запись, а возможно, и еще что-нибудь. Поэтому в формальной реляционной модели термин
“запись” не используется вообще — вместо него применяется термин “кортеж” (tuple), точ-
ное определение которого дал сам Кодд, когда впервые его ввел. Мы не станем приводить
здесь это определение, а лишь отметим, что термин “кортеж” приблизительно соответству-
ет понятию строки (так же, как термин “отношение” приблизительно соответствует поня-
тию таблицы). При дальнейшем изучении более формальных аспектов реляционных систем
в части II мы будем использовать более формальную терминологию, однако здесь мы не
станем придерживаться строго формальных терминов, а воспользуемся более привычными,
такими как “строка” и “столбец”. Однако один формальный термин мы все-таки будем ис-
пользовать довольно часто — это термин “отношение”.
Снова обратимся к базе данных отделов и сотрудников, представленной на рис. 3.1.
Заметим, что таблицы DEPT и ЕМР в базе данных фактически являются переменными от-
ношений, т.е. их значения — это значения отношений (различные значения отношений в
разное время). Предположим, например, что таблица ЕМР в данный момент имеет значе-
ние {значение отношения), которое показано на рис. 3.1, и далее предположим, что мы
удалили строку о сотруднике с фамилией Saito (его номер — ' Е4').
DELETE ЕМР WHERE EMP# = 'Е4' ;
Результат выполнения этой операции показан на рис. 3.3.
EMP# ENAME DEPT# SALARY
Е1 Lopez DI 40K
Е2 Cheng DI 42K
ЕЗ Finzi D2 30K
Рис. 3.3. Переменная-отношение ЕМР после удаления строки сотрудника с кодом 'Е4'
Концептуально это можно прокомментировать таким образом: старое значение отно-
шения ЕМР было заменено в целом совершенно другим, новым значением отношения. Ко-
нечно, старое значение (с четырьмя строками) и новое значение (с тремя строками) очень
похожи, но концептуально они являются разными. На самом деле данная операция удале-
ния строки, по сути, — это просто другой, упрощенный способ записи для определенной
операции реляционного присвоения, которая могла бы выглядеть примерно так.
ЕМР := ЕМР MINUS ( ЕМР WHERE EMP# = 'Е4' ) ;
{Замечание. Как первоначальный оператор DELETE, так и равносильный ему оператор
присвоения записаны на языке Tutorial D [3.3]. Ключевое слово MINUS используется в язы-
ке Tutorial D для реляционной операции разности. Подробности приводятся в главе 6.)
98
Часть I. Основные понятия
Как и при любом присвоении, здесь с концептуальной точки зрения сначала вычис-
ляется выражение, расположенное справа от знака присвоения, а затем результат при-
сваивается переменной, которая записана перед знаком присвоения (по определению
перед знаком присвоения может быть, естественно, только переменная). В целом, как
уже отмечалось, задача заключается в том, чтобы заменить “старое” значение отноше-
ния ЕМР “новым”.
Естественно, что операции INSERT и UPDATE также по существу являются другой фор-
мой записи соответствующих реляционных операций присвоения.
Но вот что огорчает: во многих публикациях термин отношение используется, когда
в действительности подразумевается переменная отношения (а также тогда, когда подра-
зумевается само отношение, т.е. значение отношения). А это, как показывает практика,
приводит к недоразумениям. Поэтому в дальнейшем здесь мы будем четко различать пе-
ременные отношений и сами отношения. Следуя примеру публикации [3.3], для пере-
менной отношения (relation variable) будем использовать термин переменная-
отношение (сокращенный английский вариант— relvar), и только его, во всех случаях,
когда речь будет идти не об отношении, а о переменной отношения.
Замечание. Следует предупредить читателя, что термин “relvar” (переменная-
отношение) не является общепринятым, хотя должен быть таковым! Мы действительно
считаем, что очень важно различать сами отношения (т.е. значения отношений) и пере-
менные отношений, хотя предыдущие издания настоящей книги также этим грешили и
большая часть литературы по базам данных не придает этому значения.
3.4. Смысл отношений
В главе 1 отмечалось, что столбцы в отношениях связаны с типами данных2. А в
конце раздела 3.2 мы говорили, что реляционная модель включает “неограниченный на-
бор типов [данных]”. Помимо всего прочего, это означает, что пользователи могут оп-
ределять собственные типы (а также, конечно, применять определенные системой или
встроенные типы). Например, определять типы можно представленным ниже способом
(снова воспользуемся синтаксисом языка Tutorial D, причем многоточие “...” здесь за-
меняет определения, которые для нас сейчас не важны).
TYPE EMP# ... ;
TYPE NAME ... ;
TYPE DEPT# ... ;
TYPE MONEY ... ;
Тип EMP#, например, можно рассматривать, как множество всевозможных номеров
служащих, тип NAME — как множество всевозможных имен, и т.д.
Теперь обратимся к рис. 3.4, который фактически представляет собой часть рис. 3.1 с
переменной-отношением ЕМР, которая была расширена с целью указания типов столбцов.
Как показано на этом рисунке, каждое отношение, точнее, каждое значение отношения,
состоит из двух частей: набора пар “имя-столбца:имя-типа” (заголовок) и набора строк,
согласованных с этим заголовком (тело).
2 Как мы увидим в главе 5, для типов данных чаще используют термин “домены ".
Глава 3. Введение в реляционные базы данных
99
EMP
EMP# [EMP# ENAME [NAME DEPT# [DEPT# SALARY [MONEY
Е1 Lopez DI 40K
Е2 Cheng DI 42K
ЕЗ Finzi D2 30K
Е4 Saito D2 35K
Рис. 3.4. Пример значения отношения ЕМР с отображением типов столбцов
Замечание. На практике компоненты заголовка “имя-тип” зачастую опускают, как это
делали и мы во всех предыдущих примерах. Однако необходимо учитывать, что концеп-
туально они всегда присутствуют.
Рассмотрим один важный, хотя и не столь распространенный, способ представления
смысла отношений.
Во-первых, данное отношение г и заголовок отношения г представляют опреде-
ленный предикат или логическую функцию.
Во-вторых, как упоминалось в главе 1, каждая строка в теле отношения г представ-
ляет собой определенное истинное высказывание, полученное из предиката путем
подстановки определенных значений аргументов соответствующего типа вместо
местодержателей или параметров этого предиката (реализация предиката).
Например в случае, представленном на рис. 3.4, предикат будет следующим.
Служащий с номером EMP# по фамилии ENAME работает в отделе с номером
DEPT# и получает зарплату SALARY.
Здесь параметрами являются EMP#, ENAME, DEPT# и SALARY, которые, конечно же, соот-
ветствуют четырем столбцам переменной-отношения ЕМР. Вот примеры соответствую-
щих истинных утверждений.
Служащий с номером 'Е1' по фамилии 'Lopez' работает в отделе с номером
'D1 ’ и получает зарплату 40 тыс. долларов в год.
(Получено путем подстановки в параметр EMP# значения 'El', в параметр NAME— зна-
чения ’ Lopez ’, в параметр DEPT# — значения ’ D1' ив параметр SALARY — значения 40К.)
Служащий с номером 'Е2' по фамилии 'Cheng' работает в отделе с номером
'D1' и получает зарплату 42 тыс. долларов в год.
(Получено путем подстановки в параметр EMP# значения 'Е2', в параметр NAME —
значения 'Cheng', в параметр DEPT# — значения ' D1' ив параметр SALARY — значения
42К.) Короче говоря:
типы — это объекты (множества объектов), которые можно обсуждать;
отношения — это факты (множества фактов), касающиеся объектов, кото-
рые можно обсуждать.
(Есть прекрасная аналогия, которая может помочь вам понять смысл и запомнить эти
важные определения: Типы связаны с отношениями точно так, как существительные
связаны с предложениями.') В нашем примере то, что мы можем обсуждать, — это номе-
ра служащих, их имена, номера отделов и значения денежных сумм, а то, что мы можем
100
Часть I. Основные понятия
сказать об обсуждаемом, — это истинное высказывание такого вида: “Служащий с опре-
деленным номером служащего имеет определенное имя, работает в определенном отделе
и получает определенную зарплату”.
Из вышесказанного следует, что:
во-первых, необходимы и типы, и отношения (без типов нам не о чем говорить,
без отношений мы ничего не сможем сказать);
во-вторых, типы и отношения достаточны так же, как и необходимы, т.е., логи-
чески говоря, нам не нужно что-либо еще.
Замечание. Также можно сделать вывод о том, что типы и отношения — это не одно
и то же. К сожалению, в некоторых коммерческих продуктах (нереляционных по опре-
делению!) эти два понятия смешиваются. Мы еще вернемся к данному вопросу в гла-
ве 25 (раздел 25.2).
Кстати, важно понимать, что каждое отношение имеет связанный с ним предикат,
включая отношения, полученные с помощью реляционных операторов, например опера-
тора соединения. Отношение DEPT на рис. 3.1 и три результирующих отношения на
рис. 3.2 имеют такие предикаты.
DEPT: “Отдел с номером DEPT# называется DNAME и имеет бюджет BUDGET”.
Выборка строк из DEPT, где BUDGET > 8М: “Отдел с номером DEPT# называется
DNAME и имеет бюджет BUDGET, который больше восьми миллионов долларов”.
Извлечение столбцов DEPT# и BUDGET из DEPT: “Отдел с номером DEPT# имеет ка-
кое-то название и бюджет BUDGET”.
Соединение переменных-отношений DEPT и ЕМР на основе столбца DEPT#: “Отдел
с номером DEPT# называется DNAME и имеет бюджет BUDGET, а служащий с номером
EMP# по фамилии ENAME работает в отделе с номером DEPT# и получает зарплату
SALARY” (заметим, что этот предикат имеет шесть параметров, а не семь, посколь-
ку две ссылки на DEPT# обозначают один и тот же параметр).
3.5. Оптимизация
Как объяснялось в разделе 3.2, реляционные операции, такие как выборка, проекция и
соединение, выполняются на уровне множеств. Поэтому реляционные языки часто на-
зывают непроцедурными, так как пользователь указывает, что делать, а не как делать.
Фактически пользователь говорит лишь, что ему нужно, без указания процедуры получе-
ния результата. Процесс “навигации” по хранимой базе данных с целью удовлетворения
запроса пользователя выполняется системой автоматически, а не пользователем
вручную. Поэтому реляционные системы иногда называют системами автоматической
навигации. В нереляционных системах за навигацию по базе данных, в основном, несет
ответственность сам пользователь. На рис. 3.5 приведена яркая иллюстрация преиму-
ществ автоматической навигации — оператору языка SQL INSERT противопоставлен код,
выполняющий навигацию “вручную”. Подобный код, возможно, должен написать для
получения того же результата пользователь нереляционной системы (в данном случае —
сетевой системы CODASYL; пример взят из главы по сетевым базам данных в [1.5]).
,,Замечание. Здесь используется широкоизвестная база данных деталей и поставщиков.
Защодробностями обратитесь к разделу 3.9.
Глава 3. Введение в реляционные базы данных
101
Несмотря на предыдущие замечания, следует отметить, что “непроцедурный” — это
хотя и общепринятый, но не совсем точный термин, потому что “процедурный” и
“непроцедурный” — понятия относительные. Можно лишь с уверенностью сказать, что
язык А более (или менее) процедурный, чем язык Б. Поэтому точнее будет сказать, что
реляционные языки, такие как SQL, обладают более высоким уровнем абстракции, чем
типичные языки программирования, подобные C++ или COBOL (либо подъязыки дан-
ных, обычно принадлежащие нереляционным СУБД; убедитесь в этом сами; см.
рис. 3.5). В принципе, именно более высокий уровень абстракции способствует повыше-
нию продуктивности, характерному для реляционных систем.
INSERT INTO SP ( S#, P#, QTY )
VAOLUES ( 'S4', 'P3', 1000 ) ;
MOVE 'S4' TO S# IN S
FIND CALC S
ACCEPT S-SP-ADDR FROM S-SP CURRENCY
FIND LAST SP WITHIN S-SP
while SP found PERFORM
ACCEPT S-SP-ADDR FROM S-SP CURRENCY
FIND OWNER WITHIN P-SP
GET P
IF P# IN P < 'P3'
leave loop
END-IF
FIND PRIOR SP WITHIN S-SP
END-PERFORM
MOVE 'P3' TO P# IN P
FIND CALC P
ACCEPT P-SP-ADDR FROM P-SP CURRENCY
FIND LAST SP WITHIN P-SP
while SP found PERFORM
ACCEPT P-SP-ADDR FROM P-SP CURRENCY
FIND OWNER WITHIN S-SP
GET S
IF S# IN S < 'S4'
leave loop
END-IF
FIND PRIOR SP WITHIN P-SP
END-PERFORM
MOVE 1000 TO QTY IN SP
FIND DB-KEY IS S-SP-ADDR
FIND DB-KEY IS P-SP-ADDR
STORE SP
CONNECT SP TO S-SP
CONNECT SP TO P-SP
Рис. 3.5. Примеры автоматической навигации и навигации вручную
102
Часть I. Основные понятия
Ответственность за то, как именно выполняется автоматическая навигация, несет очень
важный компонент СУБД — оптимизатор (мы уже упоминали о нем в главе 2). Другими
словами, работа оптимизатора заключается в том, чтобы для каждого запроса пользователя
выбрать самый эффективный способ выполнения этого запроса. Предположим, например,
что пользователь сделал следующий запрос (снова воспользуемся языком Tutorial D).
RESULT := ( ЕМР WHERE EMP# = 'Е4' ) { SALARY } ;
Пояснение. Выражение в первых скобках (ЕМР WHERE ...) означает запрос выборки
строк из переменной-отношения ЕМР, а именно — той строки, в которой значение столб-
ца EMP# равно 'Е4'. Название столбца в фигурных скобках (SALARY) означает запрос вы-
борки столбцов (иначе называемый проекцией) из результата, полученного после выбор-
ки строк, а именно — столбца SALARY. И наконец, оператор присвоения (:=) означает за-
прос присвоения результата выборки столбцов переменной-отношению RESULT. Следова-
тельно, после выполнения запроса переменная-отношение RESULT будет содержать зна-
чение из одной строки и одного столбца, содержащего значение зарплаты служащего с
номером 'Е4'. (Обратите внимание, что в данном случае в явном виде используется ре-
ляционное свойство замкнутости: мы написали вложенное выражение, в котором ре-
зультат выборки строк — это входные данные для выборки столбцов.)
Даже в этом простом примере существует по крайней мере два способа поиска необ-
ходимых данных.
1. Последовательный физический просмотр (хранимой версии) переменной-
отношения ЕМР, пока требуемая запись не будет найдена.
2. Если есть индекс для столбца EMP# (в хранимой версии) переменной-отношения
(который, вероятно, действительно существует, поскольку этот столбец является
уникальным, а большинство систем фактически требует создания индекса для
обеспечения уникальности), то переход с помощью этого индекса непосредственно
к данным служащего с номером 'Е4'.
Оптимизатор выберет, какую из двух возможных стратегий следует применить. В
общем случае для реализации любого конкретного реляционного запроса оптимизатор
будет осуществлять выбор стратегии, исходя из соображений, подобных следующим:
на какие переменные-отношения есть ссылки в запросе;
насколько велики эти переменные-отношения;
какие существуют индексы;
насколько избирательны эти индексы;
как физически группируются данные на диске;
какие реляционные операции используются и т.д.
Поэтому повторяем: пользователь указывает в запросе, какие данные ему требуются,
а не как их получить, тогда как стратегия доступа к данным выбирается оптимизатором
(автоматическая навигация). В результате пользователи и пользовательские программы
обретают независимость от применяемых стратегий доступа, что, конечно же, совершен-
но необходимо, если мы хотим достичь реальной независимости от физического пред-
ставления данных.
Более подробные сведения об оптимизаторе приводятся в главе 17.
Глава 3. Введение в реляционные базы данных
103
3.6. Каталог
Как отмечалось в главе 2, каждая СУБД должна поддерживать функцию каталога,
или словаря. Каталог обычно размещается там, где сохраняются различные схемы
(внешние, концептуальные, внутренние) и все, что относится к отображениям (“внеш-
ний-концептуальный”, “концептуальный-внутренний”). Иначе говоря, в каталоге со-
держится детальная информация (иногда называемая метаданными), касающаяся раз-
личных объектов, которые имеют значение для самой системы. Примерами таких объ-
ектов могут служить переменные-отношения, индексы, ограничения поддержки цело-
стности, ограничения защиты и т.д. Метаданные необходимы для обеспечения пра-
вильной работы системы. Например, оптимизатор использует информацию каталога
об индексах и других физических структурах хранения данных, а также иную инфор-
мацию, необходимую ему для принятия решения о том, каким образом выполнить тот
или иной запрос пользователя. Аналогично подсистема защиты использует информа-
цию каталога о пользователях и установленных ограничениях защиты (глава 16), что-
бы разрешить или отклонить выполнение поступившего запроса.
Замечательным свойством реляционных систем является то, что их каталог также
состоит из переменных-отношений (точнее, из системных переменных-отношений, на-
званных так для того, чтобы отличать их от обычных пользовательских). В результате
пользователь может обращаться к каталогу так же, как к своим данным. Например, в ка-
талоге обычно содержатся системные переменные-отношения TABLES и COLUMNS, назна-
чение которых— описание известных системе таблиц (т.е. переменных-отношений) и
столбцов этих таблиц. (Мы говорим “обычно”, потому что каталоги в различных систе-
мах разные, так как существенная часть информации каталога является специфической
для конкретной системы.) Для базы данных отделов и служащих переменные-отношения
TABLES и COLUMNS могут схематически выглядеть так, как показано на рис. З.б3.
Замечание. Как упоминалось в главе 2, каталог должен описывать самого себя, т.е. он
должен включать записи, описывающие переменные-отношения самого каталога. Тем не
менее на рис. 3.6 такие записи не показаны. (Подробности приводятся в упр. 3.3.)
Теперь предположим, что пользователю базы данных отделов и служащих понадоби-
лось узнать, какие именно столбцы содержит переменная-отношение DEPT (конечно,
предполагается, что по каким-то причинам пользователь не имеет этой информации).
Тогда необходимое выражение будет выглядеть следующим образом.
( COLUMNS WHERE TABNAME = 'DEPT' ) { COLNAME }
Замечание. Если бы нам понадобилось сохранить результат в более постоянном
виде, мы могли бы присвоить его другой переменной отношения, скажем, перемен-
ной RESULT, как было показано в примере из предыдущего раздела, но в большинст-
ве наших примеров мы будем опускать этот шаг присвоения (как в этой, так и в по-
следующих главах).
3 Отметим, что исходя из наличия на этом рисунке столбца ROWCOUNT можно сделать сле-
дующее заключение: выполнение в базе данных операций INSERT и DELETE в качестве побочного
эффекта потребует обновления данных каталога. На практике столбец ROWCOUNT обычно об-
новляется только по специальному запросу (например, при запуске некоторой утилиты), поэто-
му значения этого столбца не всегда будут актуальными.
104
Часть I. Основные понятия
TABLES TABNAME COLCOUNT ROWCONT
DEPT 3 3
EMP 4 4
COLUMNS TABNAME COLNAME
DEPT DEPT#
DEPT DNAME
DEPT BUDGET
EMP EMP#
EMP ENAME
EMP DEPT#
EMP SALARY
Рис. 3.6. Каталог базы данных отделов и служащих (изображен схематически)
Вот еще один пример. Пусть необходимо узнать, в каких переменных-отношениях
есть столбец ЕМР#.
( COLUMNS WHERE COLNAME = 'ЕМР#' ) { TABNAME }
Упражнение для самопроверки. Каким будет результат выполнения следующего вы-
ражения.
( ( TABLES JOIN COLUMNS )
WHERE COLCOUNT < 5 ) { TABNAME, COLNAME }
3.7. Базовые переменные-отношения
и представления
Мы уже видели, что на основе реляционных значений, присвоенных некоторому
множеству переменных-отношений, подобных DEPT и ЕМР, реляционные выражения
позволяют получить множество других реляционных значений, например в результате
соединения двух переменных-отношений. Пришло время ввести еще несколько новых
терминов. Исходные (заданные) переменные-отношения называются базовыми пере-
менными-отношениями, а присвоенные им значения называются базовыми отно-
шениями. Отношение, которое получено или может быть получено из базового отно-
шения в результате выполнения каких-либо реляционных выражений, называется про-
изводным отношением.
, Замечание. В [3.3] базовые переменные-отношения называются реальными перемен-
ными-отношениями.
Реляционные системы, очевидно, должны предоставлять средства для создания, в
первую очередь, базовых переменных-отношений. В языке SQL, например, эта функция
обеспечивается оператором CREATE TABLE (здесь слово TABLE используется в узком
смысле, как базовая переменная-отношение). Базовые переменные-отношения, конечно
же, должны быть именованными, как, например, показано ниже.
CREATE TABLE ЕМР ... ;
Глава 3. Введение в реляционные базы данных
105
Однако реляционные системы обычно поддерживают еще один вид именованных пе-
ременных-отношений, называемых представлениями. В любой конкретный момент их
значение является производным отношением (и поэтому упрощенно можно считать, что
представление— это производная переменная-отношение). Значение данного пред-
ставления в данное время является результатом вычисления определенного реляционно-
го выражения в данный момент, а упомянутое реляционное выражение определяется в
момент создания этого представления. Например, для определения представления
ТОРЕМР можно использовать следующий оператор.
CREATE VIEW ТОРЕМР AS
( ЕМР WHERE SALARY > ЗЗК ) { ЕМР#, ENAME, SALARY } ;
Замечание. Поскольку в данный момент это несущественно, в примере используется
смешанная нотация языков SQL и Tutorial D.
Когда этот оператор выполняется, выражение, следующее за ключевым словом AS и
фактически определяющее представление, не вычисляется, а просто запоминается
системой (обычно посредством сохранения в каталоге под указанным именем ТОРЕМР).
Однако, с точки зрения пользователя, все выглядит так, как будто в базе данных появи-
лась вполне реальная переменная-отношение с именем ТОРЕМР, имеющая текущее значе-
ние, которое показано на рис. 3.7 только в незатененных участках. И пользователь дол-
жен иметь возможность оперировать этим представлением точно так, как если бы оно
являлось обычной базовой переменной-отношением.
Замечание. Если, как мы уже отмечали, такие переменные-отношения, как DEPT и
ЕМР, можно считать реальными, то переменную-отношение ТОРЕМР следует понимать
как виртуальную переменную-отношение. Иначе говоря, как переменную-отношение,
которая внешне существует как таковая, но на самом деле ее нет (значение этой пере-
менной-отношения в любой данный момент зависит от значений некоторых других
переменных-отношений).
ТОРЕМР EMP# ENAME DEPT# SALARY
Е1 Lopez DI 40K
Е2 Cheng DI 42K
ЕЗ Finzi D2 30K
Е4 Saito D2 35K
Рис. 3.7. Виртуальная переменная-отношение ТОРЕМР (затененные участки) как пред-
ставление базовой переменной-отношения ЕМР
Однако будьте внимательны: отмечая, что значение переменной-отношения
ТОРЕМР является отношением, которое было бы результатом, если бы определяющее
данное представление выражение было на самом деле вычислено, мы вовсе не хотим
сказать, что существует отдельная копия этих данных. Иначе говоря, мы вовсе, не
имеем в виду, что определяющее представление выражение на самом деле вычисля-
ется. Наоборот, представление — это, по сути, просто окно, через которое можно
видеть часть значения базовой переменной-отношения ЕМР. Отсюда следует, что лю-
бые изменения в базовой переменной-отношении будут автоматически и немедленно
106
Часть I. Основные понятия
видны в подобном окне (конечно, если эти изменения относятся к незатененной час-
ти реальной переменной-отношения). Аналогично изменения, внесенные в пере-
менную-отношение ТОРЕМР, будут автоматически и немедленно применены к реаль-
ной переменной-отношению ЕМР и, следовательно, станут видны через это окно
(примеры будут приведены позднее).
Ниже показан пример запроса, использующего представление ТОРЕМР.
( ТОРЕМР WHERE SALARY < 42К ) { ЕМР#, SALARY }
Результат будет иметь следующий вид.
EMP# SALARY
Е1 40К
Е4 35К
С концептуальной точки зрения операции с представлениями, подобные рассмотрен-
ной выше, фактически реализуются посредством замены ссылки на имя представления
выражением, которое определяет представление (т.е. выражением, сохраненным в ката-
логе). Поэтому в рассмотренном примере исходное выражение
( ТОРЕМР WHERE SALARY < 42К ) { ЕМР#, SALARY }
модифицируется системой следующим образом.
(( ЕМР WHERE SALARY > ЗЗК ) { ЕМР#, ENAME, SALARY }
WHERE SALARY < 42K ) { EMP#, SALARY }
Здесь курсивом выделено имя представления в исходном выражении и заменяющий
текст в модифицированной версии. После определенного количества перегруппировок
это выражение может быть упрощено (глава 17) и может принять следующий вид.
( ЕМР WHERE SALARY > ЗЗК AND SALARY < 42К ) { ЕМР#, SALARY }
Вычисление данного выражения приводит к результату, показанному выше. Иными
словами, первоначальная операция над представлением просто конвертируется в эквива-
лентную операцию над соответствующей базовой переменной-отношением, после чего
полученная эквивалентная операция выполняется обычным образом (точнее, оптимизи-
руется и выполняется обычным образом).
В качестве другого примера рассмотрим операцию удаления DELETE.
DELETE ТОРЕМР WHERE SALARY < 42К ;
На самом деле будет выполнена следующая операция.
DELETE ЕМР WHERE SALARY > ЗЗК AND SALARY < 42К ;
Наше представление ТОРЕМР — очень простое представление, состоящее из под-
множества строк и столбцов единственной базовой переменной-отношения. Однако, в
принципе, определение представления может быть произвольной сложности. Напри-
мер, вот представление, определение которого включает соединение двух базовых пе-
ременных-отношений.
Глава 3. Введение в реляционные базы данных
107
CREATE VIEW JOINEX AS
( ( EMP JOIN DEPT ) WHERE BUDGET > 7M ) [ EMP#, DEPT# ] ;
К вопросу определения и обработки представлений мы еще вернемся в главе 9.
Между прочим, сейчас уже можно объяснить приведенное в конце раздела 2.2 за-
мечание относительно того, что термин представление (view) в реляционном контек-
сте имеет особое специфическое значение, не совпадающее со значением, приписан-
ным ему в архитектуре ANSI/SPARC. На внешнем уровне этой архитектуры база дан-
ных воспринимается как “внешнее представление”, определяемое внешней схемой (и
разные пользователи могут иметь разные внешние представления). В реляционных
системах, наоборот, представление, как пояснялось выше, является специально имено-
ванной производной виртуальной переменной-отношением. Поэтому реляционным
аналогом “внешнего представления” ANSI/SPARC обычно служит множество из не-
скольких переменных-отношений, каждая из которых является представлением в ре-
ляционном смысле. “Внешняя схема” состоит из определений таких представлений.
(Отсюда следует, что представления в реляционном смысле являются способом обес-
печения логической независимости данных, хотя еще раз следует отметить, что со-
временные коммерческие продукты имеют серьезные недостатки в этом вопросе.
(Подробности приводятся в главе 9.)
Архитектура ANSI/SPARC является достаточно общей и допускает произвольные из-
менения между внешним и концептуальным уровнями. В принципе, даже типы структур
данных, поддерживаемые на этих двух уровнях, могут быть различными: например, кон-
цептуальный уровень может быть реляционным, тогда как конкретному пользователю
может быть предоставлено внешнее представление иерархического типа. Однако на
практике большинство систем использует одинаковые типы структур в качестве базовых
на обоих уровнях. Реляционные продукты не являются исключением из этого общего
правила — представление по-прежнему остается переменной-отношением, как и базовые
переменные-отношения. А поскольку на обоих уровнях поддерживаются одинаковые ти-
пы объектов, на этих уровнях применяется один и тот же подъязык данных (обычно это
язык SQL). Действительно, тот факт, что представление— это тоже переменная-
отношение, так же важен для реляционных систем, как для математики важно то, что
подмножество также является множеством.
Замечание. Однако реальные SQL-продукты и сам стандарт языка SQL, похо-
же, часто игнорируют этот момент (глава 4), поскольку нередко ссылаются на
“таблицы и представления” (в том смысле, что представление не является табли-
цей). Советуем не делать этой распространенной ошибки, используя термин “таб-
лицы” (или “переменные-отношения”) лишь для базовых таблиц (или “базовых пе-
ременных-отношений”).
Есть еще один заслуживающий внимания вопрос, касающийся базовых переменных-
отношений и представлений. Различие между базовой переменной-отношением и пред-
ставлением часто характеризуется следующим образом.
Базовые переменные-отношения “реально существуют” в том смысле, что они
представляют данные, которые действительно хранятся в базе данных.
Представления, наоборот, “реально не существуют”, а просто предоставляют раз-
личные способы просмотра “реальных” данных.
108
Часть I. Основные понятая
Однако такая характеристика хотя и полезна в неформальном смысле, неточно
отражает истинное положение дел. Действительно, пользователи могут представ-
лять базовые переменные-отношения как физически хранимые, поскольку
фактически главная цель создания реляционных систем состоит в том, чтобы позво-
лить пользователю работать с базовыми переменными-отношениями как с физиче-
ски существующими, не заботясь о том, как в действительности эти переменные-
отношения физически представлены в памяти. Но (и это весьма существенное “но”!)
подобное представление пользователей нельзя толковать так, что базовая перемен-
ная-отношение — это непосредственно физически хранимая переменная-отношение
(т.е. как единственный хранимый файл)4. Как пояснялось в разделе 2.2, базовые пе-
ременные-отношения лучше всего представлять как абстракцию для некоторого на-
бора хранимых данных — абстракцию, скрывающую все детали уровня хранения
данных. В принципе, базовая переменная-отношение и ее хранимый эквивалент мо-
гут отличаться в произвольной степени.
Простой пример поможет прояснить этот вопрос. Снова рассмотрим базу данных от-
делов и служащих. Большинство сегодняшних реляционных систем, вероятно, реализо-
вали бы ее в виде двух хранимых файлов, по одному для каждой переменной-отношения
базы данных. Но нет абсолютно никаких аргументов против создания одного хранимого
файла иерархически хранимых записей, каждая из которых состоит из номера отдела, на-
звания и бюджета для некоторого отдела вместе с номером служащего, именем и зарпла-
той для каждого служащего, работающего в этом отделе. Иначе говоря, для физического
хранения данных может быть использован любой подходящий способ, но на логическом
уровне данные всегда должны выглядеть одинаково.
3.8. Транзакции
Замечание. Тему этого раздела нельзя отнести исключительно к теме реляционных
систем. Тем не менее она здесь уместна, поскольку понимание основной идеи необходи-
мо для усвоения некоторых аспектов материала и логичного перехода к части II. Одна-
ко здесь данная тема описывается лишь поверхностно.
В главе 1 указывалось, что транзакция — это логическая единица работы, обычно
включающая несколько операций над базой данных. Также отмечалось, что пользователь
должен иметь возможность указать системе, что отдельные операции являются частью
одной транзакции. Для этого используются операции BEGIN TRANSACTION, COMMIT и
ROLLBACK. Как правило, транзакция начинается при выполнении операции BEGIN
TRANSACTION и прекращается при выполнении операции COMMIT или ROLLBACK, как в сле-
дующем примере, написанном на псевдокоде.
4 Следующая цитата из одной недавно вышедшей книги демонстрирует некоторые недора-
зумения, обсуждаемые здесь, а также недоразумения, которые обсуждались в разделе 3.3.
“Важно различать хранимые отношения, которые являются таблицами, и виртуальные отно-
шения, которые являются представлениями... [Мы] будем использовать термин отношение
только в тех случаях, когда вместо него можно использовать термин “таблица" или
“представление “. Если необходимо будет подчеркнуть, что данное отношение является храни-
мым отношением, а не представлением, то в этом случае мы будем использовать термин базо-
вое отношение или базовая таблица. ” Подобные цитаты, к сожалению, — не редкость
Глава 3. Введение в реляционные базы данных
109
BEGIN TRANSACTION ; /* Перевести $$$ co счета А на счет В */
UPDATE account A ; /* Снятие денег co счета A */
UPDATE account В ; /* Помещение денег на счет В */
IF <Все выполнено успешно>
THEN COMMIT ; /* Нормальное завершение */
ELSE ROLLBACK ; /* Аварийное завершение */
END IF ;
Отметим некоторые свойства транзакций.
1. Транзакции заведомо атомарны, т.е. они гарантируют (с логической точки зре-
ния), что будут выполнены полностью или не выполнены вовсе, даже если в систе-
ме до окончания процесса выполнения транзакции произойдет сбой.
2. Транзакции гарантируют продолжительность результатов их выполнения в том
смысле, что если транзакция успешно выполнила оператор COMMIT, то все выпол-
ненные ею изменения гарантированно будут реализованы в базе данных, даже если
позднее в системе в какой-то момент произойдет сбой.
Замечание. По сути, благодаря именно этому свойству продолжительности тран-
закций данные в базе данных являются постоянными в том смысле, который объ-
яснялся в главе 1.
3. Для транзакций также гарантируется изолированность одной транзакции от
другой. Под этим подразумевается, что изменения в базе данных, выполненные
некоторой транзакцией Т1, не будут видимы для любой транзакции Т2 до тех
пор, пока и только пока транзакцией Т1 не будет успешно выполнена операция
COMMIT. После выполнения операции COMMIT изменения, которые были произве-
дены некоторой транзакцией, становятся видимыми для других транзакций. О
таких изменениях говорят, что они зафиксированы, и гарантируется, что они ни-
когда не будут отменены. Если же, напротив, транзакцией была выполнена опе-
рация ROLLBACK, все изменения, которые были внесены в базу данных в процессе
выполнения этой транзакции, будут отменены (выполнен откат изменений). В
последнем случае конечный результат будет таким, как если бы данная транзак-
ция вообще не выполнялась.
4. При параллельном выполнении нескольких транзакций, операции которых череду-
ются между собой, обычно гарантируется, что осуществление этих операций будет
упорядоченным (serializable). Иначе говоря, результат выполнения каждой из
транзакций будет точно таким же, как при строго последовательном выполнении
этих же транзакций в некотором произвольном порядке.
Развернутое обсуждение всех остальных аспектов данной темы будет продолжено в
главах 14 и 15.
3.9. База данных поставщиков и деталей
На протяжении почти всей этой книги используется пример, названный нами базой
данных поставщиков и деталей (поддерживаемой, как уже упоминалось в главе 1,
вымышленной компанией KnowWare, Inc.). Назначение настоящего раздела— позна-
110
Часть I. Основные понятия
комить читателя с этой базой данных, которая будет служить примером для ссылок в
последующих главах. На рис. 3.8 показано множество значений ее данных. Именно эти
конкретные значения будут фактически использоваться в дальнейшем (где это имеет
смысл). На рис. 3.9 показано определение базы данных, для которого снова использу-
ется (несколько измененный) язык Tutorial D. В частности, обратите внимание на
спецификации первичных и внешних ключей. Кроме того, обратите внимание на то,
что несколько столбцов имеют типы данных, которым присвоено название, аналогич-
ное названию соответствующего столбца. Столбцы STATUS и CITY определены как
имеющие не пользовательский, а встроенный тип данных— INTEGER (целое) и CHAR
(строка символов произвольной длины) соответственно. Наконец, необходимо отме-
тить, что в отношении значений, показанных в столбцах на рис. 3.8, должно быть сде-
лано одно важное замечание, однако мы еще не готовы к этому. Поэтому обсуждение
упомянутого замечания будет отложено до главы 5, точнее — до подраздела
“Внутренний уровень” в разделе 5.2.
S# SNAME STATUS CITY SP S# P# QTY
S1 Smith 20 London SI Pl 300
S2 Jones 10 Paris SI P2 200
S3 Black 30 Paris SI P3 400
S4 Clark 20 London SI P4 200
S5 Adams 30 Athens SI P5 100
SI P6 100
P# PNAME COLOR WEIGHT CITY S2 Pl 300
Р1 Nut Red 12.0 London S2 P2 400
Р2 Bolt Green 17.0 Paris S3 P2 200
РЗ Screw Blue 17.0 Rome S4 P2 200
Р4 Screw Red 14.0 London S4 P4 300
Р5 Cam Blue 12.0 Paris S4 P5 400
Р6 Cog Red 19.0 London
Рис. 3.8. База данных поставщиков и деталей (пример значений)
В базе данных предполагается следующая семантика.
Переменная-отношение S представляет поставщиков. Каждый поставщик имеет
уникальный номер (S#); имя (SNAME), необязательно уникальное (хотя оно может
быть уникальным, как в случае, представленном на рис. 3.8); значение рейтинга
или статуса (STATUS); место расположения (CITY). Предполагается, что каждый
поставщик находится только в одном городе.
Переменная-отношение Р представляет детали (точнее, виды деталей). У каждого
вида детали есть номер детали (Р#), который является уникальным; название дета-
ли (PNAME); цвет (COLOR); вес (WEIGHT); город, где хранится этот вид деталей (CITY).
Предполагается (где это имеет значение), что вес детали приведен в фунтах. Так-
же предполагается, что каждый отдельный вид детали имеет только один цвет и
хранится на складе только в одном городе.
Глава 3. Введение в реляционные базы данных
111
Переменная-отношение SP представляет поставки. Она в известном смысле слу-
жит для организации логической связи двух других переменных-отношений. На-
пример, первая строка переменной-отношения SP на рис. 3.8 связывает поставщика
с номером ' S1' из переменной-отношения S с соответствующей деталью, имеющей
номер 'Р1' в переменной-отношении Р, т.е. представляет факт поставки деталей
типа ' Р1' поставщиком с номером ' S1' (а также указывает количество деталей —
300 штук). Таким образом, каждая поставка характеризуется номером поставщика
(S#), номером детали (Р#) и количеством (QTY). Предполагается, что в одно и то же
время может быть не более одной поставки для одного поставщика и одной
детали, поэтому для каждой поставки комбинация значений столбцов S# и P# уни-
кальна с точки зрения набора текущих поставок, представленных в переменной-
отношении SP.
Замечание. На рис. 3.8 умышленно показано одно значение поставщика (с номе-
ром ' S5'), для которого не существует ни одной поставки.
TYPE S# ... ;
TYPE NAME ... ;
TYPE P# ... ;
TYPE COLOR ... ;
TYPE WEIGHT ... ;
TYPE QTY ... ;
VAR S BASE RELATION
{ s# s#,
SNAME NAME,
STATUS INTEGER,
CITY CHAR }
PRIMARY KEY { S# } ,-
VAR P BASE RELATION
{ P# P#,
PNAME NAME,
COLOR COLOR,
WEIGHT WEIGHT,
CITY PRIMARY CHAR } KEY { P# } ;
SP BASE RELATION
{ S# s#,
P# Р»,
QTY QTY }
PRIMARY KEY { S#( , p# }
FOREIGN KEY { S# } REFERENCES S
FOREIGN KEY { P# } REFERENCES P ;
Рис. 3.9. База данных поставщиков и деталей (определение данных)
112
Часть I. Основные понятия
Как отмечалось выше (в главе 1, раздел 1.3), детали и поставщиков можно рассмат-
ривать как сущности, а поставку — как связь между определенным поставщиком и оп-
ределенной деталью. Однако в том же разделе было указано, что связи можно понимать
как особый вид сущностей. Одно из преимуществ реляционных баз данных состоит
именно в том, что все сущности, независимо от того, что на самом деле они могут яв-
ляться связями, представляются одним универсальным способом, а именно — с помо-
щью строк, объединенных в отношения, как показано в нашем примере.
И еще пара последних замечаний.
Во-первых, наша база данных поставщиков и деталей исключительно проста, го-
раздо проще любой реальной базы данных, которая может встретиться на практи-
ке. Большинство реальных баз данных включает значительно больше сущностей и
связей (и намного больше видов сущностей и связей). Но несмотря на это предло-
женный здесь простой пример вполне подходит для иллюстрации большинства
вопросов, обсуждаемых в оставшейся части книги, и (как уже отмечалось) будет
использоваться как основа для большинства (но не для всех) примеров в несколь-
ких последующих главах.
Во-вторых, безусловно, не было бы ошибкой, если бы мы использовали более
описательные названия переменных-отношений, подобные SUPPLIERS (постав-
щики), PARTS (детали) и SHIPMENTS (поставки), вместо сокращенных названий S, Р
и SP. Более того, на практике рекомендуется использовать именно такие описа-
тельные названия. Однако в нашем конкретном случае в последующих главах на-
звания этих переменных-отношений будут употребляться так часто, что целесооб-
разнее использовать именно короткие названия. Многократно употребляемые
длинные названия зачастую способны вызвать раздражение.
3.10. Резюме
На этом завершается краткий обзор реляционной технологии. Конечно, мы коснулись
лишь вершины айсберга, ставшего сегодня весьма обширным предметом изучения, но,
как уже отмечалось, назначение данной главы — введение в более расширенное обсуж-
дение, которое проводится далее. Однако несмотря на это нам удалось охватить немалую
часть материала. Подведем итог обсуждению затронутых тем.
Реляционная база данных — это такая база данных, которая воспринимается ее
пользователями как множество переменных, значениями которых являются отношения
(т.е. переменных-отношений— relvars) или, менее формально, таблиц. Реляционная
система — это система, которая поддерживает реляционные базы данных и операции
над ними, включая, в частности, операцию выборки строк RESTRICT (иначе называемую
SELECT), операцию выборки столбцов PROJECT (также называемую проекцией) и опера-
цию соединения таблиц JOIN. Эти и подобные им операции выполняются на уровне
множеств. Свойство замкнутости реляционных систем означает, что результат выпол-
нения операции имеет тот же тип, что и объекты, над которыми проводилась операция
(все они являются отношениями). А это, в свою очередь, позволяет использовать вло-
женные реляционные выражения. Значения переменных-отношений изменяются с
помощью операций реляционного присвоения, причем привычные нам операции об-
новления INSERT, UPDATE и DELETE можно считать сокращенной формой записи опера-
ций реляционного присвоения определенных типов.
Глава 3. Введение в реляционные базы данных
113
Формальная теория, положенная в основу реляционных систем, называется реля-
ционной моделью данных. Реляционная модель изучает материал только на логиче-
ском уровне и не затрагивает физический уровень. В модели рассматриваются три
принципиальных аспекта данных — их структура, сохранение их целостности и ма-
нипулирование данными. Структурный аспект касается собственно отношений, ас-
пект целостности имеет отношение (помимо всего прочего) к первичным и внеш-
ним ключам, а аспект манипулирования данными связан с операторами (RESTRICT,
PROJECT, JOIN и т.д.). Информационный принцип утверждает, что все информацион-
ное содержимое реляционной базы данных должно быть представлено одним и только
одним способом, а именно — явным заданием значений, помещенных в позиции
столбцов в строках отношений.
Каждое отношение имеет заголовок и тело; заголовок— это набор пар “имя-
столбца:имя-типа”, а тело отношения состоит из набора строк, которые соответствуют
заголовку. Заголовок любого отношения можно рассматривать как предикат, а каж-
дую строку в теле отношения — как некоторое истинное высказывание, образован-
ное в результате подстановки определенных значений аргументов соответствующего
типа вместо местодержателей или параметров этого предиката. Другими словами,
типы — это что-то (множество чего-то), что мы можем обсуждать, а отношения — это
то (множество чего-то), что мы можем сказать о том, что мы можем обсуждать. И ти-
пы, и отношения необходимы и достаточны для представления любых данных (на
логическом уровне).
Оптимизатор — это компонент системы, определяющий, как именно будут реали-
зованы запросы пользователей (которые указывают, что делать, а не как делать). Та-
ким образом, на реляционные системы возложена ответственность за навигацию по
хранимой базе данных для поиска требуемых данных. Подобные системы иногда на-
зывают системами с автоматической навигацией. Оптимизация и автоматическая
навигация являются основой для достижения реальной независимости от физическо-
го представления данных.
Каталог — это набор системных переменных-отношений, содержащих метаданные
о различных элементах, важных для системы (базовых переменных-отношениях, пред-
ставлениях, индексах, пользователях и т.д.). Пользователи могут опрашивать каталог те-
ми же методами, которые они применяют для доступа к собственным данным.
Исходные переменные-отношения в некоторой базе данных называются базовы-
ми переменными-отношениями, а их значения называются базовыми отноше-
ниями. Отношение, которое получено из таких базовых отношений путем вычисле-
ния некоторого реляционного выражения, называется производным (базовые и
производные отношения иногда называют представимыми отношениями). Пред-
ставление — это переменная-отношение, значение которой в любой данный момент
является некоторым производным отношением (нестрого говоря, представление
можно рассматривать как производную переменную-отношение). Значение такой
переменной-отношения в любой данный момент представляет собой результат вы-
числения соответствующего реляционного выражения, определяющего это пред-
ставление. Поэтому можно сказать, что базовые переменные-отношения существу-
ют независимо, а представления — нет, поскольку они зависят от соответствующих
базовых переменных-отношений. (Это можно сформулировать и иначе: базовые пе-
ременные-отношения автономны, а представления — нет.) Пользователь может
114
Часть I. Основные понятия
оперировать представлениями практически так же, как и базовыми переменными-
отношениями (по крайней мере, теоретически). Система выполняет операции над
представлениями, заменяя ссылку на название представления определяющим его
выражением, т.е. преобразуя операцию над представлением в соответствующую
операцию над базовыми переменными-отношениями.
Транзакция — это логическая единица работы, которая обычно включает выполнение
нескольких операций базы данных. Выполнение транзакции начинается с выполнения опе-
ратора BEGIN TRANSACTION и завершается выполнением оператора COMMIT (нормальное за-
вершение) или ROLLBACK (аварийное завершение). Транзакции обладают свойствами ато-
марности, продолжительности и изолированности одна от другой. При чередующемся
выполнении операций нескольких параллельно обрабатываемых транзакций обычно гаран-
тируется, что выполнение этих операций будет упорядоченным.
И наконец, в данной главе приведен основной пример книги — база данных поставщи-
ков и деталей. Рекомендуется ознакомиться с ним именно сейчас, если вы еще не сделали
этого. Необходимо знать по крайней мере, какие в этой базе данных существуют столбцы и в
каких переменных-отношениях, а также какие внешние и первичные ключи для них опреде-
лены. (Безусловно, конкретные значения в таблицах не имеют большого значения.)
Упражнения
3.1.
Дайте определения следующим терминам.
автоматическая навигация
базовая переменная-отношение
внешний ключ
выборка строк
высказывание
замкнутость
каталог
операции на уровне множеств
оптимизация
откат
первичный ключ
предикат
представление
проекция
производная переменная-отношение
реляционная база данных
реляционная модель
реляционная СУБД
соединение
фиксация транзакции
3.2. Опишите содержимое переменных-отношений каталога TABLE и COLUMN для базы
данных поставщиков и деталей.
3.3. Как пояснялось в разделе 3.6, каталог должен описывать самого себя, т.е. включать
записи о переменных-отношениях самого каталога. Дополните рис. 3.6 так, чтобы
он включал необходимые записи о самих переменных-отношениях TABLE и COLUMN.
3.4. Вот запрос для базы данных поставщиков и деталей.
RESULT := ( ( S JOIN SP ) WHERE P# = 'P2' ) { S#, CITY } ;
Что получится в результате его выполнения?
Замечание. Здесь может возникнуть небольшое затруднение, касающееся типа дан-
ных столбца Р#. Мы возвратимся к этому вопросу в разделе 5.2 главы 5 (подраздел
“Домены”). Аналогичное замечание относится и к следующему упражнению.
Глава 3. Введение в реляционные базы данных
115
3.5. Предположим, что выражение, расположенное в запросе из упр. 3.4 справа, ис-
пользуется для определения представления.
CREATE VIEW V AS
( ( S JOIN SP ) WHERE P# = 'P2' ) { Si, CITY } ;
Теперь рассмотрим следующий запрос.
RESULT := ( V WHERE CITY = 'London' ) { S# } ;
Что получится в результате его выполнения? Поясните, какой компонент исполь-
зуется со стороны СУБД при выполнении запроса.
3.6. Как вы понимаете термины, характеризующие свойства транзакций: атомарность,
продолжительность, изолированность и упорядоченность выполнения операций
параллельных транзакций.
Список литературы
3.1. Codd E.F. Relational Database: A Practical Foundation for Productivity // CACM. —
February, 1982.— 25, №2. (Переиздано: Robert L. Ashenhurst (ed.). ACM Turing
Award Lectures: The First Twenty Years 1966-1985.— Reading, Mass.:
Addison-Wesley, 1989.)
Статья была представлена Коддом на соискание награды ACM Turing Award в
1981 году. В ней обсуждается хорошо известная проблема отставания разработ-
ки приложений. Перефразируя ее, можно сказать: “Потребности в приложениях
для компьютеров быстро возрастают — настолько быстро, что отделы информаци-
онных систем (которые несут ответственность за написание приложений) отстают
от них все больше и больше”. Существует два дополнительных метода разрешения
этой проблемы.
1. Предоставить специалистам по информационным технологиям новые средства
для повышения продуктивности их работы.
2. Предоставить пользователям возможность доступа непосредственно к базе дан-
ных, полностью игнорируя специалистов по информационным технологиям.
Оба подхода необходимо развивать, причем в предлагаемой статье Кодда приво-
дится обоснование того, что основу для обоих этих подходов дает применение ре-
ляционной технологии.
3.2. Date C.J. Why Relational? // С.J. Date. Relational Database Writings 1985-1989.—
Reading, Mass.: Addison-Wesley, 1990.
Попытка предоставить краткую, но достаточно основательную сводку основных
преимуществ реляционного подхода. Приведем следующее высказывание из ста-
тьи: “Среди многочисленных преимуществ реляционного подхода существует
одно, которое следует особо подчеркнуть: наличие солидной теоретической
базы”. Цитирую:
“...реляционная действительно является иной. Она отличается тем, что не является
произвольной. Прежние же системы, напротив, имели произвольно выбранную ор-
ганизацию; они предоставляли решения для определенных задач того времени, но
116
Часть I. Основные понятия
у них не было твердой теоретической базы, тогда как у реляционных систем такая
база есть... а это означает, что [они] надежны, как скала”.
“Благодаря этому твердому основанию поведение реляционных систем отли-
чается предсказуемостью и пользователь (возможно, не осознавая этого) дер-
жит в голове простую модель этого поведения, позволяющую ему предвидеть,
что сделает система в той или иной ситуации. Сюрпризов быть не может (или
не должно быть). Предопределенность означает, что пользовательский интер-
фейс прост для понимания, документирования, обучения, изучения, использо-
вания и запоминания.”
3.3. Date C.J. and Hugh Darwen. Foundation for Object/Relational Databases: The third
manifesto. — Reading, Mass.: Addison-Wesley, 1998. Также см. вводный обзор ста-
тьи “The third manifesto: Foundation for Object/Relational Databases” в издании Date
C.J., Hugh Darwen, David McGoveran. Relational Database Writings 1994-1997.—
Reading, Mass.: Addison-Wesley, 1998.
Третий манифест — это детализированное, формальное и подробное предложе-
ние будущих направлений развития СУБД. Манифест можно рассматривать как
абстрактный план проектирования СУБД и языка этой СУБД. Данный план ос-
нован на классических фундаментальных понятиях тип, значение, переменная
и оператор. Например, у нас может быть тип INTEGER; целое число “3” может
быть значением этого типа; N может быть переменной этого типа, значение ко-
торой в каждый момент — это некоторое целое значение (т.е. некоторое значе-
ние этого типа); знак “+” может быть оператором, применяемым к целым значе-
ниям (т.е. к значениям этого типа).
Ответы к некоторым упражнениям
3.3. На рис. 3.10 показаны строки таблиц TABLES и COLUMNS (остальные строки, описы-
вающие пользовательские таблицы, пропущены). Понятно, что дать точные значе-
ния в столбцах COLCOUNT и ROWCOUNT невозможно.
TABLES COLUMNS TABNAME COLCOUNT ROWCOUNT
TABLES COLUMNS (>3) (>2) (>2) (>5) .....
TABNAME COLNAME
TABLES TABLES TABLES COLUMNS COLUMNS TABNAME COLCOUNT ROWCOUNT TABNAME COLNAME
Рис. 3.10. Записи каталога для самих переменных-отношений TABLES и COLUMNS
(схематически)
Гл$ва 3. Введение в реляционные базы данных
117
3.4. Запрос предназначен для выбора номеров и городов тех поставщиков, которые по-
ставляют деталь с номером 'Р2'.
3.5. Значение этого запроса следующее: “Выбрать номер поставщика из Лондона, по-
ставляющего деталь с номером ' Р2'”. Первый шаг при выполнении запроса
(замена имени V значением, определяющим переменную-отношение V) дает
следующее.
( ( ( ( S JOIN SP ) WHERE P# = 'P2' ) { S#, CITY } )
WHERE CITY = 'London' ) { S# }
Это выражение можно упростить.
( ( S WHERE CITY = 'London' ) JOIN ( SP WHERE P# = 'P2' ) ) { S# }
Объяснение и дальнейшее обсуждение правил построения подобных выражений
приводятся в главах 9 и 17.
118
Часть I. Основные понятия
Глава 4
Введение в язык SQL
4.1. Введение
Как отмечалось в главе 1, SQL является стандартным языком для работы с реляцион-
ными базами данных и в настоящее время поддерживается практически всеми продукта-
ми, представленными на рынке. Он был разработан в компании IBM Research в начале
1970-х годов [4.8], [4.9], [4.28]. Первой серьезной реализацией этого языка был продукт-
прототип System R компании IBM [4.1]—[4.3], [4.11]—[4.13]; впоследствии он был реали-
зован в многочисленных коммерческих продуктах как компании IBM [4.20], так и других
изготовителей. В этой главе представлено введение в язык SQL, а дополнительные ас-
пекты, касающиеся таких вопросов, как целостность, защита и т.п., обсуждаются в по-
следующих главах, специально посвященных этим темам. При обсуждении языка мы бу-
дем основываться (если не утверждается противное) на текущем стандарте, неформально
называемом SQL/92 (иначе — SQL-92 или просто SQL2 [4.22], [4.23]). Его официальное
название— Международный стандарт языка баз данных SQL (1992) (International
Standard Database Language SQL).
Замечание. Необходимо сразу же добавить, что разработка следующего нового стандарта
SQL3 близится к завершению и его утверждение ожидается в конце 1999 года. К этому вре-
мени данная книга уже появится в продаже и текущий стандарт, возможно, будет называться
SQL/99, а не SQL/92. Однако мы сочли, что, если при обсуждении языка основываться на еще
не утвержденном стандарте SQL3, это может привести к недоразумениям, поскольку совер-
шенно очевидно, что ни один продукт еще не поддерживает данный стандарт. Поэтому мы
решили рассмотреть стандарт SQL3 отдельно, в приложении Б. Во всяком случае, и это необ-
ходимо отметить, ни один из коммерческих продуктов к моменту написания книги не под-
держивал в полной мере даже стандарт SQL/921. Те языки, которые обычно поддерживаются
отдельными продуктами, можно назвать “надмножествами подмножества” языка SQL/92.
Другими словами, любой продукт, не поддерживающий некоторых аспектов стандарта, в дру-
гих отношениях, возможно, превосходит его. Например, СУБД IBM DB2, безусловно, не под-
держивает всех функциональных возможностей, предусмотренных стандартом SQL/92 в от-
ношении обеспечения целостности данных, тем не менее она превосходит стандарт в отноше-
нии правил, связанных с обновлением представлений.
И еще несколько предварительных замечаний.
Язык SQL первоначально разрабатывался конкретно как подъязык данных. Одна-
ко после включения в стандарт в конце 1996 года такого средства, как постоянные
хранимые модули (Persistent Stored Modules — PSM), язык стал полностью вычис-
1 На самом деле ни один из продуктов, по-видимому, и не смог бы поддерживать в полной ме-
ре стандарт SQL/92, поскольку в этом стандарте на сегодняшний день содержится множество
расхождений, ошибок и противоречий. Подробно этот вопрос рассматривается в [4.19].
Глава 4. Введение в язык SQL
119
лительным (и сейчас в нем имеются процедурные операторы, например CALL,
RETURN, SET, CASE, IF, LOOP, LEAVE, WHILE, REPEAT, а также несколько связанных с
ними функциональных возможностей, например можно использовать переменные
и обработчики исключительных ситуаций). Поэтому во многих случаях отпала не-
обходимость в объединении SQL с каким-то отдельным “основным” языком для
разработки полнофункционального приложения. Однако в этой книге возможно-
сти PSM рассматриваться не будут.
Вас не должно удивлять, что в языке SQL вместо терминов отношение и перемен-
ная-отношение используется термин таблица (см. главу 3). Именно этот термин
используется стандартом языка SQL и поддерживающими его продуктами, поэто-
му в соответствии с ними мы будем использовать указанный термин в данной гла-
ве (и везде, где пойдет речь о языке SQL). Кроме того, в языке SQL не употребля-
ются термины заголовок и тело (таблицы или отношения).
Необходимо подчеркнуть, что SQL — язык очень большого объема. Документ по
его стандарту [4.22] содержит свыше 600 страниц (а описание стандарта SQL3 —
в два раза больше). Поэтому в книге, подобной этой, невозможно дать исчерпы-
вающее описание языка. Достаточно полно мы сможем рассмотреть лишь самые
важные его аспекты. Хотелось бы предупредить читателя, что приведенное здесь
описание языка во многих случаях беглое и поверхностное. В частности, мы, не
колеблясь, опустили материал, не относящийся непосредственно к обсуждаемой
теме, и для краткости сделали существенные упрощения. Более полное (но также
учебное) описание языка SQL можно найти в [4.4], [4.19] и [4.27].
И наконец, нельзя не сказать о том (как уже неоднократно отмечалось в предыду-
щих главах), что языку SQL еще очень далеко до совершенного реляционного
языка. В нем много недостатков, появившихся в результате как недоделок, так и
переделок. Однако как бы там ни было, это — стандарт, он поддерживается прак-
тически всеми продуктами, представленными на рынке, и поэтому каждый спе-
циалист по базам данных должен быть знаком с этим языком, по крайней мере в
том объеме, который охватывает эта книга.
4.2. Обзор языка SQL
В языке SQL имеются операции как определения данных, так и манипулирования ими.
Сначала мы познакомимся с операциями определения данных. На рис. 4.1 показано, как с
помощью средств языка SQL определяется база данных поставщиков и деталей (ср. с
рис. 3.9 в главе 3). Как можно видеть, определение включает один оператор CREATE TABLE
для каждой базовой таблицы (как указывалось в главе 3, ключевое слово TABLE в операторе
CREATE TABLE обозначает именно базовую таблицу). Каждый оператор CREATE TABLE задает
имя создаваемой базовой таблицы, имена и типы данных столбцов этой таблицы, а также
первичный ключ таблицы и любые внешние ключи, присутствующие в ней (кроме того,
может быть указана другая дополнительная информация, которая не показана на рис. 4.1).
Приведем еще пару замечаний по синтаксису.
Обратите внимание, что символ который мы часто используем в именах
столбцов, на самом деле в стандарте SQL/92 недопустим.
120
Часть I. Основные понятия
В качестве признака конца оператора мы здесь используем символ хотя соглас-
но стандарту SQL/92 выбор используемого для этой цели символа зависит от реали-
зации. Детальное рассмотрение данного вопроса выходит за рамки этой книги.
CREATE TABLE S
( Si CHAR(5),
SNAME CHAR(20),
STATUS NUMERIC(5),
CITY CHAR(15),
PRIMARY KEY ( Si ) ) ;
CREATE TABLE P
( Pi CHAR(6),
PNAME CHAR(20),
COLOR CHAR(6),
WEIGHT NUMERIC(5,1),
CITY CHAR(15),
PRIMARY KEY ( Pi ) ) ;
CREATE TABLE SP
( Si CHAR(5),
Pi CHAR(6),
QTY NUMERIC(9),
PRIMARY KEY ( Si, Pi ),
FOREIGN KEY ( Si ) REFERENCES S,
FOREIGN KEY ( Pi ) REFERENCES P ) ;
Puc. 4.1. Определение базы данных поставщиков и деталей средствами языка SQL
Одно из важных отличий между рис. 4.1 и его аналогом (рис. 3.9) в главе 3 состоит в
том, что на рис. 4.1 нет ничего, соответствующего определениям типов (т.е. операторов
TYPE). И причина этого, конечно, заключается в следующем: в языке SQL пользователю
не разрешается определять собственные типы2. Поэтому для определения столбцов мож-
но использовать только встроенные (определенные системой) типы. В языке SQL под-
держиваются следующие встроенные типы, которые фактически не требуют дополни-
тельных разъяснений.
CHARACTER [ VARYING ] (n) INTEGER DATE
BIT [ VARYING ] (л) SMALLINT TIME
NUMERIC (p,q) DECIMAL (p,g) FLOAT (p) TIMESTAMP INTERVAL
i
2 В языке SQL/92 разрешается определять собственные типы для так называемых доменов,
однако эти “домены” на самом деле — не домены (т.е. типы) в реляционном смысле (см. подроб-
ности приводятся в главе 5). Замечание. Определяемые пользователем типы данных поддержи-
ваются стандартом SQL3 (приложение Б).
Глд.ва 4. Введение в язык SQL
121
В языке SQL поддерживается множество значений, принимаемых по умолчанию, со-
кращений и альтернативных написаний. Например, существует сокращение CHAR для опре-
делителя CHARACTER. Квадратные скобки “[” и в принятой нотации используются для
указания необязательных элементов (например, CHARACTER или BIT), при отсутствии кото-
рых будут использованы значения по умолчанию. (Это правило обычно подразумевается
при описании в форме Бэкуса-Наура, сокращенно — BNF). И наконец, отметим, что в язы-
ке SQL требуется указывать конкретную длину или точность для определенных типов
(например, CHAR) в отличие от нашего гипотетического синтаксиса, использовавшегося в
главе 3. Очевидно, что язык SQL рассматривает эти длины и спецификаторы точности как
часть определения типа (подразумевая, например, что значения CHAR (3) и CHAR (4) задают
разные типы). Однако мы считаем, что лучше расценивать их (длины и точности) как огра-
ничения целостности (что мы и делаем, в частности, в главе 8, упр. 8.4).
Определив базу данных, можно начинать выполнять в ней различные операции, зада-
ваемые с помощью операторов манипулирования данными языка SQL: SELECT, INSERT,
UPDATE и DELETE. В частности, можно выполнять с данными реляционные операции выбор-
ки, проекции и соединения, причем во всех этих случаях следует использовать один и тот
же оператор манипулирования данными языка SQL SELECT. На рис. 4.2 показаны примеры
операций выборки проекции и соединения, сформулированные на языке SQL.
Выборка (RESTRICT): Результат: SELECT S#, Р#, QTY FROM SP S# P# QTY
SI S2 P5 P6 100 100
WHERE QTY < 150 ;
Проекция (PROJECT): Результат: S# CITY
SELECT S#, CITY SI London
FROM S ; S2 Paris
S3 Paris
S4 London
S5 Athens
Соединение (JOIN):
SELECT S.S#, SNAME, STATUS, CITY, P#, QTY
FROM S, SP
WHERE S.S# = SP.S# ;
Результат: S# SNAME STATUS CITY P# QTY
SI Smith 20 London Pl 300
SI Smith 20 London P2 200
SI Smith 20 London P3 400
S4 Clark 20 London P5 400
Puc. 4.2. Примеры выполнения операций выборки, проекции и соединения на языке SGL
122
Часть I. Основные понятия
Замечание. Пример операции соединения на этом рисунке подтверждает, что в языке
SQL иногда необходимо использовать уточненные имена (например, S.S#, SP.S#), по-
зволяющие устранить неоднозначность при указании столбцов. Согласно общему прави-
лу уточненные имена допустимы всегда, а неуточненные имена допустимы, только если
при этом не возникает неоднозначности.
Отметим, что в языке SQL поддерживается сокращенная форма предложения SELECT,
как показано в следующем примере.
SELECT * — или SELECT S.* (т.е. символ может быть уточнен)
FROM S ;
В результате выполнения этого запроса будет получена копия всей таблицы S. Символ
“*” — это сокращение для списка разделенных запятыми имен всех столбцов таблицы, ука-
занной в предложении FROM. Имена столбцов перечисляются слева направо в том порядке, в
котором они определены в этой таблице. Кстати, обратите внимание на комментарий, ко-
торый начинается двумя дефисами и заканчивается символом новой строки.
Замечание. Выражение SELECT * FROM Т, где Т— это имя таблицы, может быть со-
кращено до простого выражения TABLE Т.
Значительно подробнее оператор SELECT обсуждается в главе 7 (раздел 7.7).
Перейдем к операциям обновления. Примеры операций INSERT, UPDATE и DELETE языка
SQL приводились в главе 1. Однако во всех примерах этой главы использовались операции
обработки отдельных строк. Тем не менее операции INSERT, UPDATE и DELETE, как и опера-
ция SELECT, обрабатывают данные на уровне множеств (некоторые упражнения и ответы к
ним в главе 1 действительно демонстрировали эту возможность). Вот несколько примеров
обновления на уровне множеств для базы данных поставщиков и деталей.
INSERT
INTO TEMP ( Р#, WEIGTH )
SELECT P#, WEIGTH
FROM P
WHERE COLOR = 'Red' ;
В этом примере подразумевается, что предварительно создана другая таблица TEMP с
двумя столбцами: P# и WEIGTH. Оператор INSERT вставляет в нее номера деталей и соот-
ветствующие веса всех деталей с цветом 'Red' (красный).
UPDATE S
SET STATUS = STATUS * 2
WHERE CITY = 'Paris' ;
Приведенный выше оператор UPDATE удваивает статус всех поставщиков в Париже.
DELETE
FROM SP
WHERE P# = 'P2' ;
Этот оператор DELETE удаляет из таблицы SP все строки с информацией о детали с
номером 'Р2'.
Глава 4. Введение в язык SQL
123
Замечание. В язык SQL не включен прямой аналог операции реляционного при-
своения. Но можно имитировать эту операцию, сначала удалив все строки из целевой
таблицы, а затем выполнив для нее операции INSERT ... SELECT ... (как это сделано вы-
ше, в первом примере).
4.3. Каталог
В языке SQL существует аналог того, что принято называть каталогом, — инфор-
мационная схема. Знакомые нам термины “каталог” и “схема” действительно исполь-
зуются в языке SQL, но с особым, специфическим только для языка SQL смыслом. Не-
строго говоря, каталог в языке SQL состоит из дескрипторов (метаданных) для от-
дельной базы данных3, а схема состоит из дескрипторов той части базы данных, кото-
рая принадлежит отдельному пользователю. Другими словами, в системе может быть
любое число каталогов (по одному для каждой базы данных), каждый из которых де-
лится на произвольное число схем. Однако каждый каталог должен содержать ровно
одну схему с именем INFORMATION_SCHEMA (информационная схема), которая, с точки
зрения пользователя, и является схемой (как уже указывалось), выполняющей функции
обычного каталога.
Таким образом, информационная схема состоит из набора SQL-таблиц, содержи-
мое которых фактически отражает (точно определенным образом) все определения
из всех остальных схем рассматриваемого каталога. Точнее говоря, информацион-
ная схема по определению содержит набор представлений гипотетической “схемы
определения”. Для поддержки схемы определения реализация не требуется, но она
требуется, во-первых, для поддержки некоторого вида “схемы определения” и, во-
вторых, для поддержки представлений такой “схемы определения”, которые имеют
вид, подобный представлениям информационной схемы. Необходимо отметить сле-
дующие моменты.
1. Основная причина того, что требования состоят из двух отдельных требований,
сформулированных выше, заключается в следующем. Существующие продукты,
конечно, поддерживают нечто близкое к “схеме определения”. Однако от одного
продукта к другому диапазон различий таких схем будет очень широким (даже ес-
ли эти продукты имеют одного изготовителя). Поэтому требование лишь того, что-
бы в реализации поддерживались предопределенные представления “схемы опре-
деления”, имеет смысл.
2. На самом деле нужно говорить “одна из информационных схем”, а не просто
“информационная схема”, поскольку, как мы убедились, в каждом каталоге имеет-
ся такая схема. Поэтому в общем случае все данные, которые доступны некоторому
пользователю, не будут описаны с помощью единственной информационной схе-
мы. Однако, чтобы упростить изложение материала, мы будем продолжать считать,
что в действительности существует только одна схема.
3 В интересах точности необходимо отметить, что в стандарте языка SQL такое понятие,
как “база данных”, в действительности просто отсутствует! По определению каталогом опи-
сывается то, что называется набором данных и зависит от реализации Однако нет никаких ра-
зумных аргументов, запрещающих подразумевать под этим понятием базу данных.
124
Часть I. Основные понятия
Нет причин вдаваться здесь в детали содержимого информационной схемы. Просто
приведем некоторые из наиболее важных представлений информационной схемы в на-
дежде на то, что сами названия позволят читателю получить некоторое понятие о содер-
жимом этих представлений. Следует также отметить, что представление TABLES содер-
жит информацию обо всех именованных таблицах, как базовых таблицах, так и пред-
ставлениях, в то время как представление VIEWS содержит информацию только о пред-
ставлениях. В [4.19] этот вопрос рассмотрен более подробно, в частности в этой работе
рассказывается, как формулировать запросы для получения данных из информационной
схемы (что не так просто, как можно было бы ожидать).
SCHEMATA
(схемы)
DOMAINS
(домены)
TABLES
(таблицы)
VIEWS
(представления)
COLUMNS
(столбцы)
TABLE-PRIVILEGES
(привилегии для таблиц)
COLUMN-PRIVILEGES
(привилегии для столбцов)
USAGE_PRIVILEGES
(применяемые привилегии)
DOMAIN-CONSTRAINTS
(ограничения для домена)
TABLE-CONSTRAINTS
(ограничения для таблицы)
REFERENTIAL-CONSTRAINTS
(ссылочные ограничения)
CHECK-CONSTRAINTS
(проверочные ограничения)
KEY_COLUMN_USAGE
(использование столбца ключа)
ASSERTIONS
(утверждения)
VIEW_TABLE-USAGE
(использование таблицы представления)
VIEW_COLUMN_USAGE
(использование столбца представления)
CONSTRAINT_TABLE_USAGE
(использование таблицы ограничений)
CONSTRAINT_COLUMN_USAGE
(использование столбца ограничения)
CONSTRAINT_DOMAIN_USAGE
(использование домена ограничения)
4.4. Представления
Приведем пример определения представления на языке SQL.
CREATE VIEW GOOD_SUPPLIER
AS SELECT S#, STATUS, CITY
FROM S
WHERE STATUS > 15 ;
А вот пример SQL-запроса к этому представлению.
SELECT S#, STATUS
FROM GOOD_SUPPLIER
WHERE CITY = 'London' ;
Глава 4. Введение в язык SQL
125
Подставив определение представления вместо ссылки на имя представления, получим
выражение, которое будет подобно приведенному ниже (обратите внимание на вложен-
ный подзапрос в предложении FROM).
SELECT GOOD_SUPPLIER.S#, GOOD_SUPPLIER.STATUS
FROM ( SELECT S#, STATUS, CITY
FROM S
WHERE STATUS > 15 ) AS GOOD_SUPPLIER
WHERE GOOD_SUPPLIER.CITY = 'London' ;
Это выражение может быть затем упрощено, например, так.
SELECT S#, STATUS
FROM S
WHERE STATUS > 15
AND CITY = 'London' ;
В последнем случае показан текст запроса, который фактически будет выполняться.
В качестве второго примера рассмотрим следующую операцию DELETE.
DELETE
FROM GOOD_SUPPLIER
WHERE CITY = 'London' ;
Запрос на удаление, который будет выполняться на самом деле, выглядит так.
DELETE
FROM S
WHERE STATUS > 15
AND CITY = 'London' ;
4.5. Транзакции
Для операторов COMMIT и ROLLBACK в языке SQL есть прямые аналоги. Это операторы
COMMIT WORK и ROLLBACK WORK соответственно (в обоих операторах слово WORK необяза-
тельное). Но в языке SQL нет явного оператора, соответствующего оператору BEGIN
TRANSACTION. Неявно транзакция начинается всякий раз, когда программа выполняет
оператор, способный “инициализировать транзакцию” (transaction-initiating), но только в
том случае, когда никакая транзакция еще не выполняется. Рассматривать здесь список
SQL-операторов, способных инициализировать транзакцию, в наши планы не входит.
Достаточно сказать, что таковыми являются практически все операторы, которые мы об-
суждаем в этой главе (кроме, конечно, самих операторов COMMIT и ROLLBACK).
4.6. Внедрение SQL-операторов
В большинстве SQL-продуктов операторы языка SQL могут выполняться как непосред-
ственно (т.е. интерактивно, с подключенного терминала), так и в виде части прикладной
программы (т.е. SQL-операторы могут быть внедренными, а значит, могут смешиваться с
126
Часть I. Основные понятия
операторами базового языка этой программы). Приложения, использующие внедренные
SQL-операторы, могут быть написаны на многих базовых языках: COBOL, Java, PL/I и т.д.4
Рассмотрим особенности технологии внедрения SQL-операторов более подробно.
Фундаментальный принцип, лежащий в основе технологии внедрения SQL-
операторов, мы будем называть принципом двухрежимности. Он заключается в том,
что любое SQL-выражение, которое можно использовать интерактивно, можно при-
менять и в прикладной программе. Конечно, существует множество различий в деталях
между интерактивными SQL-операторами и их внедренными аналогами. В частности,
операции выборки требуют существенной дополнительной обработки в вычислительной
среде базового языка (подробности приводятся ниже в этом же разделе). Тем не менее
сам принцип двухрежимности всегда соблюдается. (Обратное правило, между прочим,
не верно, т.е. существует несколько внедряемых SQL-операторов, которые не могут ис-
пользоваться интерактивно, в чем мы вскоре убедимся.)
Прежде чем начать обсуждение конкретных внедряемых SQL-операторов, необходи-
мо обсудить некоторые детали. Большинство из них иллюстрируется фрагментом про-
граммы, представленным на рис. 4.3. (Для закрепления наших представлений будем счи-
тать, что базовым языком является PL/I. Большинство приводимых примеров транслиру-
ется на другие базовые языки лишь с незначительными изменениями.)
EXEC SQL BEGIN DECLARE SECTION ;
DCL SQLSTATE CHAR(5) ;
DCL P# CHAR(6) ;
DCL WEIGHT FIXED DECIMAL(5,1) ;
EXEC SQL END DECLARE SECTION ;
P# = 'P2' ; /* например */
EXEC SQL SELECT P.WEIGHT
INTO :WEIGHT
FROM P
WHERE P.P# = :P# ;
IF SQLSTATE = '00000'
THEN ; /* WEIGHT = <выбираемое значение> */
ELSE ... ; /* возникла какая-то исключительная ситуация */
Рис. 4.3. Фрагмент программы на языке PL/I с внедренными операторами языка SQL
Рассмотрим все по порядку.
1. Внедренные SQL-операторы предваряются инструкцией EXEC SQL, так что их лег-
ко отличить от других операторов базового языка, и заканчиваются специальным
завершающим символом (точка с запятой для языка PL/I).
4 Стандарт языка SQL [4.22] в настоящее время поддерживает языки Ada, С, COBOL,
Fortran, М (раньше он назывался MUMS), Pascal и PL/I. Требование поддержки языка Java на
время написания книги еще отсутствовало, но должно было быть добавлено в ближайшее время
(подробности приводятся в [4.6], а также в приложении Б), причем некоторые продукты уже
поддерживают язык Java.
Глава 4. Введение в язык SQL
127
2. Выполняемый SQL-оператор (далее до конца этого раздела уточнение
“внедренный” обычно будет опускаться) может быть в программе везде, где могут
быть выполняемые операторы базового языка. Обратите внимание на уточнение
“выполняемые”: в отличие от интерактивного режима использования языка SQL,
режим внедрения SQL-операторов подразумевает включение в программу отдель-
ных SQL-операторов, которые являются чисто декларативными, а не выполняемы-
ми. Например, оператор DECLARE CURSOR — это невыполняемый оператор
(подробности приводятся в разделе “Операции, использующие курсоры”); таковы-
ми не являются и операторы BEGIN и END DECLARE SECTION (см. п. 5 этого списка), а
также оператор WHENEVER (см. п. 9).
3. SQL-операторы могут включать ссылки на базовые переменные (т.е. переменные
базового языка). Подобные ссылки должны включать префикс в виде двоеточия,
предназначенный для отличия их от имен столбцов SQL-таблиц. Базовые перемен-
ные могут применяться во внедренных SQL-операторах везде, где в интерактивном
языке SQL могут использоваться литералы. Они могут также находиться в предло-
жении INTO операторов SELECT (см. п. 4) и FETCH (подробности — в разделе
“Операции, использующие курсоры”), определяющих результирующие перемен-
ные для размещения результатов выборки данных.
4. Обратите внимание на предложение INTO оператора SELECT, представленного на
рис. 4.3. Назначение этого предложения (как только что отмечалось) — указать ре-
зультирующие (целевые) переменные, в которые будут возвращены выбранные зна-
чения. Каждая /-я целевая переменная, указанная в предложении INTO, соответствует
/-му извлекаемому значению, указанному в списке выборки предложения SELECT.
5. Все базовые переменные, на которые ссылаются внедренные SQL-операторы,
должны быть определены (в PL/I это оператор DCL) в разделе объявлений вне-
дренного языка SQL, который ограничивается операторами BEGIN DECLARE
SECTION и END DECLARE SECTION.
6. Каждая программа, содержащая внедренные SQL-операторы, должна включать ба-
зовую переменную с именем SQLSTATE. После выполнения любого присутствую-
щего в программе SQL-оператора в эту переменную возвращается код состояния. В
частности, код состояния 00000 означает, что оператор был выполнен успешно, а
код состояния 02000 — что оператор был выполнен, но никаких удовлетворяющих
запросу данных найдено не было. Таким образом, выполнение в программе каждо-
го SQL-оператора должно завершаться проверкой значения переменной SQLSTATE
и, если это значение будет отличаться от ожидаемого, должны предприниматься
соответствующие действия. На практике, однако, такая проверка обычно выполня-
ется неявно (см. п. 9).
7. Базовые переменные должны иметь типы данных, соответствующие значениям,
для размещения которых эти переменные используются. В частности, базовая пе-
ременная, используемая в качестве целевой (т.е. для размещения результатов опе-
рации SELECT), должна иметь тип данных, который совместим с типом выражения,
представляющего значение, присваиваемое этой целевой переменной. Аналогично,
если базовая переменная служит источником (например, для операции INSERT), она
должна иметь тип данных, совместимый с SQL-типом того столбца, которому при-
128
Часть I. Основные понятия
сваивается значение из этого источника. Подобные замечания касаются также ба-
зовых переменных, используемых в сравнениях или в любых других операциях. В
официальном документе стандарта [4.22] подробно объясняется, что для двух ти-
пов значит быть совместимыми.
8. Базовые переменные для столбцов SQL-таблиц могут иметь те же имена, что и
имена соответствующих столбцов.
9. Как уже упоминалось, выполнение каждого SQL-оператора, в принципе, должно
сопровождаться проверкой значения, возвращаемого в переменной SQLSTATE. Для
упрощения этого процесса предназначен оператор WHENEVER, который имеет сле-
дующий синтаксис.
EXEC SQL WHENEVER <условие> <действие> ;
Здесь параметр <условие> может принимать значение либо SQLERROR (ошибка
SQL), либо NOT FOUND (не найдено), а параметр <действие> — это либо оператор
CONTINUE (продолжить), либо оператор GO ТО (перейти к). Оператор WHENEVER не
является выполняемым; это просто директива для SQL-компилятора. Наличие в
программе выражения “WHENEVER <условие> GO ТО <метка>" приведет к тому, что
компилятор поместит оператор “IF <условие> GO ТО <метка> END IF” после каж-
дого встретившегося ему выполняемого SQL-оператора. Однако, встретив выраже-
ние “WHENEVER <условие> CONTINUE”, SQL-компилятор не вставляет в программу
никаких операторов и, следовательно, программист должен будет вставить требуе-
мые операторы вручную. Два фиксированных значения условия определяются так.
NOT FOUND означает никаких данных не найдено
- SQLSTATE = 02000 (обычно)
SQLERROR означает возникла ошибка
- см. описание стандарта [4.22] для переменной SQLSTATE
Каждый оператор WHENEVER, который процессор SQL встречает при последователь-
ном сканировании текста программы (для определенного условия), отменяет пре-
дыдущий (для этого условия).
10. Используя терминологию главы 2, отметим, что внедрение SQL-операторов уста-
навливает слабую связь между SQL-средой и базовым языком.
Итак, для предварительного обсуждения этого достаточно. Далее мы сосредоточимся
на операторах манипулирования данными. Как уже отмечалось, большинство из них
можно использовать практически в неизменном виде (т.е. лишь с незначительными из-
менениями в синтаксисе). Однако операции выборки требуют особого рассмотрения.
Проблема состоит в том, что такие операторы в общем случае выбирают не одну, а мно-
жество строк, в то время как процедурные базовые языки обычно не приспособлены для
выборки более одной строки за одно обращение. Следовательно, необходимо обеспечить
своего рода “мост” между уровнем выборки “множество-за-один-раз” в языке SQL и
уровнем выборки “строка-за-один-раз” в базовом языке. В качестве подобного моста ис-
пользуются курсоры. Курсор — это специальный тип SQL-объекта, который применяет-
ся только во внедренном языке SQL (поскольку в интерактивном языке SQL в нем нет
необходимости). Курсор представляет собой определенный тип логического указателя,
который может использоваться для перемещения по набору строк, указывая поочередно
Глава 4. Введение в язык SQL
129
на каждую из них и таким образом обеспечивая возможность адресации к этим
строкам — к одной за один раз. Однако временно отложим подробное обсуждение кур-
соров и рассмотрим сначала такие операторы, для которых курсоры не требуются.
Операции, не использующие курсоры
Ниже перечислены операторы манипулирования данными, для которых не требуется
использование курсоров.
Однострочный оператор SELECT
INSERT
UPDATE (кроме формы CURRENT)
DELETE (также кроме формы CURRENT)
Рассмотрим примеры для каждого из этих операторов.
Однострочный оператор SELECT. Получить статус и название города для поставщи-
ка, номер поставки которого задан в базовой переменной GIVENS#.
EXEC SQL SELECT STATUS, CITY
INTO .-RANK, :CITY
FROM S
WHERE S# = :GIVENS# ;
Термин однострочный оператор SELECT используется для обозначения выражения
SELECT, значением которого будет таблица, содержащая не более одной строки. В дан-
ном примере, если в таблице S существует ровно одна строка, удовлетворяющая задан-
ному условию WHERE, значения столбцов STATUS и CITY из этой строки в соответствии с
запросом будут присвоены базовым переменным RANK и CITY, а переменной SQLSTATE
будет присвоено значение 00000. Если в таблице S нет ни одной строки, удовлетворяю-
щей заданному условию WHERE, переменной SQLSTATE будет присвоено значение 02000
Если же таких строк окажется больше одной, будет зафиксирована ошибка и переменная
SQLSTATE будет содержать ее код.
Оператор INSERT. Вставить в таблицу Р сведения о новой детали (номер детали, ее
название и вес задаются содержимым базовых переменных Р#, PNAME, PWT соответствен-
но; цвет детали и город неизвестны).
EXEC SQL INSERT
INTO Р ( Р#, PNAME, WEIGHT )
VALUES ( :P#, -.PNAME, :PWT ) ;
Столбцам COLOR и CITY вновь добавляемой строки таблицы будут присвоены значения
принимаемые по умолчанию. Подробнее об этом речь пойдет в разделе 5.5 главы 5.
Оператор UPDATE. Увеличить статус всех поставщиков из Лондона на значение, по
мешенное в базовую переменную RAISE.
EXEC SQL UPDATE S
SET STATUS = STATUS + :RAISE
WHERE CITY = 'London' ;
130
Часть I. Основные поняты
Если в таблице поставщиков строк, удовлетворяющих условию WHERE, найдено не бу-
дет, система присвоит переменной SQLSTATE значение 02000.
Оператор DELETE. Удалить сведения обо всех поставках для поставщиков из города,
название которого помещено в базовую переменную CITY.
EXEC SQL DELETE
FROM SP
WHERE :CITY =
( SELECT CITY
FROM S
WHERE S.S# = SP.S# ) ;
И снова, если нет строк, удовлетворяющих условию WHERE, переменной SQLSTATE
присваивается значение 02000. Также обратите внимание на вложенный подзапрос (на
этот раз в предложении WHERE).
Операции, использующие курсоры
Теперь перейдем к вопросу о выборках на уровне множеств, т.е. о выборках не одной
строки, как это было в случае однострочного оператора SELECT, а множества с произ-
вольным количеством строк. Как указывалось ранее, в этой ситуации потребуется пооче-
редный доступ к строкам выбранного множества, а механизмом такого доступа будет
курсор. На рис. 4.4 этот процесс схематически проиллюстрирован на примере выборки
информации о поставщиках (столбцы S#, SNAME и STATUS) для всех поставщиков из горо-
да, название которого задается в базовой переменной Y.
EXEC SQL DECLARE X CURSOR FOR SELECT S.S#, S.SNAME, /* определить курсор X */ , S.STATUS
FROM WHERE ORDER S S.CITY = :Y BY S# ASC ;
EXEC SQL OPEN X; /* выполнить запрос */
DO <для всех строк S, доступных через Х> ;
EXEC SQL FETCH X INTO :S#, :SNAME, :STATUS ;
/* выбрать следующего поставщика */
END ;
EXEC SQL CLOSE X ; /* закрыть курсор X */
Рис. 4.4. Выборка нескольких строк
Пояснение. Оператор DECLARE X CURSOR... определяет курсор с именем X, связанный
с табличным выражением (т.е. выражением, которое вычисляет таблицу). Табличное
выражение определяется оператором SELECT, который является частью всего выражения
DECLARE. Причем указанное табличное выражение не вычисляется в этом месте програм-
мы, поскольку оператор DECLARE CURSOR — чисто декларативный. Табличное выражение
Глава 4. Введение в язык SQL
131
вычисляется только при открытии курсора (оператор OPEN X). Далее для выборки строк
из результирующего множества, по одной за один раз, используется оператор FETCH,
присваивающий извлеченные значения базовым переменным в соответствии со специ-
фикациями в предложении INTO. (Для простоты базовым переменным присвоены имена,
совпадающие с именами соответствующих столбцов таблицы базы данных. Обратите
внимание, что в операторе SELECT при определении курсора нет своего предложения
INTO.) Поскольку в результирующем наборе потенциально присутствует большое коли-
чество строк, оператор FETCH обычно используется в некотором цикле (оператор
DO.. .END в языке PL/I). Цикл будет повторяться до тех пор, пока не закончатся строки в
результирующем наборе. При выходе из цикла курсор X закрывается (оператор CLOSE X).
А теперь рассмотрим курсоры и операции с ними более подробно. Курсор определя-
ется с помощью оператора DECLARE CURSOR, общий вид которого следующий.
EXEC SQL DECLARE <имя курсора> CURSOR
FOR стабличное выражение> [ <упорядочение> ] ;
Для краткости несколько необязательных спецификаций в этом определении не ука-
заны. Здесь параметр <имя курсора> — это имя определяемого курсора. Полное опреде-
ление табличного выражения, помещаемого в параметр Стабличное выражение^ дано в
приложении А. Необязательный параметр определения сортировки результата выборки
<упорядочение> имеет следующий формат.
ORDER BY <список элементов>
Здесь параметр ссписок элементов> содержит список перечисленных через запятую
элементов, по которым должно быть выполнено упорядочение извлекаемых строк. Спи-
сок элементов не должен быть пустым, в каждом элементе списка должно содержаться
имя столбца (заметьте, не уточненное), после которого может следовать необязательное
служебное слово ASC (по возрастанию) или DESC (по убыванию). При опускании служеб-
ного слова по умолчанию принимается порядок по возрастанию (ASC).
Замечание. Дадим определение термину список элементов, перечисленных через
запятую (commalist). Пусть <xyz> обозначает произвольную синтаксическую катего-
рию (т.е. то, что находится слева от некоторого правила вывода в нотации BNF). Тогда
выражение <xyz commalist> (или <список xyz>) обозначает последовательность из нуля
или более элементов <xyz>, в которой каждая пара элементов <xyz> разделена запятой
(и, может быть, одним или несколькими пробелами). Обратим ваше внимание на то,
что сокращение <список ...> будет широко использоваться в приводимых далее син-
таксических правилах (причем во всех синтаксических правилах, а не только в прави-
лах языка SQL).
Как утверждалось ранее, оператор DECLARE CURSOR— декларативный, а не выпол-
няемый. Он предназначен для объявления курсора с определенным именем и постоянно
связанного с ним табличного выражения и типа упорядочения. Табличное выражение
может включать ссылки на базовые переменные. Программа может содержать любое ко-
личество операторов DECLARE CURSOR, каждый из которых, конечно, предназначен для
определения разных курсоров.
Для работы с курсорами существует три выполняемых оператора: OPEN, FETCH и
CLOSE.
132
Часть I. Основные понятия
Оператор OPEN имеет следующий формат.
EXEC SQL OPEN <имя курсорам,
Он предназначен для открытия или активизации указанного курсора (который в
данный момент не должен быть открыт). В результате его выполнения вычисля-
ется связанное с этим курсором табличное выражение (причем для всех базовых
переменных, упоминаемых в этом выражении, используются текущие значения).
В результате идентифицируется определенное множество строк, которое стано-
вится текущим активным набором для данного курсора. Курсор также уста-
навливает исходную позицию в этом активном наборе, а именно — позицию пе-
ред его первой строкой. (Активные наборы всегда рассматриваются как упоря-
доченные, а значит, и понятие позиции имеет для них смысл5. Порядок опреде-
ляется предложением ORDER BY; если же оно отсутствует, порядок строк уста-
навливается системой.)
Оператор FETCH имеет следующий формат.
EXEC SQL <нмя курсора> INTO ссписок ссылок на базовые переменные> •,
Он служит для перемещения позиции указанного курсора (который должен
быть уже открыт) к следующей строке в его активном наборе с последующим
присвоением значений столбцов этой строки базовым переменным, указанным
в предложении INTO. Если при выполнении оператора FETCH следующей стро-
ки нет, то никакие данные не выбираются и переменной SQLSTATE присваива-
ется значение 02000.
Оператор CLOSE имеет следующий формат.
EXEC SQL CLOSE <нмя курсора> ;
Он служит для закрытия (деактивизации) указанного курсора (который должен
быть в данный момент открыт). После его выполнения у курсора уже не будет ак-
тивного набора. Однако в дальнейшем курсор вновь может быть открыт; при этом
он опять получит активный набор — возможно, уже не такой, как раньше (в част-
ности, если значения указанных в объявлении курсора базовых переменных к те-
кущему моменту были изменены). Заметьте, что изменение этих переменных при
открытом курсоре не окажет влияния на его активный набор.
Есть еще два оператора, в которых могут использоваться ссылки на курсоры, — это
CURRENT-формы операторов UPDATE и DELETE. Если курсор (скажем, X) в данный момент
позиционирован на определенную строку, то можно обновить или удалить эту “текущую
строку курсора X”, т.е. строку, на которую курсор X в данный момент позиционирован,
как, например, показано ниже.
EXEC SQL UPDATE S
SET STATUS = STATUS + :RAISE
WHERE CURRENT OF X ;
5 Сами no себе множества, конечно, не являются упорядоченными (глава 5), так что
"активный набор” — это на самом деле не множество как таковое. Его лучше представлять в
виде упорядоченного списка или массива (строк).
Глава 4. Введение в язык SQL
133
Замечание. Выражения UPDATE.. .WHERE CURRENT и DELETE.. .WHERE CURRENT будут
недопустимы, если табличное выражение в объявлении курсора определено с участием
необновляемого представления, созданного с помощью оператора CREATE VIEW
(подробности приводятся в главе 9, раздел 9.6).
Динамический SQL
Динамический язык SQL состоит из набора функций поддержки внедрения SQL-
операторов, предназначенных специально для создания обобщенных, оперативных и,
возможно, интерактивных приложений. (Напомним, что, как отмечалось в главе 1, инте-
рактивные приложения — это приложения, которые предоставляют пользователю доступ
к базе данных с некоторого интерактивного терминала.) Рассмотрим, что должно делать
типичное интерактивное приложение. Схематически оно должно выполнять
(многократно) следующие действия.
1. Принять с терминала команду пользователя.
2. Проанализировать поступившую команду.
3. Сгенерировать соответствующие SQL-операторы для обращения к базе данных.
4. Возвратить сообщение и (или) полученные результаты на терминал.
Если набор команд пользователя, который программа может принять с терминала,
достаточно мал (как, например, в случае обработки предварительных заказов мест на
авиалиниях), то набор всех возможных выполняемых SQL-операторов также будет неве-
лик и его можно будет непосредственно внедрить в программу. В этом случае действия
на втором и третьем этапах будут состоять в логической проверке введенной команды с
последующим переходом к той части программы, которая выполняет заранее предопре-
деленные SQL-операторы. В противном случае, если набор вводимых команд достаточно
разнообразен, было бы непрактично заранее предопределять и внедрять в программу все
требуемые SQL-выражения для всех возможных команд. Вместо этого, вероятно, целе-
сообразнее конструировать необходимые SQL-запросы динамически, а затем динамиче-
ски же компилировать и выполнять сконструированные запросы. Средства динамическо-
го языка SQL предназначены для поддержки этого процесса.
Существует два основных динамических SQL-оператора— PREPARE и EXECUTE. Их
использование проиллюстрировано на следующем (нереальном по простоте, но доста-
точно точном) примере.
DCL SQLSOURCE CHAR VARYING (65000) ;
SQLSOURCE = 'DELETE FROM SP WHERE QTY < 300' ;
EXEC SQL PREPARE SQLPREPPED FROM :SQLSOURCE ;
EXEC SQL EXECUTE SQLPREPPED ;
Пояснения
1. Имя SQLSOURCE идентифицирует переменную языка PL/I типа символьной строки
переменной длины, в которой программа каким-либо образом конструирует исход-
ную форму (т.е. представление в виде символьной строки) некоторого SQL-
оператора, в нашем конкретном примере — оператора DELETE.
134
Часть I. Основные понятия
2. Имя SQLPREPPED, напротив, идентифицирует переменную среды SQL, а не базового
языка PL/I, которая будет (концептуально) использоваться для хранения скомпилиро-
ванной формы SQL-оператора (исходная форма которого представлена в переменной
SQLSOURCE). Конечно, имена SQLSOURCE и SQLPREPPED можно выбирать произвольно.
3. С помощью оператора присвоения SQLSOURCE =...; переменной SQLSOURCE при-
сваивается исходная форма SQL-оператора DELETE. Конечно, на практике процесс
конструирования такого исходного оператора будет значительно сложнее и, воз-
можно, в нем будут использоваться ввод и анализ некоторых элементов запросов
от конечного пользователя, выраженных на обычном языке или в другой, более
“дружественной для пользователя” форме, чем обыкновенный язык SQL.
4. Оператор PREPARE извлекает это исходное выражение и подготавливает (т.е. ком-
пилирует) его, создавая выполняемую версию извлеченного им оператора, сохра-
няемую в переменной SQLPREPPED.
5. Оператор EXECUTE выполняет откомпилированную версию оператора из перемен-
ной SQLPREPPED, в результате чего осуществляется собственно операция DELETE.
Информация SQLSTATE выполненного оператора DELETE возвращается так же, как
при выполнении аналогичного оператора обычным образом.
Обратите внимание, что, поскольку имя SQLPREPPED идентифицирует переменную
языка SQL, а не PL/I, при его использовании в операторах PREPARE и EXECUTE двоеточие
перед ним не указывается. Заметьте также, что подобные SQL-переменные не объявля-
ются явно.
Описанный выше процесс в точности совпадает с процессом, который происходит,
если SQL-выражения вводятся интерактивно. Во многих системах имеется некоторое
подобие процессора SQL-запросов. Этот процессор в действительности — не что иное,
как обобщенное интерактивное приложение, способное обрабатывать весьма широкий
спектр вводимых команд, а именно — любой допустимый (или недопустимый!) оператор
языка SQL. Для конструирования SQL-операторов, соответствующих вводимым пользо-
вателем командам, для компиляции и выполнения сконструированных операторов и для
возврата сообщений и результатов на терминал в нем используются именно средства ди-
намического языка SQL.
Завершая этот раздел, кратко рассмотрим более позднее (1995) дополнение стандарта
SQL, известное как SQL Call-Level Interface, или кратко — просто интерфейс CL1. Ин-
терфейс CLI, в основном, строится на базе интерфейса Open Database Connectivity ком-
пании Microsoft (ODBC). Благодаря интерфейсу CLI приложения, которые написаны на
одном из базовых языков, могут выдавать запросы к базе данных, обращаясь к процеду-
рам CLI, предоставляемым изготовителем. Затем эти процедуры, обязательно предвари-
тельно связанные с данным приложением, используют динамический язык SQL для вы-
полнения требуемых операций с базой данных от имени приложения. (Иными словами, с
точки зрения СУБД процедуры CLI могут считаться просто другим приложением.)
Как видим, интерфейс SQL/CLI (и ODBC тоже) решает ту же задачу, что и динамиче-
ский язык SQL, а именно — позволяет приложению предоставлять текст SQL-оператора
лишь к тому времени, когда его непосредственно необходимо выполнять. Однако подход
интерфейсов CLI и ODBC к решению этой задачи лучше, чем подход динамического
языка SQL. Эти преимущества заключаются в следующем.
Глава 4. Введение в язык SQL
135
Во-первых, динамический SQL — это стандарт исходного кода. Поэтому для лю-
бого приложения, которое использует динамический язык SQL, требуется какой-
то SQL-компилятор, необходимый для обработки установленных стандартом опе-
раций, таких как PREPARE, EXECUTE и т.д. Интерфейсом CLI, напротив, нормирова-
ны лишь детали вызова процедуры (т.е., в основном, вызовов подпрограмм). Не
требуется услуг никакого специального компилятора, достаточно использовать
обычный компилятор стандартного базового языка. Поэтому приложение может
распространяться (возможно, сторонними изготовителями программного обеспе-
чения) в “сжатой” форме в виде объектного кода.
Во-вторых, такие приложения могут быть независимыми от типа СУБД, т.е. ин-
терфейс CLI включает средства создания общих приложений (опять же, возможно,
от сторонних изготовителей программного обеспечения), которые могут исполь-
зоваться для нескольких различных типов СУБД вместо специальных для какой-то
конкретной СУБД.
Такие интерфейсы, как CLI, ODBC и JDBC (вариант ODBC для языка Java), приобре-
тают все более важное значение по причинам, которые будут обсуждаться (частично) в
главе 20.
4.7. Несовершенство языка SQL
Как отмечалось во введении к этой главе, язык SQL далек от совершенства и имеет
недостатки, вызванные многочисленными недоделками и переделками. Конкретные кри-
тические замечания будут представлены в последующих главах. Здесь лишь отметим,
что основной недостаток заключается в том, что, строго говоря, язык SQL, в целом, не-
корректно поддерживает реляционную модель. Поэтому возникает сомнение, заслужи-
вают ли современные SQL-продукты права называться действительно реляционными.
Фактически, насколько это известно автору, на сегодняшний день на рынке нет ни одно-
го продукта, который поддерживал бы реляционную модель в полном объеме. Мы не
хотим этим сказать, что какие-то аспекты реляционной модели не важны; как раз наобо-
рот, каждый элемент в модели важен. Более того, каждый из ее элементов важен по
чисто практическим соображениям. Нельзя не подчеркнуть тот непреложный факт, что
назначение реляционной теории состоит не в том, чтобы просто быть “теорией для тео-
рии”. Вовсе нет, ее назначение — обеспечить базу для построения систем, которые бу-
дут практическими на все сто процентов. Но, как это ни печально, со стороны изгото-
вителей продуктов еще не сделано реальных шагов к решению проблемы реализации ре-
ляционной теории во всей ее полноте. В результате “реляционные” продукты сегодняш-
него дня все как один по тем или иным причинам оказываются неспособными реализо-
вать преимущества, которые теоретически могут быть получены в результате использо-
вания реляционной технологии.
4.8. Резюме
На этом завершается знакомство с некоторыми важнейшими функциональными воз-
можностями, предусмотренными стандартом языка SQL (точнее, SQL/92). Мы подчер-
киваем тот факт, что язык SQL очень важен с коммерческой точки зрения, хотя, к сожа-
лению, в определенной степени несовершенен с чисто реляционной точки зрения.
136
Часть I. Основные понятия
Язык SQL состоит из двух компонентов: языка определения данных (DDL) и языка
манипулирования данными (DML). Язык манипулирования данными может приме-
няться и на внешнем уровне (по отношению к представлениям), и на концептуальном
уровне (по отношению к базовым таблицам). Аналогично язык определения данных мо-
жет использоваться для определения объектов на внешнем уровне (представления), кон-
цептуальном уровне (базовые таблицы), а в большинстве коммерческих систем (хотя это
и не соответствует самому стандарту) даже на внутреннем уровне (по отношению к ин-
дексам и другим физическим структурам организации памяти). Кроме того, язык SQL
предоставляет определенные возможности управления данными, т.е. возможности, кото-
рые нельзя отнести ни к языку DDL, ни к языку DML. Примером здесь может служить
оператор GRANT, который одни пользователи могут применять для предоставления приви-
легий доступа другим пользователям системы (глава 16).
Мы показали, как можно использовать язык SQL для создания базовых таблиц с по-
мощью оператора CREATE TABLE. Затем мы привели несколько примеров использования
операторов SELECT, INSERT, UPDATE и DELETE и, в частности, продемонстрировали, как
можно применять оператор SELECT для реализации операций выборки, проекции и со-
единения. Также некоторое внимание было уделено информационной схеме, состоящей
из множества предопределенных представлений гипотетической “схемы определения”, и
возможностям языка SQL по работе с представлениями и транзакциями.
Значительная часть этой главы была посвящена внедренным SQL-операторам. Ос-
новная идея, лежащая в основе использования внедренных SQL-операторов, называется
принципом двухрежимности, т.е. принципом, в соответствии с которым (насколько это
возможно) любое SQL-выражение, которое можно использовать интерактивно, мож-
но внедрить и в прикладную программу. Главное исключение из этого принципа имеет
место в связи с операциями многострочной выборки, для которых требуется исполь-
зовать курсоры, позволяющие преодолеть разрыв между возможностью выборки дан-
ных на уровне множеств в языке SQL и возможностями выборки данных на уровне стро-
ки в базовых языках программирования, таких, например, как PL/I.
Далее мы обсуждали, главным образом, вопросы синтаксиса, в том числе выяснили на-
значение переменной SQLSTATE и рассмотрели такие операторы, как однострочный опера-
тор SELECT и операторы INSERT, UPDATE и DELETE, для которых курсор не нужен. Затем мы
возвратились к операторам, для которых требуется использование курсора, и обсудили
операторы DECLARE CURSOR, OPEN, FETCH, CLOSE и формы CURRENT для операторов UPDATE
и DELETE. (В стандарте языка SQL форму CURRENT этих операторов называют позиционным
оператором UPDATE и DELETE соответственно, а термин поисковый используют для других
форм этих операторов, отличных от CURRENT.) Наконец, мы кратко обсудили концепцию
динамического языка SQL, в частности — операторы PREPARE и EXECUTE, а также кратко
коснулись назначения интерфейса SQL Cali-Level Interface или CLI.
Упражнения
4.1. На рис. 4.5 показаны примеры значений данных для расширенной формы базы
данных поставщиков и деталей, которая называется базой данных поставщиков,
деталей и проектов. Поставщики (S), детали (Р) и проекты (J) однозначно опреде-
ляются номером поставщика (S#), номером детали (Р#) и номером проекта (J#) со-
Глава 4. Введение в язык SQL
137
ответственно. Значение строки SPJ (поставки) следующее: определенный постав-
щик поставляет определенную деталь для определенного проекта в определенном
количестве (причем комбинация значений столбцов S#-P#-J# уникальна для от-
дельных строк). Запишите соответствующие определения данных на языке SQL
для этой базы данных.
Замечание. Эта база данных будет использоваться во многих упражнениях в по-
следующих главах.
S S# SNAME STATUS CITY SPJ S# P# J# QTY
S1 Smith 20 London SI Pl JI 200
S2 Jones 10 Paris SI Pl J4 700
S3 Black 30 Paris S2 P3 JI 400
S4 Clark 20 London S2 P3 J2 200
S5 Adams 30 Athens S2 P3 J3 200
S2 P3 J4 500
S2 P3 J5 600
р P# PNAME COLOR WEIGHT CITY S2 P3 J6 400
Р1 Nut Red 12.0 London S2 P3 J7 800
Р2 Bolt Green 17.0 Paris S2 P5 J2 100
РЗ Screw Blue 17.0 Rome S3 P3 JI 200
Р4 Screw Red 14.0 London S3 P4 J2 500
Р5 Cam Blue 12.0 Paris S4 P6 J3 300
Р6 Cog Red 19.0 London S4 P6 J7 300
S5 P2 J2 200
S5 P2 J4 100
J J# JNAME CITY S5 P5 J5 500
Л Sorter Paris S5 P5 J7 100
J2 Display Rome S5 P6 J2 200
J3 OCR Athens S5 Pl J4 100
J4 Console Athens S5 P3 J4 200
J5 RAID London S5 P4 J4 800
J6 EDS Oslo S5 P5 J4 400
J7 Tape London S5 P6 J4 500
Рис. 4.5. База данных поставщиков, деталей и проектов (значения для примера)
4.2. В разделе 4.2 был описан оператор CREATE TABLE, как он определен в стандарте
языка SQL. Однако многие коммерческие продукты поддерживают дополнитель-
ные опции этого оператора, обычно связанные с индексами, размещением на дис-
ковом пространстве и другими вопросами реализации, что противоречит цели фи-
зической независимости данных и междусистемной совместимости. Исследуйте
доступный вам продукт, поддерживающий язык SQL. Верны ли предыдущие заме-
чания для этого продукта? В частности, какие дополнительные опции оператора
CREATE TABLE поддерживаются в этом продукте?
4.3. И снова исследуйте доступный вам продукт, поддерживающий язык SQL. Поддер-
живается ли в нем информационная схема? Если нет, то каким образом поддержи-
вается каталог?
138
Часть I. Основные понятия
4.4. Сформулируйте на языке SQL следующие операции обновления для базы данных
поставщиков, деталей и проектов.
а) Вставить нового поставщика 'S10' в таблицу S; имя поставщика— 'Smith',
город— 'New York', статус еще неизвестен.
б) Изменить цвет всех красных деталей (' red') на оранжевый (' orange').
в) Удалить все проекты, для которых нет поставок.
4.5. Используя базу данных поставщиков, деталей и проектов, напишите программу с
внедренными SQL-выражениями для выдачи списка всех строк поставщиков по
порядку их номеров. За каждой строкой поставщика должны непосредственно сле-
довать строки проектов, обеспечиваемых этим поставщиком, по порядку номеров
проектов.
4.6. Даны таблицы PART и PART_STRUCTURE, определенные таким образом.
CREATE TABLE PART
( P# ... , DESCRIPTION ... ,
PRIMARY KEY ( P# ) ) ;
CREATE TABLE PART STRUCTURE
( MAJOR P# .7. , MINOR P# ... , QTY ... ,
PRIMARY KEY ( MAJOR P#, MINOR P# ),
FOREIGN KEY ( MAJOR~P# ) REFERENCES PART,
FOREIGN KEY ( MINOR^P# ) REFERENCES PART ) ;
В таблице PART__STRUCTURE показано, какие детали (MAJOR_P#) содержат другие де-
тали (MINOR_P#) как компоненты первого уровня. Напишите программу на языке
SQL для получения списка всех компонентов данной детали на всех имеющихся
уровнях (задача разузлования деталей).
Замечание. Значения, показанные в качестве примера на рис. 4.6, могут помочь
вам более наглядно представить предложенную выше задачу. Следует отметить,
что таблица PART_STRUCTURE демонстрирует, как информация о составе изделий
(см. главу 1, раздел 1.3, подраздел “Сущности и связи”) обычно представляется в
реляционных системах.
PART_STRUCTURE MAJOR P# MINORP# QTY
Pl P2 2
Pl P3 4
P2 P3 1
P2 P4 3
P3 P5 9
P4 P5 8
P5 P6 3
Рис. 4.6. Таблица PART STRUCTURE (значения для примера)
Глава 4. Введение в язык SQL
139
Список литературы
4.1. Astrahan М.М., Lorie R.A. SEQUEL-XRM: A Relational System П Proc. ACM Pacific
Regional Conference. — San Francisco, Calif., April, 1975.
Описан первый прототип реализации языка SEQUEL — самой ранней версии язы-
ка SQL [4.8]. См. также документы [4.2], [4.3], которые выполняют аналогичную
функцию для проекта System R.
4.2. Astrahan М.М. et al. System R: Relational Approach to Database Management // ACM
TODS. — June, 1976. — 1, № 2.
Система System R была реализацией основного прототипа (ранней версии — языка
SEQUEL/2, см. [4.8]) языка SQL. В статье описывается архитектура System R в том
виде, в каком она была изначально запланирована; также см. [4.3].
4.3. Biasgen M.W. et al. System R: An Architectural Overview 11 IBM Sys. J. — February,
1981. —20, № 1.
Описывается архитектура System R на момент, когда система была полностью реа-
лизована (ср. с [4.2]).
4.4. Stephen С. and Otten G. SQL — The Standard Handbook. Maidenhead, UK: McGrow-
Hill International, 1993.
“[Наша] задача ... представить справочное руководство, в котором объясняется и
описывается [стандарт SQL/92, как он изначально был определен] в менее фор-
мальном и легче воспринимаемом изложении по сравнению с самим стандартом”
(цитата из введения к книге).
4.5. Celko J. SQL for Smarties: Advanced SQL Programming. San Francisco, Calif.: Morgan
Kaufmann, 1995.
“Это первая вышедшая книга по языку SQL с глубоким и детальным освещением
материала, в которой исчерпывающе представлены средства и методы, позволяю-
щие совершенствовать свои навыки читателю, от неопытного пользователя языка
SQL до высококвалифицированного программиста” (цитата с обложки книги).
4.6. Eisenberg A. and Meltom J. SQLJ Part 0, Now Known as SQL/OLB (Object Language
Bindings) // ACM SIGMOD Record.— Desember, 1998.— 27, №4. См. также
Clossman G. et al. Java and Relational Databases: SQLJ // Proc. ACM SIGMOD Int.
Conf, on Management of Data. — Seattle, Wash., June, 1998.
4.7. Chamberlin D. Using the New DB2. — San Francisco, Calif.: Morgan Kaufmann, 1996.
Интересное и всестороннее описание современного положения дел в отношении
коммерческих SQL-продуктов, сделанное одним из двух основных разработчиков
первоначальной версии языка SQL [4.8].
Замечание. В книге также обсуждаются “некоторые спорные решения”, воплощен-
ные в проекте языка SQL (прежде всего, решение о поддержке отсутствующих
значений и решение о допущении дублирования строк). “Моя цель ... скорее, исто-
рическая, чем стремление убедить. Я понимаю, что нули и дубликаты — это рели-
гиозные вопросы... В большей части разработчики [языка SQL] были практиками,
а не теоретиками, и такая ориентация отразилась на многих решениях [проекта].”
Подобная позиция очень отличается от той, которую представляет автор! Нули и
дубликаты — это научные вопросы, а не религиозные; они научно обсуждаются в
этой книге в главах 18 и 5 соответственно. А относительно противопоставления
140
Часть I. Основные понятия
“практиками, а не теоретиками” подчеркнем, что мы категорически отвергаем су-
ждение, что теория — это не практика. Мы уже констатировали нашу позицию (в
разделе 4.5) относительно того, что теория, по крайней мере реляционная, по своей
сути очень даже практична.
4.8. Chamberlin D.D. and Воусе R.F. SEQUEL: A Structured English Query Language //
Proc. ACM SIGMOD Workshop on Data Description, Access, and Control. — Ann
Arbor, Mich., May, 1974.
В статье впервые представлен язык SQL (или SEQUEL, как он назывался вначале;
впоследствии название по юридическим причинам было изменено).
4.9. Chamberlin D.D. et al. SEQUEL/2: A Unified Approach to Data Definition, Manipulation,
and Control 11 IBM J. R&D. — November, 1976. — 20, № 6; January, 1977. —21, № 1.
Опыт реализации предыдущего прототипа языка SEQUEL, описанного в [4.1], и
результаты проверок практичности, отчет о которых содержится в [8.28], привели
к разработке новой версии языка, названной SEQUEL/2. Язык, поддерживаемый
системой System R [4.2], [4.3], был, в основном, похож на SEQUEL/2 (с заметным
отсутствием возможностей так называемых “утверждений” и “триггеров”; подроб-
ности приводятся в главе 8), плюс некоторые расширения, появившиеся в резуль-
тате учета опыта пользователей [4.10].
4.10. Chamberlin D.D. A Summary of User Experience with the SQL Data Sublanguage //
Proc. Int. Conf, on Database.— Aberdeen, Scotland, July, 1980. (См. также IBM
Research Report RJ2767. —April, 1980.)
В статье обсуждается ранний опыт использования системы System R и предлагают-
ся некоторые дополнения языка SQL в свете этого опыта. Некоторые из этих до-
полнений— операторы EXISTS, LIKE, PREPARE и EXECUTE— действительно были
реализованы в окончательной версии System R.
Замечание. Подробности приводятся в главе 7 и приложении А, в которых обсуж-
даются операторы EXISTS и LIKE соответственно.
4.11. Chamberlin D.D. et al. Support for Repetitive Transactions and Ad Hoc Queries in
System R11 ACM TODS. — March, 1981. — 6, № 1.
В статье приводятся некоторые результаты оценки производительности системы
System R как в среде выполнения произвольных запросов, так и в среде выполнения
стандартных транзакций. (Стандартные транзакции — это простое приложение, ко-
торое имеет доступ лишь к небольшой части базы данных и перед выполнением
предварительно компилируется. Это соответствует тому, что мы называли планируе-
мым запросом в главе 2 в разделе 2.8) Измерения производились на компьютере IBM
System 370 Model 158 в системе System R, выполняющейся под управлением опера-
ционной системы VM. Эти измерения названы предварительными. Тем не менее с
учетом этого предупреждения статья, кроме всего прочего, демонстрирует, что ком-
пиляция почти всегда превосходит интерпретацию, даже для произвольных запросов,
и что система, подобная System R, способна выполнять несколько стандартных тран-
закций в секунду, если предусмотреть в базе данных соответствующие индексы.
Статья достойна внимания, поскольку она была одной из первых статей, показав-
ших несостоятельность заявлений (которые в то время можно было слышать очень
часто), что “реляционные системы никогда не будут иметь хорошие эксплуатаци-
онные качества”. Безусловно, со времени этой первой публикации коммерческие
Глава 4. Введение в язык SQL
141
реляционные продукты достигли такой скорости выполнения транзакций, что за
секунду могут выполняться сотни и даже тысячи транзакций.
4.12. Chamberlin D.D. et al. A History and Evaluation of System R И CACM. — October,
1981. —24, № 10.
Описываются три основные фазы развития проекта System R (предварительный
прототип, многопользовательский прототип и оценочный вариант); основное вни-
мание уделяется технологиям компиляции и оптимизации, которые использовались
в System R впервые. Частично эта статья пересекается с [4.13].
4.13. Chamberlin D.D., Gilbert А.М., Yost R.A. A History of System R and SQL / Data
System // Proc. 7th Intern. Conf, on Very Large Data Bases. — Cannes, France,
September, 1981.
Обсуждаются уроки, полученные в результате использования прототипа системы
System R, а также описывается эволюция этого прототипа до первого семейства
реляционных продуктов DB2 компании IBM, а именно — SQL/DS
(переименованного впоследствии в DB2 for VM and VSE).
4.14. Date C.J. A Critique of the SQL Database Language H ACM SIGMOD Record. —
November, 1984.— 14, №3. (Переиздано: C.J. Date. Relational Database: Selected
Writings. — Reading, Mass.: Addison-Wesley, 1986.)
Как уже подчеркивалось в этой главе, язык SQL далек от совершенства. В статье
представлен критический анализ его принципиальных недостатков (в основном,
исходя из требований к формальному компьютерному языку вообще, а не из тре-
бований к языку баз данных).
Замечание. Некоторые критические замечания из этой статьи не относятся к стан-
дарту SQL/92.
4.15. Date C.J. What’s Wrong with SQL? 11 C.J. Date. Relational Database Writings 1985—
1989. — Reading, Mass.: Addison-Wesley, 1990.
Обсуждаются некоторые недостатки языка SQL в дополнение к описанным в [4.14]
под заголовками “Недостатки собственно языка SQL”, “Недостатки стандарта
SQL” и “Переносимость приложений”.
Замечание. Некоторые критические замечания из этой статьи не относятся к стан-
дарту SQL/92.
4.16. Date C.J. SQL Dos and Don’ts // C.J. Date. Relational Database Writings 1985-1989. —
Reading, Mass.: Addison-Wesley, 1990.
В статье предложены некоторые практические советы по использованию языка
SQL таким образом, чтобы избежать потенциальных ловушек, вызванных недос-
татками этого языка, которые описаны в [4.14], [4.15], [4.18], и получить макси-
мальные преимущества по продуктивности, переносимости, связности и т.п.
4.17. Date C.J. How We Missed the Relational Boat // Relational Database Writings 1991-
1994. — Reading, Mass.: Addison-Wesley, 1995.
Краткое заключение о недостатках языка SQL, имеющих отношение к поддержке
(или отсутствию таковой) некоторых аспектов реляционной модели: структурных,
аспектов обработки и поддержки целостности.
4.18. Date C.J. Grivous Bodily Harm (в двух частях) // DBP&D. — June, 1998. — 11, № 5, 6.
Fifty Ways to Query // Web-узел DBP&D www.dbpd.com. — July, 1998.
142
Часть I. Основные понятия
Язык SQL чрезмерно избыточен в том смысле, что если не все, то большинство
простых запросов могут быть выражены различными способами. В статьях это по-
казано на примерах; также в них обсуждаются возможные последствия избыточно-
сти языка SQL. В частности показано, что предложения GROUP BY, HAVING и пере-
менные диапазонов можно с пользой исключить из языка, не потеряв при этом ни-
каких функциональных возможностей (то же самое справедливо и для конструкции
“IN <подзапрос>”).
Замечание. Все перечисленные выше конструкции поясняются в главе 7 и прило-
жении А.
4.19. Date C.J., Darwen Н. A Guide to the SQL Standard (4th edition). — Reading, Mass.:
Addison-Wesley, 1997.
Полное руководство по стандарту SQL/92, включая средства CLI и PSM. В частно-
сти, в приложении D приведены “многие аспекты стандарта, которые на сегодняш-
ний день определены неадекватно или даже неверно”.
Замечание. Публикации [4.4], [4.27] также являются руководствами по стандарту
SQL/92.
4.20. Date C.J. and Colin J.W. A Guide to DB2 (4th edition). — Reading, Mass.:
Addison-Wesley, 1993.
В книге дается обширный и детальный обзор СУБД DB2 компании IBM (по со-
стоянию на 1993 год) и некоторых ее сопутствующих продуктов. СУБД DB2, как и
SQL/DS, была основана на системе System R.
4.21. Fishman N. SQL du Jour. П DBP&D. — 1997. — 10, № 10.
Скучный обзор некоторых неточностей, найденных в SQL-продуктах, которые бы-
ли объявлены как “поддерживающие стандарт SQL”.
4.22. International Organization for Standardization (ISO): Database Language SQL. Docu-
ment ISO/IEC 9075, 1992. Также доступно как American National Standards Institute
(ANSI) Document ANSI X3.135-1992.
Оригинальное определение стандарта ISO/ANSI SQL/92 (также называемое среди
знатоков ISO/IEC 9075 или просто ISO 9075). Первоначальный документ, состоя-
щий из одной части, был со временем расширен до неограниченной серии отдель-
ных частей под общим названием “Information Technolody— Database
Languages — SQL”. На время написания книги были определены следующие части
(хотя, конечно, не все завершены).
Часть 1. Структура (SQL/Framework)
Часть 2. Основы (SQL/Foundation)
Часть 3. Интерфейс на уровне вызова (SQL/CLI)
Часть 4. Постоянные хранимые модули (SQL/PSM)
Часть 5. Связь с базовым языком (SQL/Bindings)
Часть 6. Специализация ХА (SQL/Transaction)
Часть 7. Хронологические функции (SQL/Temporal)
Часть 8. (Этой части нет)
Часть 9. Управление внешними данными (SQL/MED)
Часть 10. Связь с объектным языком (SQL/OLB)
Глава 4. Введение в язык SQL
143
Проекты SQL3, которые, как ожидается, будут утверждены в 1999 году, логически будут
входить в части 1, 2, 4 и 5. Рабочие черновики, в которых описаны эти проекты, можно
найти на Web-узле ftp://jerry.ece.umassd.edu/isowg3/dbl/BASEdocs/public.
Замечание. Стоит упомянуть, что, хотя язык SQL часто считается международным
стандартом “реляционных” баз данных, в документе стандарта это не утверждает-
ся; на самом деле в документе вообще не используется термин “реляционный”!
(Как говорилось ранее в сноске, в нем не упоминается и термин “база данных”.)
4.23. International Organization for Standardization (ISO): Information Technology — Data-
base Languages— SQL— Technical Corrigendum 2. Document ISO/IEC
9075:1992/Cor.2:1996(E).
Содержит большое количество исправлений и дополнений к начальной версии
[4.22]. К сожалению, все исправления и дополнения практически не устраняют ни
одной из проблем, указанных в [4.19].
4.24. Raymond A.L. and Daudenarde J.J. SQL and its Applications. — Englewood Cliffs, N.J.:
Prentice-Hall, 1991.
Книга о языке SQL, содержащая практические советы и инструкции (почти поло-
вина книги посвящена подробному обсуждению серии примеров применения прак-
тических приложений).
4.25. Raymond A.L. and Nilsson J.F. An Access Specification Language for Relational Data
Base System 11 IBM J.R&D. — May, 1979. — 23, № 3.
В публикации подробно рассматриваются вопросы, связанные с техникой компи-
ляции в системе System R [4.11], [4.25], [4.26]. Для любого данного SQL-оператора
оптимизатор системы генерирует программу на внутреннем языке ASL (Access
Specification Language). Этот язык используется как интерфейс между оптимизато-
ром и генератором кодов. (Генератор кодов, как следует из его названия, преобра-
зует программу на языке ASL в машинный код.) В языке ASL есть, например, опе-
раторы scan (поиск) и insert (вставить), применяемые к таким объектам, как ин-
дексы и хранимые файлы. Язык создавался, чтобы весь процесс трансляции стал
управляемым. Это достигалось путем разбиения процесса трансляции на множест-
во четко определенных подпроцессов.
4.26. Raymond A.L. and Bratford W.W. Compilation of High-Level Data Language. IBM Re-
search Report RJ2598. — August, 1979.
В системе System R впервые была применена идея компиляции запросов перед их
выполнением и рекомпиляции запросов, если физическая структура базы данных
значительно изменялась на каком-то переходном этапе. В этой статье подробно
описывается механизм компиляции и рекомпиляции, но не затрагиваются вопросы
оптимизации (эта актуальная тема освещается в [17.34]).
4.27. Melton J., Simon A.R. Understanding The New SQL: A Complete Guide. — San Mateo,
Calif.: Morgan Kaufmann, 1993.
Руководство по стандарту SQL/92 (как представлена сама книга). Один из авторов
(Melton) был редактором первоначальных спецификаций стандарта SQL/92 [4.22].
4.28. Reisner Р., Воусе R.F., Chamberlin D.D. Human Factors Evaluation of Two Data Base
Query Languages: SQUARE and SEQUEL П Proc. NCC 44. — Anaheim, Calif.;
Montvale, N.J.: AFIPS Press, May, 1975.
144
Часть I. Основные понятия
Язык SEQUEL [4.8], предшественник языка SQL, был разработан на базе более
раннего языка SQUARE. Эти два языка, в основном, совпадали, но в языке
SQUARE использовался математический синтаксис, а в языке SEQUEL — ключе-
вые слова из английского языка, такие как SELECT, FROM, WHERE и т.д. В статье при-
ведены отчеты по ряду исследований, в которых изучалась практичность этих язы-
ков; в качестве объектов использовались студенты колледжа. В результате такого
исследования в язык SEQUEL были внесены некоторые изменения [4.9].
4.29. Rozenshtein D., Abramovich A., Birger Е. Optimizing Transact-SQL: Advanced
Programming Techniques. — Fremont, Calif.: SQL Forum Press, 1995.
Язык Transact-SQL— это диалект языка SQL, который поддерживается такими
продуктами, как Sybase и SQL Server. В этой книге рассматривается ряд приемов
программирования для языка Transact-SQL, которые основаны на использовании
характеристических функций (определенных авторами как средства, позволяю-
щие программистам кодировать логические условия в виде... выражений в предло-
жениях SELECT, WHERE, GROUP BY и SET). Хотя эти идеи выражены в терминах языка
Transact-SQL, на самом деле они имеют более широкую область применения.
Замечание. Необходимо отметить, что слово “optimizing”, которое входит в назва-
ние книги, не имеет отношения к оптимизатору СУБД. Напротив, здесь подразуме-
вается оптимизация, которая может выполняться самими пользователями вручную.
Ответы к некоторым упражнениям
4.1. CREATE TABLE S
( S# CHAR(5),
SNAME CHAR(20),
STATUS NUMERIC(5),
CITY CHAR(15),
PRIMARY KEY ( S# ) ) ;
CREATE TABLE P
( P# CHAR(6),
PNAME CHAR(20),
COLOR CHAR(6),
WEIGHT NUMERIC(5,1),
CITY CHAR(15),
PRIMARY KEY ( P# ) ) ;
CREATE TABLE J
( J# CHAR(4),
JNAME CHAR(20),
CITY CHAR(15),
PRIMARY KEY ( J# ) ) ;
CREATE TABLE SPJ
( S# CHAR(5),
P# CHAR(6),
Глава 4. Введение в язык SQL
145
J# CHAR(4),
QTY NUMERIC(9),
PRIMARY KEY ( S#, P#, J# ),
FOREIGN KEY ( S# ) REFERENCES S,
FOREIGN KEY ( P# ) REFERENCES P,
FOREIGN KEY ( J# ) REFERENCES J ) ;
4.4. Ниже приведены ответы к отдельным пунктам упражнения.
a) INSERT INTO S (S#, SNAME, CITY )
VALUE ( 'S10', 'Smith', 'New York' ) ;
Значение столбца STATUS здесь установлено равным значению по умолчанию.
б) UPDATE Р
SET COLOR = 'Orange'
WHERE COLOR = 'Red' ;
в) DELETE
FROM J
WHERE J# NOT IN
( SELECT J#
FROM SPJ ) ;
Обратите внимание на вложенный подзапрос и оператор IN (а точнее, на отрица-
ние оператора IN) в ответе в. Такие подзапросы рассматриваются в главе 7.
4.5. Отметим, что могут существовать поставщики, которые не поставляют деталей ни
для одного проекта; в следующем ответе рассматриваются именно такие постав-
щики (только такие?). Сначала определим два курсора, CS и CJ.
EXEC SQL DECLARE CS CURSOR FOR
SELECT S.S#, S.SNAME, S.STATUS, S.CITY
FROM S
ORDER BY S# ;
EXEC SQL DECLARE CJ CURSOR FOR
SELECT J.J#, J.JNAME, J.CITY
FROM J
WHERE J.J# IN
( SELECT SPJ.J#
FROM SPJ
WHERE SPJ.S# = :CS S# )
ORDER BY J# ;
(Снова обратите внимание на вложенный подзапрос и оператор IN.)
Когда курсор CJ открыт, базовая переменная CSJ5# содержит значение номера по-
ставщика, получаемое с помощью курсора CS. Логика процедуры, по существу,
следующая.
146
Часть I. Основные понятия
EXEC SQL OPEN CS ;
DO <для всех строк S, доступных через С8>’,
EXEC SQL FETCH CS INTO :CS S#, :CS SN, :CS ST, :CS SC ;
print CS S#, CS SN, CS ST,“CS SC
EXEC SQL“OPEN CJ ;
DO <для всех строк J, доступных через CJ>',
EXEC SQL FETCH CJ INTO :CJ_J#, :CJ JN, :CJ JC ;
print CJ_J#, CJ_JN, CJ_JC ”
END DO
EXEC SQL CLOSE CJ ;
END DO ;
EXEC SQL CLOSE CS ;
4.6. Это хороший пример задачи, которую с помощью языка SQL в его обычной форме
решить полностью нельзя. Нужно “разобрать” данную деталь на п уровней при ус-
ловии, что п во время написания программы неизвестно. Сравнительно простой
способ формирования таких п уровней (если бы это было возможно) мог бы быть
реализован с помощью рекурсивной программы, в которой каждый рекурсивный
вызов создает новый курсор, как показано ниже.
CALL RECURSION ( GIVENPj ) ;
RECURSION: PROC ( UPPER_P# ) RECURSIVE ;
DCL UPPER_P# ... ;
DCL LOWER_P# ;
EXEC SQL DECLARE C "reopenable" CURSOR FOR
SELECT MINOR_P#
FROM PART_STRUCTURE
WHERE MAJOR_P# = :UPPER P# ;
print UPPER_P# ;
/* вывести значение UPPER_P# */
EXEC SQL OPEN C ;
DO <для всех строк PART_STRUCTURE, доступных через С> ;
EXEC SQL FETCH C INTO :LOWER_P# ;
CALL RECURSION ( LOWER_P# ) ;
END DO ;
EXEC SQL CLOSE C ;
END PROC ;
Здесь подразумевается, что фиктивная спецификация “reopenable” (“повторно от-
крываемый”) в операторе DECLARE CURSOR означает допустимость операции OPEN
даже в том случае, если курсор уже открыт. В результате такой операции создается
новый экземпляр курсора для данного табличного выражения (использующего те-
кущие значения любых базовых переменных, на которые есть ссылки в этом вы-
ражении). Далее подразумевается, что ссылки на такой курсор в операторе FETCH и
других являются ссылками на “текущий” экземпляр и что оператор CLOSE уничто-
жает именно этот экземпляр и восстанавливает предыдущий экземпляр как
Глава 4. Введение в язык SQL
147
“текущий”. Другими словами, подразумевается, что повторно открываемый курсор
формирует стек, который обслуживается операторами OPEN и CLOSE так же, как
обычный стек обрабатывается операторами push и pop.
К сожалению, подобные допущения на сегодняшний день чисто гипотетические. В
языке SQL пока нет таких средств, как повторно открываемый курсор (в действи-
тельности попытка повторно открыть курсор приведет к ошибке). Приведенный код
недопустим. Но этот пример наглядно показывает, что “повторно открываемые кур-
соры” были бы очень полезным дополнением к современному варианту языка SQL.
Поскольку предыдущая процедура не справляется с поставленной задачей, мы
вкратце приведем одну из возможных процедур (но не наиболее эффективную),
которая позволяет решить задачу.
CALL RECURSION ( GIVENP# ) ;
RECURSION: PROC ( UPPER_Pj ) RECURSIVE ;
DCL UPPER_P# ;
DCL LOWER_Pj ... INITIAL ( ' ' );
EXEC SQL DECLARE C CURSOR FOR
SELECT MIN0R_P#
FROM PART_STRUCTURE
WHERE MAJ0R_P# = :UPPER_P#
AND MINOR P# > :LOWER_P#
ORDER BY MINOR_P# ;
print UPPER_P# ;
DO <без ограничений ;
EXEC SQL OPEN C ;
EXEC SQL FETCH C INTO :LOWER_P# ;
EXEC SQL CLOSE C ;
IF <нет выбранных lower P#> THEN RETURN ; END IF ;
IF <есть выбранные lower THEN
CALL RECURSION ( LOWER_P# ) ; END IF ;
END DO ;
END PROC ;
Заметьте, что в этом решении один и тот же курсор используется в каждом вызове
подпрограммы RECURSION (но каждый раз при ее вызове динамически создаются но-
вые экземпляры переменных UPPER_Pj и LOWER_Pj, причем в конце вызова эти экзем-
пляры уничтожаются). В связи с данным фактом мы использовали следующий трюк.
... AND MINOR_P# > :LOWER_P# ORDER BY MINOR_P#
Так что при каждом вызове подпрограммы RECURSION все промежуточные компо-
ненты (LOWER_Pj) текущего значения UPPER_Pj, которые уже были обработаны,
просто игнорируются.
Обсуждение некоторых альтернативных подходов к этой задаче вы найдете в [4.5],
[4.7]. В главе 6 (в конце раздела 6.7) описывается оператор, имеющий отношение к
данному вопросу. Он называется транзитивным замыканием (transitive closure). В
приложении Б приводится обзор некоторых возможностей в стандарте SQL3, ко-
торые также имеют отношение к данной проблеме.
148
Часть I. Основные понятия
Часть II
Реляционная модель
Основой современной технологии баз данных, конечно же, является реляционная мо-
дель. Именно она делает область технологии баз данных наукой. Поэтому любое описа-
ние этой области, не охватывающее описание реляционной модели, может быть лишь
поверхностным. Точно так же знания, умения и опыт в области баз данных нельзя при-
знать удовлетворительными, если человек не имеет глубокого и ясного представления о
реляционной модели. Поспешим добавить: мы вовсе не хотим сказать, что этот материал
труден для понимания; просто он представляет собой основу и, без сомнения, будет ос-
таваться ею в обозримом будущем.
Как уже отмечалось в главе 3, в реляционной модели рассматриваются три прин-
ципиальных аспекта данных — структура данных, манипулирование данными и
поддержание целостности данных. В этой части книги обсуждается каждый из трех
указанных аспектов по очереди: в главе 5 — структура данных, в главах 6 и 7 — ма-
нипулирование данными и в главе 8 — целостность данных. (Обработке данных по-
священо две главы, поскольку эта часть реляционной модели может быть реализо-
вана двумя разными, но эквивалентными способами, известными как реляционная
алгебра и реляционное исчисление соответственно.) Наконец, предметом обсуждения
в главе 9 будут представления.
Важно понимать, что реляционная модель не статична, она изменялась с течением
времени и, конечно же, продолжает изменяться1. Определения, описания и объяснения в
следующих главах отвечают современным взглядам автора книги и других специалистов
в этой области (в частности, как упоминалось в предисловии, большое влияние на со-
держание настоящей книги оказали идеи другой выпущенной автором книги — The Third
Manifesto [3.3]). Автор не считает, что обсуждаемая тема освещена здесь достаточно
полно, а определения и выводы совершенны, хотя изложение материала выдержано в пе-
дагогическом стиле. Поэтому читатель не должен воспринимать последующий материал
как последнее слово в данной области.
Как было отмечено выше, реляционная модель не очень сложна для понимания. Но
она является теорией, а в большинстве теорий используется собственная специальная
терминология. И реляционная модель не является исключением (по причинам, указан-
ным в разделе 3.3). В настоящей части книги мы, конечно же, будем использовать имен-
1 В этом отношении она напоминает математику (математика также не статична и по-
стоянно развивается на протяжении многих веков). Фактически саму реляционную модель мож-
но рассматривать как раздел математики.
149
но эту специальную терминологию. Нельзя отрицать, что она может поначалу сбивать
читателя с толку, но наберитесь терпения: освоив терминологию, вы сразу же обнаружи-
те, что все понятия очень просты и ясны.
Как можно видеть, главы этой части имеют довольно большой объем (данная
часть — практически книга в книге). Однако такой объем соответствует важности об-
суждаемого материала и необходимости предоставить его расширенное (или даже ис-
черпывающее) изложение. Возможно, читатель предпочтет читать по одному разделу
за раз, а не по одной главе. Конечно, можно было представить обзор реляционной мо-
дели на одной или двух страницах. В действительности основная сила реляционного
подхода состоит в том, что ее главные идеи можно легко объяснить и понять. Однако
одно- или двухстраничное изложение не позволит полностью раскрыть все стороны
предмета и проиллюстрировать обширные возможности его применения. Значитель-
ный объем этой части не следует считать следствием сложности модели; скорее, это
дань важности излагаемого материала и тому, что он является основой для многочис-
ленных перспективных разработок.
И наконец, несколько слов относительно языка SQL. Как мы уже говорили в части I,
язык SQL — это стандартный “реляционный” язык баз данных и практически все имею-
щиеся сегодня на рынке СУБД его поддерживают, а точнее — некоторый его диалект
(см. [4.21]). И поэтому ни один современный учебник по базам данных нельзя назвать
полным, если в нем отсутствует достаточно пространное изложение основ языка SQL. В
следующих главах, раскрывающих различные аспекты реляционной модели, одновре-
менно будут рассмотрены соответствующие возможности языка SQL (основные его по-
нятия уже приводились в главе 4).
150
Часть II. Реляционная модель
Глава
Домены, отношения
и базовые переменные-
отношения
5.1. Введение
Как упоминалось в главе 3, реляционная модель состоит из трех основных частей, ка-
сающихся структуры, целостности данных и манипулирования ими соответственно. Каж-
дая часть имеет свою терминологию. Наиболее важные термины описания структуры
данных представлены на рис. 5.1 (на нем показано отношение поставщиков для базы дан-
ных поставщиков и деталей (см. рис. 3.8), расширенное таким образом, чтобы были видны
используемые типы данных и домены). Терминами здесь являются отношение, кортеж,
кардинальность (количество записей), атрибут, степень, домен и первичный ключ.
Рис. 5.1. Термины, используемые для описания структуры данных
Термины отношение и первичный ключ уже должны быть вам знакомы из главы 3.
Сейчас мы объясним значения остальных терминов на понятийном уровне, а затем в со-
ответствующих разделах дадим их более формальные определения. Итак, если рассмат-
Глава 5. Домены, отношения и базовые переменные-отношения
151
ривать отношение как таблицу, то кортежам будут соответствовать строки этой табли-
цы, а атрибутам — ее столбцы. Количество кортежей в таблице называется ее карди-
нальностью, а количество атрибутов — степенью. Домен — это совокупность значе-
ний, из которой берутся значения для определенных атрибутов определенного отноше-
ния. Например, домен, обозначенный на рис. 5.1 как S#, — это множество всех допусти-
мых номеров поставщиков, и каждое значение, принимаемое атрибутом S#, принадлежит
этому множеству (аналогично каждое значение атрибута S# в отношении поставок (см.
рис. 3.8) также принадлежит этому множеству).
Все сказанное ранее подытожено на рис. 5.2. Однако следует отметить, что эти поня-
тия “эквивалентны” показанным на рисунке только приблизительно (и каждый из терми-
нов имеет точное определение). Так, “отношение” и “таблица” — это не одно и то же,
хотя, как вы знаете из части I, на практике данные понятия часто отождествляются.
Формальный реляционный термин Неформальный эквивалент
отношение кортеж кардинальность атрибут степень первичный ключ домен таблица строка или запись количество строк столбец или поле количество столбцов уникальный идентификатор совокупность допустимых значений
Рис. 5.2. Термины, использующиеся для описания структуры таблиц баз данных
5.2. Домены
Домен — это не что иное, как тип данных (или, для краткости, — просто тип)', в
частности, возможно, простой, определяемый системой, подобно типам INTEGER и
CHAR. В общем случае этот тип определяется пользователем, как, например, типы S#,
Р#, WEIGHT и QTY в базе поставщиков и деталей. В действительности термины домен и
тип данных взаимозаменяемы, и в этой книге будут использоваться оба термина (хотя
нам больше нравится термин тип', термин домен будет употребляться, в основном, как
дань истории).
Итак, что же такое тип? Прежде всего, это множество значений — всех возможных
значений рассматриваемого типа. Например, тип INTEGER — это множество всех целых
чисел, тип S# — множество всех номеров поставщиков и т.д. Говоря о каком-либо типе
данных, мы не должны также забывать о допустимых операторах, которые могут кор-
ректно применяться к значениям этого типа. Другими словами, значениями заданного
типа можно манипулировать только с помощью операторов, определенных для этого
типа. Рассмотрим, например, тип INTEGER (который для простоты будем считать опреде-
ляемым системой).
Для сравнения целых чисел системой предоставляются операторы “=”, “<” и т.д.
Арифметические действия над целыми числами выполняются с помощью опера-
торов и т.д.
152
Часть II. Реляционная модель
Этот тип данных не поддерживает такие операторы, как “| |” (конкатенация),
SUBSTR (выделение подстроки) и т.д. Другими словами, операторы манипулирова-
ния строками к целым числам неприменимы.
Многие системы позволяют определять собственные типы, как, например, тип S#.
Возможно, нам понадобится определить операторы “=” и “<” для сравнения номеров по-
ставщиков. С другой стороны, для данного типа наверняка не потребуется определять
операторы “+” и Это означает, что выполнение арифметических действий над номе-
рами поставщиков поддерживаться не будет (действительно, зачем может потребоваться
складывать или перемножать номера поставщиков?).
Тем не менее следует различать типы данных сами по себе и физическое пред-
ставление значений этих типов внутри системы2. (Фактически типы являются моде-
лями, в то время как физическое представление значений — это их реализация.} На-
пример, номера поставщиков физически могут быть представлены как символьные
строки, однако это не значит, что над ними можно выполнять те же операции, что и
над строками. Выполнение любых операций возможно лишь в том случае, если для за-
данного типа были определены соответствующие операторы. И безусловно, опреде-
ляемые для заданного типа операторы должны зависеть от реального смысла или се-
мантики рассматриваемого типа и ни в коем случае не от его физической реализации.
Более того, физическое представление типа должно быть скрыто настолько, насколь-
ко в этом заинтересован пользователь.
К настоящему моменту вы, должно быть, уже догадались, что предметом нашего об-
суждения является то, что в программировании называется строгим контролем типов
или строгой типизацией. Разные авторы определяют этот термин несколько по-
разному. Мы же дадим ему следующее определение: строгий контроль типов имеет ме-
сто, если каждое значение принадлежит какому-либо типу и при выполнении любой
операции система проверяет, принадлежит ли каждый из операндов этой операции до-
пустимому для нее типу. Рассмотрим, например, следующие выражения.
Р.WEIGHT + SP.QTY /* Вес детали плюс количество деталей */
Р.WEIGHT * SP.QTY /* Вес детали, умноженный на количество деталей */
Первое выражение не имеет никакого смысла, поэтому система должна его отверг-
нуть. Второе выражение имеет смысл — оно дает суммарный вес всех деталей конкрет-
ной поставки. Таким образом, определяя операторы для веса и количества деталей (в со-
четании), следует включить в определение оператор но нет необходимости опреде-
лять оператор “+”.
Ниже приводится еще один пример, на этот раз для операторов сравнения (в частно-
сти, для оператора равенства).
Р.WEIGHT = SP.QTY
P.CITY = S.CITY
2 В литературе типы иногда называют абстрактными типами данных. Это делается для
того, чтобы подчеркнуть различие между типом и его физической реализацией. Однако здесь
данный термин использоваться не будет, поскольку это предполагало бы существование других
типов, не "абстрактных” в указанном смысле, тогда как мы считаем, что различать тип и его
физическую реализацию необходимо всегда.
Глава 5. Домены, отношения и базовые переменные-отношения
153
И в этом случае первое выражение, в отличие от второго, смысла не имеет. Таким об-
разом, оператор “=” для веса и количества деталей (в сочетании) определять наверняка
не следует, тогда как для сравнения городов он, скорее всего, понадобится3. (Здесь мы
придерживаемся мнения, высказанного в [3.3] и состоящего в том, что для каждого типа
должен быть определен оператор “=”, поскольку всегда должна существовать возмож-
ность проверки, совпадают ли два заданных значения одного и того же типа.)
Следует отметить тот факт, что выше ничего не было сказано о природе значений,
составляющих тип данных. Фактически они могут быть произвольными. Мы склонны
считать, что они являются простейшими, как, например, числа или строки, однако ничто
в реляционной модели не запрещает им иметь более сложный вид. Можно использовать
домены, состоящие из аудио- и видеозаписей, карт, чертежей, архитектурных планов,
представлений геометрических точек и т.д. Единственное требование, которому должны
удовлетворять эти значения, следующее: манипулирование ими может осуществляться
исключительно посредством операторов, определенных для рассматриваемого домена
(физическая реализация должна быть скрыта).
Вышесказанное имеет очень большое значение и очень часто понимается неправиль-
но, поэтому мы выскажем эту мысль еще раз другими словами.
Вопрос о том, какие типы данных поддерживаются, ортогонален
вопросу о поддержке реляционной модели.
Каждое значение имеет тип
Каждое значение данных обязательно имеет некоторый тип. Другими словами, если
V— значение, то оно как бы обладает неким признаком, который гласит: “Я— целое
число” или “Я — номер поставщика”, или “Я — геометрическая точка”. Заметьте, что по
определению заданное значение обязательно принадлежит лишь одному типу4 и никогда
не может изменить свой тип (отсюда следует, что разные типы данных никогда не пере-
секаются, т.е. не имеют общих значений).
Каждый тип данных может быть либо скалярным, либо нескалярным. Нескалярны-
ми являются все типы, явно определенные таким образом, что в них есть компоненты,
видимые для пользователя. В частности, в этом смысле нескалярными являются типы
отношений. Например, отношение, представленное на рис. 5.1, принадлежит определен-
ному типу и этот тип, несомненно, имеет видимые компоненты (а именно — атрибуты
S#, SNAME, STATUS и CITY). Скалярные же типы, напротив, видимых пользователю ком-
понентов не имеют. Подведем итоги.
1. В оставшейся части этого раздела все рассматриваемые типы будут скалярными, и
поэтому, употребляя термин тип, мы будем подразумевать именно скалярный тип.
3 В отношении вопроса о том, какие операторы и для каких типов являются допустимыми,
нами замечено, что исторически в большинстве изданий по базам данных, в том числе в несколь-
ких первых изданиях этой книги, рассматриваются операторы сравнения и т.д.) и не
рассматриваются другие операторы, подобные и
4 За исключением тех случаев, когда имеет место поддержка наследования типов. До гла-
вы 19 эта возможность рассматриваться не будет.
154
Часть II Реляционная модель
2. Физическое представление заданного скалярного значения, т.е. заданное значение за-
данного скалярного типа, может быть произвольно сложным. В частности, оно может
быть составным (однако его компоненты не могут быть видимы пользователю). На-
пример, при определенных обстоятельствах заданное скалярное значение может
иметь физическое представление в виде массива стеков списков символьных строк.
3. Из-за того что скалярные типы не имеют видимых компонентов, их иногда назы-
вают инкапсулированными (скрытыми). Также иногда используется термин ато-
марный тип. Однако мы предпочитаем не употреблять подобные термины, по-
скольку в прошлом из-за них возникало множество недоразумений (поспешим до-
бавить, что и по нашей собственной вине). В частности, путаница возникает при
разграничении модели и ее реализации, а также при разграничении типа данных и
его представления.
4. Как вы вскоре убедитесь, скалярные типы имеют так называемые допустимые
представления, а допустимые представления, в свою очередь, обязательно имеют
видимые компоненты. Обратите внимание на то, что в данном случае видимые
компоненты являются компонентами не типа, а его допустимого представления.
Тип данных всегда остается скалярным в смысле приведенного выше определения.
Определение типа
В этой книге мы часто будем использовать язык Tutorial D (вернее, некоторую его
версию), впервые применявшийся в главе 3 для иллюстрации излагаемых в ней идей. В
общих чертах язык Tutorial D напоминает язык Pascal. Мы будем знакомить вас с этим
языком по мере его использования. Первое, для чего он нам потребуется, — для получе-
ния средства определения собственных типов.
TYPE <имя типа> возможное представлений ...;
В качестве примера рассмотрим определения типов для базы данных поставщиков и
деталей (см. рис. 3.9).
TYPE S# TYPE NAME TYPE P# POSSREP (CHAR) ; POSSREP (CHAR) ; POSSREP (CHAR) ;
TYPE COLOR POSSREP (CHAR) ;
TYPE WEIGHT POSSREP (RATIONAL)
TYPE QTY POSSREP (INTEGER)
Пояснения
1. Поскольку из главы 3 следует, что атрибут поставщиков STATUS и атрибут поставщи-
ков и деталей CITY определяется с помощью встроенных типов, а не типов, опреде-
ленных пользователем, определение типов для указанных атрибутов отсутствует.
2. Как мы уже видели, физическое представление типа скрыто от пользователя. Соот-
ветственно приведенные выше определения типов не содержат никакой информации
об их физическом представлении. Фактически эти представления должны задаваться
как часть отображения “концептуальный-внутренний” (см. главу 2, раздел 2.6).
Глава 5. Домены, отношения и базовые переменные-отношения
155
Обязательным является наличие у каждого типа данных хотя бы одного допусти-
мого представления по причине, рассматриваемой в следующем разделе. Напри-
мер, значения типов S#, NAME, P# и COLOR можно представить в виде строк симво-
лов, а значение типа WEIGHT — в виде рационального числа.
Замечание. В этой книге (следуя рекомендациям из [3.3]) вместо привычного на-
звания встроенного типа REAL будет использоваться более точное название —
RATIONAL.
3. Здесь принимаются очевидные синтаксические соглашения, суть которых состоит в
следующем: неименованные допустимые представления наследуют имя соответст-
вующих типов, а компоненты неименованных допустимых представлений насле-
дуют имена соответствующих представлений. Например, единственное допустимое
представление, определенное для типа QTY, также называется QTY; то же самое от-
носится к единственному компоненту данного возможного представления.
4. При определении нового типа система делает в каталоге запись, содержащую опи-
сание этого типа (чтобы вспомнить некоторые детали, касающиеся каталогов, воз-
вратитесь к разделу 3.6 главы 3). То же самое происходит при определении опера-
тора (об этом рассказывается в двух следующих разделах).
5. Возможно, вы заметили, что в приведенных выше определениях типов не задаются
фактические значения, составляющие конкретный тип. Эту функцию выполняют
наложенные на тип ограничения (то, что находится в круглых скобках в приведен-
ном выше примере описания типов), которые будут рассмотрены в главе 8.
Если какой-либо тип данных больше не нужен, от него, конечно же, можно избавиться.
DROP TYPE <нмя типа> ;
В приведенном выше операторе параметр <имя типа> должен задавать имя типа дан-
ных, определенного пользователем, но не имя какого-либо встроенного типа. В резуль-
тате выполнения этого оператора из каталога удаляется запись, описывающая рассмат-
риваемый тип данных, после чего он перестает быть известным системе.
Замечание. Для простоты будем считать, что оператор DROP TYPE не выполняется, ес-
ли удаляемый тип данных в текущий момент где-либо используется, например если на
основе этого типа определен атрибут некоторого отношения.
Допустимые представления
Для того чтобы продемонстрировать важность понятия “допустимое представление”,
рассмотрим несколько более сложных примеров.
TYPE POINT /* геометрические точки */
POSSREP CARTESIAN ( X RATIONAL, Y RATIONAL )
POSSREP POLAR ( R RATIONAL, THETA RATIONAL ) ;
В первую очередь, следует отметить, что тип POINT имеет два разных допустимых
представления, CARTESIAN и POLAR, отображающих тот факт, что точку на плоскости
можно задать либо в декартовых, либо в полярных координатах. (Безусловно, физиче-
ское представление этого типа в конкретной системе на самом деле может быть выпол-
нено в декартовых координатах, в полярных координатах или посредством некоторого
156
Часть II. Реляционная модель
совершенно иного метода.) Каждое из этих представлений, в свою очередь, имеет по два
компонента. Обратите внимание на то, что в отличие от предыдущего примера здесь яв-
но задаются имена как допустимых представлений, так и их компонентов.
При каждом объявлении допустимого представления автоматически5 определяются
два более или менее очевидных оператора.
Оператор выбора (selector) (с тем же именем, что и имя допустимого представле-
ния), который предоставляет пользователю средство задания или выбора значения
рассматриваемого типа, осуществляемого посредством присваивания значений
каждому компоненту данного допустимого представления.
Набор операторов ТНЕ_ (по одному оператору для каждого компонента допусти-
мого представления), обеспечивающих доступ к соответствующему компоненту
данного допустимого представления.
Рассмотрим на примере использование оператора выбора и оператора ТНЕ_ для ти-
па POINT.
CARTESIAN ( 5.0, 2.5 ) /* Задает точку с координатами х = 5.0, у = 2.5
CARTESIAN ( XXX, YYY ) /* Задает точку с координатами х = XXX, у = YYY
/* Здесь XXX и YYY - переменные типа RATIONAL */
POLAR ( 2.7, 1.0 ) /* Задает точку с г = 2.7 и theta =1.0 */
THE_X ( P ) /* Возвращает координату х точки Р */
/* Здесь Р - переменная типа POINT */
THE_R ( P ) /* Возвращает координату г точки Р */
Замечание. Очевидным является тот факт, что оператор выбора— это обобщение
уже знакомого нам понятия литерал (literal).
Для того чтобы увидеть, как все вышесказанное работает на практике, будем считать,
что физическим представлением значения типа POINT являются фактические декартовы
координаты точки (хотя в общем случае физическое представление может быть произ-
вольным). Кроме того, допустим, что для описания этого физического представления
системой предоставляются специальные защищенные операторы (выделенные курсивом),
которые затем будут использованы определителем типа для реализации операторов вы-
бора6 CARTESIAN и POLAR, как, например, показано ниже.
OPERATOR CARTESIAN ( X RATIONAL, Y RATIONAL ) RETURNS ( POINT ) ;
BEGIN;
VAR P POINT;
Х-компонент физического представления P := X ;
Y-компонент физического представления Р := Y ;
5 Здесь слово “автоматически ” означает следующее. Во-первых, кто бы ни определял допус-
тимое представление (реальный пользователь или система), он также отвечает за определение
соответствующих операторов. Во-вторых, до того момента, пока не будут определены указан-
ные операторы, процесс определения соответствующего допустимого представления считать
завершенным нельзя.
6 Очевидно, что определитель типа является исключением из общего правила, гласящего, что
пользователи не осведомлены о физическом представлении типа.
Глава 5. Домены, отношения и базовые переменные-отношения
157
RETURN ( P ) ;
END ;
END OPERATOR ;
OPERATOR POLAR ( R RATIONAL, THETA RATIONAL ) RETURNS ( POINT ) ;
RETURN ( CARTESIAN ( R * COS ( THETA ),
R * SIN ( THETA ) ) ) ;
END OPERATOR ;
Обратите внимание на то, что при определении оператора POLAR используется опера-
тор выбора CARTESIAN, а также встроенные операторы SIN и COS. Оператор POLAR можно
определить и по-другому, непосредственно с помощью защищенных операторов.
OPERATOR POLAR ( R RATIONAL, THETA RATIONAL ) RETURNS( POINT ) ;
BEGIN;
VAR P POINT ;
Х-компонент физического представления P := R * COS ( THETA ) ;
Y-компонент физического представления P := R * SIN ( THETA ) ;
RETURN ( P ) ;
END ;
END OPERATOR ;
Защищенные операторы используются также определителем типа для реализации не-
обходимых операторов ТНЕ__.
OPERATOR ТНЕ_Х ( Р POINT ) RETURNS ( RATIONAL ) ;
RETURN ( ^-компонент физического представления Р ) ;
END OPERATOR ;
OPERATOR THE__Y ( P POINT ) RETURNS ( RATIONAL ) ;
RETURN ( Y-компонент физического представления P ) ;
END OPERATOR ;
OPERATOR THE R ( P POINT ) RETURNS ( RATIONAL ) ;
RETURN ( SQRT ( THE X ( P ) ** 2+ THE Y ( P ) ** 2 ) ) ;
END OPERATOR ;
OPERATOR THE THETA ( P POINT ) RETURNS ( RATIONAL ) ;
RETURN ( ARCTAN ( THE Y ( P ) / THE X ( P ) ) ) ;
END OPERATOR ;
Здесь при определении операторов THE_R и THE THETA используются операторы ТНЕ_Х
и THE Y, а также (встроенные по предположению) операторы SQRT и ARCTAN. Операторы
THE_R и THE THETA также можно определить непосредственно в терминах защищенных
операторов. Предлагаем читателю сделать это самостоятельно в качестве упражнения.
На этом наше пространное обсуждение типа POINT можно считать завершенным. Од-
нако следует понимать, что все вышесказанное применимо и к более простым типам, на-
пример к таким, как тип QTY. Вот несколько примеров использования оператора выбора
для этого типа.
158
Часть II. Реляционная модель
QTY (100)
QTY (Q)
QTY ( ( QI - Q2 ) * 2 )
Операторы THE_ этого типа могут использоваться следующим образом.
THE_QTY ( Q )
THE_QTY ( ( Q1 - Q1 ) * 2 )
Отметим, в частности, что, поскольку каждое значение всегда принадлежит ка-
кому-либо типу, совершенно некорректно говорить, например, что количество дета-
лей определенной поставки равно 100. Количество деталей — это значение типа QTY,
а не INTEGER! В этом случае более правильно было бы сказать, что количество дета-
лей равно QTY(IOO), а не просто 100. В неформальном контексте мы часто не забо-
тимся о такой точности и употребляем число 100 как удобное сокращение для опе-
ратора выборки QTY(100)7. В частности, подобные сокращения использовались на
рис. 3.8 (база данных поставщиков и деталей) и на рис. 4.5 (база данных поставщи-
ков, деталей и проектов).
В завершение приведем пример определения типа LINESEG (отрезок).
TYPE LINESEG POSSREP ( BEGIN POINT, END POINT ) ;
Допустимые представления можно, конечно же, определять не только в терминах
встроенных типов (как во всех предыдущих примерах), но и с помощью типов, опреде-
ленных пользователем, так как это сделано в данном случае.
Определение операторов
В этом разделе особое внимание будет уделено определению операторов. Для этого
рассмотрим еще несколько примеров. В первом примере определяется пользовательский
оператор для встроенного типа RATIONAL.
OPERATOR ABS ( Z RATIONAL ) RETURNS ( RATIONAL ) ;
RETURN(CASE
WHEN Z > 0.0 THEN +Z
WHEN Z < 0.0 THEN -Z
END CASE ) ;
END OPERATOR ;
Оператор ABS (модуль числа) определен для одного параметра Z типа RATIONAL и воз-
вращает значение того же типа (другими словами, такое выражение, как ABS (АМТ1 - .
АМТ2), принадлежит типу RATIONAL).
7 В контексте языка SQL мы делаем то же самое, но по другой причине, а именно — потому,
что в языке SQL не поддерживаются (пока) типы, определенные пользователем (см. приложе-
ние Б).
Глава 5. Домены, отношения и базовые переменные-отношения
159
В следующем примере для определения оператора DIST (вычисления расстояния ме-
жду двумя точками) применяются типы данных, установленные пользователем.
OPERATOR DIST ( Pl POINT, P2 POINT ) RETURNS ( LENGTH ) ;
RETURN ( WITH THE_X( Pl ) AS XI ,
THE_X( P2 ) AS X2 ,
THE_Y( Pl ) AS Y1 ,
THE_Y( P2 ) AS Y2 :
LENGTH ( SQRT ( ( XI - X2 ) ** 2 + ( Y1 - Y2 ) ** 2 ) ) ) ;
END OPERATOR ;
Здесь предполагается, что LENGTH — это определенный пользователем тип с допусти-
мым представлением RATIONAL. Обратите внимание на то, что для использования в соот-
ветствующих выражениях сокращенных имен употребляется предложение WITH.
В следующем примере рассмотрен оператор равенства “=” для типа POINT.
OPERATOR EQ ( Pl POINT, P2 POINT ) RETURNS ( BOOLEAN ) ;
RETURN ( THE X ( Pl ) = THE_X ( P2 ) AND
THE^Y ( Pl ) = THE Y ( P2 ) ) ;
END OPERATOR ;
Обратите внимание, что в выражении оператора RETURN используется встроенный
оператор “=” для типа RATIONAL. Далее с целью упрощения будем считать, что обычное
инфиксное обозначение “=” используется для оператора равенства (для всех типов, в ча-
стности и для типа POINT). Практическое определение данного инфиксного обозначения
рассматриваться не будет, поскольку это всего лишь вопрос синтаксиса.
Оператор “<” для типа QTY определяется следующим образом.
OPERATOR LT (QI QTY, Q2 QTY ) RETURNS ( BOOLEAN ) ;
RETURN ( THE_QTY ( QI ) < THE QTY ( Q2 ) ) ;
END OPERATOR ;
Здесь в выражении оператора RETURN используется встроенный оператор “<” для типа
INTEGER. И опять же, с этого момента и далее будем считать, что обычное инфиксное
обозначение “<” используется для этого оператора по отношению ко всем
“упорядоченным” типам, каковым, в частности, является и тип QTY. (По определению
упорядоченным типом называется тип, для которого применим оператор Про-
стейшим примером неупорядоченного типа может служить тип POINT.)
Рассмотрим пример определения оператора обновления (во всех предыдущих приме-
рах операторы были операторами считывания^ Мы увидим далее, что в теле определе-
ния таких операторов вместо слова RETURNS используется слово UPDATES. Операторы об-
новления значений не возвращают и должны активизироваться с помощью явных вызо-
вов CALL [3.3].
8 Операторы считывания и обновления также называются наблюдателями и мутаторами
соответственно, особенно в объектных системах (см. часть IVэтой книги).
160
Часть II. Реляционная модель
OPERATOR REFLECT ( P POINT ) UPDATES ( P ) ;
BEGIN ;
THE_X ( P ) := - THE_X ( P ) ;
THE_Y ( P ) := - THE_Y ( P ) ;
RETURN ;
END ;
END OPERATOR ;
Оператор REFLECT отображает точку с декартовыми координатами (х,у) симметрично
относительно начала координат в точку (-х,-у), модифицируя соответствующим обра-
зом координаты исходной точки. Обратите внимание на использование в этом примере
выражений вида ТНЕ_псевдопеременная. ТНЕ_псевдопеременная — это обращение опе-
ратора THE к точке назначения (в частности, слева от оператора присвоения). Такое об-
ращение оператора фактически не возвращает, а назначает значение указанному компо-
ненту своего аргумента. Например, в определении оператора REFLECT выражение THE X
( Р ) :=...; фактически присваивает компоненту X некоторое значение (допустимого
декартова представления) аргумента-переменной, представленной параметром Р. Разу-
меется, для изменения любого аргумента с помощью оператора обновления, в частности
путем присвоения значения выражению ТНЕ_псевдопеременная, этот аргумент следует
определить как переменную, а не как более общее выражение.
Ниже показано, что псевдопеременные могут быть вложенными.
VAR LS LINESEG ;
ТНЕ_Х ( THE_BEGIN ( LS ) ) := 6.5 ;
Наконец, от ненужного оператора можно избавиться, как, например, показано ниже.
DROP OPERATOR REFLECT ;
Однако удаляемый таким образом оператор не может быть встроенным.
Преобразование типов
Еще раз рассмотрим следующее определение типа данных.
TYPE S# POSSREP ( CHAR ) ;
По умолчанию допустимое представление этого типа унаследует имя Si, а значит,
данное имя получит и соответствующий оператор выбора. Таким образом, следующее
выражение будет корректным.
S# ( 'S1' )
Оно возвращает номер определенного поставщика. Обратите внимание на то, что
оператор выбора S# можно рассматривать как оператор преобразования типа, который
преобразует строки в номера поставщиков. Аналогично оператор выбора P# можно рас-
сматривать как оператор преобразования строк в номера деталей, а оператор выбора
QTY — как оператор преобразования целых чисел в количество деталей и т.д.
В главе 3 приводилось несколько примеров, в которых строки сравнивались с номе-
рами деталей. Например, в упр. 3.4 присутствует следующее выражение.
...WHERE P# = 'Р2'
Глава 5. Домены, отношения и базовые переменные-отношения
161
Левая часть этого сравнения принадлежит типу Р#, а правая имеет тип CHAR. Поэтому
при сравнении (фактически во время компилирования) должна возникнуть ошибка не-
совпадения типов. Однако с концептуальной точки зрения система может “догадаться”,
что для преобразования значения в правой части сравнения (тип CHAR) в тип P# можно
использовать “оператор преобразования” Р#. В этом случае система перепишет преды-
дущее выражение следующим образом.
...WHERE P# = P# ('Р2' )
Теперь операция сравнения является корректной.
Вызов оператора преобразования в такой неявной форме называется приведением, и
мы часто, хотя и негласно, использовали этот метод в главе 3. Тем не менее известно,
что на практике использование операций приведения нередко приводит к ошибкам в
программах. По этой причине мы принимаем консервативную точку зрения, и с этого
момента использование автоматических приведений типов запрещается— операнды
всегда должны иметь соответствующие типы, а не просто быть приводимыми к этим ти-
пам. В частности, будем требовать следующее.
Величины, расположенные слева и справа от операторов “<”, “>” и “=”, должны
быть одного и того же типа.
Величины, расположенные слева и справа от оператора присвоения должны
быть одного и того же типа.
Разумеется, при необходимости для явного преобразования типов можно воспользо-
ваться так называемыми операторами CAST, как, например, показано ниже.
CAST_AS_RATZONAL ( 5 )
Как уже отмечалось, операторы выбора — по крайней мере, зависящие от одного ар-
гумента — также можно рассматривать в качестве явных операторов преобразования ти-
пов данных.
Заключительные замечания
Из всего вышесказанного о поддержке типов данных можно сделать несколько выво-
дов. Наиболее важные из них приводятся ниже.
Во-первых, наиболее важно то, что теперь система может определить, какие вы-
ражения являются допустимыми, а какие нет, и установить тип результата
выполнения любого допустимого выражения.
Во-вторых, общая совокупность всех типов данных определенной базы данных
является замкнутым множеством. Это означает, что тип результата выполнения
любого допустимого выражения принадлежит этой совокупности. В частности,
если операторы сравнения являются допустимыми, то этому замкнутому множе-
ству обязательно должен принадлежать тип boolean или значение true!
В-третьих, тот факт, что системе известны типы результатов выполнения всех до-
пустимых выражений, означает, в частности, что системе известно и то, какие
операции присвоения и сравнения допустимы.
162
Часть II. Реляционная модель
В завершение этого раздела приведем важный факт, который пригодится нам в буду-
щем. Мы сказали, что домен — это тип данных, системный или определенный пользовате-
лем, с произвольной внутренней структурой и что к значениям этого типа применимы
только определенные для него операторы (внутреннее представление типа скрыто от поль-
зователя). Теперь, если переключиться на объектно-ориентированные системы, можно
обнаружить, что фундаментальное понятие таких систем, класс объектов, — это тип дан-
ных, системный или определенный пользователем, с произвольной внутренней структурой
и что к значениям этого типа применимы только определенные для него операторы
(внутреннее представление типа скрыто от пользователя)... Другими словами, домены и
классы объектов — это одно и то же\ Данный факт является звеном, связующим две тех-
нологии — объектную и реляционную. Подробно этот важный вопрос изучается в главе 25.
5.3. Значения отношений
Как уже говорилось в главе 3, следует четко различать собственно отношения и пе-
ременные-отношения (т.е. переменные, значениями которых являются отношения). В
этом разделе рассматриваются значения отношений (для краткости— просто отноше-
ния). Переменные-отношения будут рассмотрены в следующем разделе. Прежде всего
дадим точное определение термина отношение.
Пусть задано множество из п типов или доменов 7] (/ = 1,2, ... , п), причем все они
необязательно должны быть различными. Тогда г будет отношением, определен-
ным на этих типах, если оно состоит из двух частей: заголовка и тела9, где:
а) заголовок— это множество из п атрибутов вида А\.Т\, здесь А\— имена ат-
рибутов (которые должны отличаться одно от другого) отношения г, а 1\ — со-
ответствующие имена типов (i= 1,2, ..., л);
б) тело — это множество из т кортежей /; здесь t, в свою очередь, является мно-
жеством компонентов вида А^.vj, в которых Vj — значение типа 7], т.е. значение
атрибута для атрибута А\ в кортеже t (/ = 1,2,..., п).
Значения т и п называются соответственно кардинальностью и степенью отношения г.
Из этого определения вытекает следующее.
1. В терминах таблицы, представляющей отношение, заголовок— это строка, со-
стоящая из названий столбцов и соответствующих имен типов, а тело — это мно-
жество строк данных (далее будет рассматриваться подробнее).
2. Говорят, что атрибут А, имеет тип 7] или (иногда) определен на типе Т\. Отметим,
что любое число различных атрибутов из одного отношения или из различных от-
ношений может быть одного и того же типа (см. рис. 3.8 в главе 3, рис. 4.5 и
рис. 4.6 в главе 4).
3. В любой заданный момент могут существовать значения определенного типа, не
представленные в базе данных как значение одного из атрибутов этого типа. На-
пример, значение 'Р8' может быть номером некоторой детали, хотя на рис. 3.8 де-
тали с номером ' Р8' нет.
9 Заголовок еще иногда называют схемой (отношения). Используется также термин содер-
жание (intension). В этом случае тело называется расширением (extention).
Глава 5. Домены, отношения и базовые переменные-отношения
163
4. Как сказано в определении, значение п, задающее количество атрибутов некоторо-
го отношения, называется его степенью (иногда используется термин арность). В
последнем случае отношение степени 1 называется унарным, степени 2 — бинар-
ным, степени 3 — тернарным, ..., степени п — л-арным. Таким образом, реляцион-
ная модель в общем случае имеет дело с л-арными отношениями, где п — произ-
вольное натуральное число.
5. Иногда вместо термина кортеж используется термин п-кортеж (например 4-
кортеж, 5-кортеж и т.д.), однако чаще всего префикс “и-” опускается.
6. Когда мы говорим, что Н является заголовком отношения г, то, если быть более
точным, это означает, что отношение г является отношением типа RELATION{H}
(имя этого типа именно RELATION {Н}). Дальнейшее обсуждение данного вопроса
будет продолжено в разделе 5.4.
В качестве примера рассмотрим представленную на рис. 5.1 таблицу (в этом случае
мы умышленно не называем ее отношением), чтобы проверить, насколько она соответ-
ствует данному выше определению.
В этой таблице есть четыре основных типа, а именно: тип номеров поставщиков
(S#), тип имен (NAME), тип значений статуса (STATUS) и тип названий городов
(CITY).
Замечание. Изображая отношение как таблицу на листе бумаги, мы обычно не за-
ботимся о том, чтобы показать лежащие в основе типы (как в главе 3); но следует
понимать, что, по крайней мере концептуально, они всегда есть.
В таблице действительно есть две части— строка имен столбцов и некоторое
множество строк данных. Рассмотрим вначале строку имен (или заголовков)
столбцов.
( S#, SNAME, STATUS, CITY )
Эта строка действительно представляет собой набор упорядоченных пар.
{ S# ! S#
SNAME : NAME ,
STATUS : STATUS ,
CITY : CITY }
Первый компонент каждой пары является именем атрибута, а второй — соответ-
ствующим именем типа. Поэтому можно согласиться с тем, что строка заголовков
столбцов действительно представляет собой заголовок в смысле приведенного оп-
ределения.
Замечание. Как уже отмечалось, на практике заголовок отношения обычно рассмат-
ривают как заголовок, состоящий из набора имен атрибутов (т.е. имена типов часто
опускаются), за исключением случаев, когда очень важна точность. Хотя, наверное,
эта практика несколько небрежна, она удобна, и мы часто будем ей следовать.
Что касается остальной части таблицы, то это, конечно, множество, а именно —
множество строк данных. Давайте сконцентрируем внимание на какой-нибудь од-
ной строке, например на следующей.
( SI, Smith, 20, London )
164
Часть II. Реляционная модель
Эта строка в действительности представляет собой множество упорядоченных пар.
{ S# : S# ( 'S1' ) ,
SNAME : NAME ( 'Smith' ) ,
STATUS : 20 ,
CITY : 'London' }
Первый компонент каждой пары — это имя атрибута, а второй компонент — со-
ответствующее значение атрибута. Часто в неформальном описании имена атри-
бутов опускают, поскольку мы знаем, что каждое отдельное значение в таблице в
действительности является значением того атрибута, имя которого указано в заго-
ловке соответствующего столбца. Кроме того, известно, что это значение принад-
лежит типу, положенному в основу данного атрибута. Например, значение 'S1'
(точнее, S#('S1'))— это значение атрибута S# и оно взято из соответствующего
типа, а именно — из типа номера поставщика (который также называется S#). Та-
ким образом, можно согласиться, что каждая строка представляет собой некото-
рый кортеж в смысле данного выше определения.
Из всего сказанного можно сделать вывод о том, что таблица S на рис. 5.1 может
рассматриваться как изображение отношения в смысле данного выше определения, ес-
ли условиться, как правильно “читать” такое изображение (т.е. если будут определены
правила интерпретации таких изображений). Иначе говоря, необходимо условиться,
что есть некоторые типы, лежащие в основе; каждый столбец соответствует в точности
одному из этих типов; каждая строка представляет кортеж; каждое значение атрибута
принадлежит соответствующему типу и т.д. Если принять все эти “правила интерпре-
тации”, тогда и только тогда можно будет говорить, что “таблица” — это допустимое
изображение отношения.
Теперь можно с уверенностью сказать, что отношение и таблица— это в действи-
тельности не одно и то же (хотя в предыдущих главах мы делали вид, что не знаем это-
го). Отношение — это некоторый абстрактный вид объекта, соответствующий данному
ранее определению, а таблица — это конкретное изображение (обычно на бумаге) дан-
ного абстрактного объекта. Повторим, что это не одно и то же. Конечно, они очень близ-
ки... и обычно, по крайней мере в неформальном контексте, их отождествляют, что
вполне приемлемо. Но, если говорить более формально и более точно (а сейчас мы, ко-
нечно, хотим быть более точными), следует признать, что эти два понятия не являются
идентичными.
Замечание. Если у вас возникли затруднения с пониманием идеи некоторых раз-
личий между отношением и таблицей, вам поможет следующее рассуждение. Преж-
де всего, одним из неоспоримых преимуществ реляционной модели является то, что
ее основной абстрактный объект (т.е. отношение) имеет такое простое представле-
ние на бумаге (представление в виде таблицы). Именно оно делает реляционные
системы простыми в использовании и простыми для понимания, а также упрощает
понимание поведения реляционных систем. Однако, к сожалению, табличное пред-
ставление предполагает некоторые неверные факты. К примеру, оно явно предпо-
лагает, что строки таблицы (т.е. кортежи отношения) расположены в определенном
порядке сверху вниз, хотя это неверно. Дальнейшее обсуждение этого вопроса при-
водится в следующем разделе.
Глава 5. Домены, отношения и базовые переменные-отношения
165
Свойства отношений
Отношения обладают определенными свойствами, причем все они очень важны и вы-
текают непосредственно из приведенного выше определения отношения. Сначала
вкратце перечислим эти свойства, а затем рассмотрим каждое из них более подробно.
Итак, отношения обладают следующими свойствами:
в них нет одинаковых кортежей;
кортежи отношения не имеют упорядоченности в направлении сверху вниз;
атрибуты в кортежах не упорядочены слева направо;
каждый кортеж содержит ровно одно значение для каждого атрибута.
Свойство 1. Отсутствие одинаковых кортежей
Данное свойство следует из того факта, что тело отношения — это математическое
множество (кортежей), а в математике множества по определению не содержат одинако-
вых элементов.
Замечание. На самом деле совершенно очевидно, что понятие “одинаковые кортежи”
просто бессмысленно. Рассмотрим, например, отношение с атрибутами S# и CITY
(имеется в виду, что поставщик с номером S# находится в городе CITY). Допустим, что в
этом отношении есть кортеж, отображающий тот “истинный факт”, что поставщик с но-
мером ' S1' находится в городе 'London'. Далее, если в отношении есть второй такой же
кортеж (допустим, что это возможно), то он также отображает данный “истинный факт”.
Однако, если истинное утверждение повторить два раза, более истинным оно не станет.
Между прочим, первое свойство служит хорошей иллюстрацией того факта, что от-
ношение и таблица — это не одно и то же, поскольку таблица (в общем случае) может
содержать одинаковые строки (при отсутствии правил, запрещающих это), в то время
как отношение не может содержать одинаковых кортежей в принципе. (Суть в том, что
“отношение”, содержащее одинаковые кортежи, по определению не будет отношени-
ем!) К большому сожалению, стандарт языка SQL допускает присутствие в таблицах
одинаковых строк. Здесь было бы неуместным обсуждать все причины того, почему на-
личие одинаковых строк является ошибкой (см. развернутое обсуждение этого вопроса в
[5.3], [5.6]). Для достижения наших целей достаточно остановиться на том, что реляци-
онная модель просто не допускает наличия одинаковых строк. Здесь и далее в этой книге
будет предполагаться, что одинаковые строки отсутствуют. (Это замечание касается, в
основном, языка SQL. При рассмотрении самой реляционной модели, конечно, никаких
предположений делать не нужно.)
Свойство 2, Отсутствие упорядочения кортежей (сверху вниз)
Данное свойство также следует из того, что тело отношения — это математическое
множество, а простые множества в математике не упорядочены. К примеру, на рис. 5.1
кортежи отношения S могли бы располагаться в противоположном порядке, но оно при
этом оставалось бы тем же самым отношением. Поэтому в отношении нет 5-, 97- или 1-
го кортежа, т.е. нет понятий позиционной адресации и следования. В статье [5.6], кото-
рая уже упоминалась в связи со свойством отсутствия одинаковых кортежей, показано,
почему свойство неупорядоченности кортежей также имеет важное значение (на самом
деле эти свойства взаимосвязаны).
166
Часть II. Реляционная модель
Замечание. Действительно, понятие “следование” иногда необходимо для стыковки
базы данных с базовым языком программирования, например с языком С или COBOL
(см. обсуждение курсоров SQL и предложения ORDER BY в главе 4). Однако эта необ-
ходимость привносится не реляционной моделью, а базовым языком. В сущности, ба-
зовый язык требует, чтобы неупорядоченные наборы были преобразованы в упорядо-
ченные списки или массивы (кортежей), и тогда такая операция, как выбор следующе-
го кортежа, будет иметь смысл. Обратите также внимание на то, что эти средства со-
ставляют часть исключительно программного интерфейса приложений и конечному
пользователю не предъявляются.
Как уже говорилось в настоящем разделе, второе свойство отношений служит так-
же иллюстрацией того факта, что отношение и таблица — это не одно и то же, по-
скольку строки таблицы упорядочены сверху вниз, а кортежи отношения не упорядо-
чены таким образом.
Свойство 3. Отсутствие упорядочения атрибутов
(слева направо)
Данное свойство следует из того факта, что заголовок отношения также определен
как множество (атрибутов). Например, на рис. 5.1 атрибуты отношения S могли быть
представлены, скажем, в таком порядке: SNAME, CITY, STATUS, S#. Это было бы то же са-
мое отношение, по крайней мере с точки зрения реляционной модели10. Поэтому не су-
ществует первого атрибута или последнего атрибута (и т.п.), не существует следующего
атрибута (т.е. нет понятия “следование”). Иначе говоря, атрибут всегда определяется по
имени, а не по расположению. Это позволяет избежать некоторых ошибок и неясностей
при написании программ. Например, не существует (или не должно существовать) воз-
можности возникновения сбоя системы из-за “наложения” одного атрибута на другой.
Эта ситуация отличается от ситуации во многих системах программирования, где часто
можно использовать физическую смежность логически дискретных элементов, как
умышленно, так и случайно, причем многими, но одинаково губительными способами.
Заметим, что вопрос, связанный с порядком атрибутов, — это еще одна область, в кото-
рой конкретное представление отношения в виде таблицы предполагает наличие неверных
фактов: столбцы таблицы упорядочены слева направо, а атрибуты отношения — нет.
Свойство 4. Каждый кортеж содержит ровно одно значение
для каждого атрибута
Последнее свойство непосредственно следует из определения кортежа: кортеж явля-
ется множеством из п компонентов или упорядоченных пар вида /Ij. v, (/ = 1, 2, ..., п). От-
ношение, удовлетворяющее этому свойству, называется нормализованным или пред-
ставленным в первой нормальной форме (1НФ).
Замечание. Данное свойство может показаться совершенно очевидным, каковым оно
на самом деле и является, особенно если учесть (как вы, возможно, уже догадались), что
все отношения нормализованы по определению. Тем не менее у этого свойства есть не-
сколько важных следствий, о которых можно узнать из аннотации к статье [5.10], из гла-
вы 18 (обсуждение вопроса об отсутствующих данных), а также из следующего раздела.
10 Атрибуты математических отношений, в отличие от реляционных, действительно упо-
рядочены слева направо.
Глава 5. Домены, отношения и базовые переменные-отношения
167
Атрибуты, значениями которых являются отношения
В разделе 5.2 говорилось, что характер значений, составляющих тип данных, может
быть произвольным. В частности, возможно существование типа, значениями которого
будут отношения, и, следовательно, существование отношения с атрибутами, значения-
ми которых также являются отношения. Другими словами, возможно существование от-
ношений, в которые вложены другие отношения. Рассмотрим, например, отношение
S_SP, показанное на рис. 5.3. Здесь значением атрибута PQ является отношение. Заметьте,
в частности, что пустому множеству деталей, поставляемых поставщиком с номером
' S5', соответствует пустое множество (а точнее, пустое отношение).
S-SP S# SNAME STATUS CITY PQ
S1 Smith 20 London p# QTY
Pl 300
P2 200
P6 100
S2 Jones 10 Paris P# QTY
Pl 300
P2 200
S5 Adams 30 Athens P# QTY
Рис. 5.3. Отношение с атрибутом, значениями которого являются отношения
Основной причиной того, что здесь явно рассматривается возможность использова-
ния отношений с атрибутами, принимающими в качестве значений отношения, является
то, что исторически в большинстве публикаций по базам данных (включая предыдущие
издания настоящей книги) это считалось недопустимым (а в большинстве изданий счита-
ется таковым и поныне). Вот, например, несколько отредактированная цитата из преды-
дущего издания этой книги.
' Обратите внимание на то, что все значения столбцов атомарные... Это значит, что
на каждом месте в столбце или строке всегда находится ровно одно значение, а не
группа из нескольких значений. Поэтому, например, в таблице ЕМР мы имеем
DEPT# EMP#
DI El
DI E2
вместо
DEPT# EMP#
DI E1.E2
168
Часть II. Реляционная модель
Столбец EMP# второй таблицы является примером так называемой повто-
ряющейся группы. Повторяющаяся группа— это столбец, ...содержащий по
нескольку значений в каждой строке (в общем случае — различное количество
значений в разных строках). В реляционных базах данных повторяющиеся груп-
пы недопустимы, поэтому использование второго варианта таблицы в рамках
реляционной модели запрещено.
Вот еще одна цитата из той же книги.
[Домены] состоят только из атомарных значений... [Поэтому] отношения не
содержат повторяющихся групп. Отношение, отвечающее этим условиям, на-
зывается нормализованным или, что равносильно, отношением в первой нор-
мальной форме... Под термином отношение в контексте реляционной модели
всегда будет подразумеваться нормализованное отношение.
Однако, по крайней мере в целом, эти высказывания неверны. Они являются следст-
вием ошибочного понимания автором истинной природы типов и предикатов. По причи-
нам, которые будут рассмотрены в главе 11 (раздел 11.6), маловероятно, чтобы эти за-
блуждения привели к серьезным ошибкам на практике. Тем не менее мы приносим свои
извинения всем, кто был введен нами в заблуждение. Во всяком случае в предыдущем
издании утверждение о том, что в реляционной модели все отношения всегда нормали-
зованы, соответствует действительности. Дальнейшее обсуждение этого вопроса будет
продолжено в главе 11.
Отношения и их интерпретация
В заключение этого раздела напомним, что, как сказано в разделе 3.4 главы 3, заголовок
отношения можно считать предикатом, а любой кортеж — истинным высказыванием, по-
лученным из этого предиката в результате подстановки значения соответствующего типа
вместо параметров (или местодержателей) в этом предикате (“конкретизация предика-
та”). В действительности допущение замкнутости мира (известное также как интерпре-
тация замкнутости мира) гласит: если какой-то другой допустимый кортеж (т.е. согласо-
ванный с заголовком отношения) не содержится в теле отношения, можно предположить,
что соответствующее ему утверждение ложно. Другими словами, тело отношения содер-
жит все такие и только такие кортежи, которым соответствуют истинные утверждения.
5.4. Переменные-отношения
Как уже говорилось в главе 3, существует две разновидности переменных-отношений
(relation variable или кратко — relvar): базовые переменные-отношения и представления
(которые иногда называют реальными и виртуальными переменными-отношениями со-
ответственно). В этом разделе рассматриваются только базовые переменные-отношения.
Представления будут обсуждаться в главе 9.
Определение базовых переменных-отношений
Базовые переменные-отношения определяются следующим образом.
VAR <имя переменной-отношения > BASE <тип отношениЯ>
<перечень определений потенциальных ключей»
[ <перечень определений внешних ключей» ] ;
Глава 5. Домены, отношения и базовые переменные-отношения
169
Параметр <тип отношения* имеет следующий вид.
RELATION { <список атрибутов> }
Здесь каждое значение <атрибут> в параметре <список атрибутов>, в свою очередь,
является упорядоченной парой следующего вида.
<имя атрибута> <имя типа>
Смысл выражения <перечень определений потенциальных ключей? и необязательно-
го выражения <перечень определений внешних ключей> раскрывается ниже.
Замечание. Термин <список ...> (список, разделенный запятыми) был определен в
главе 4 (раздел 4.6), а термин <перечень ...> имеет следующее определение. Если
<xyz> — это некоторая синтаксическая категория (т.е. что-либо, что записывается слева
в BNF-нотации), то <перечень хуг> обозначает последовательность категорий <xyz>,
количество которых больше нуля либо равно нулю, причем каждая соседняя пара этих
определений разделяется по крайней мере одним пробелом.
В качестве примера рассмотрим несколько определений базовых отношений для базы
данных поставщиков и деталей.
VAR S BASE RELATION
{ s# s#,
SNAME NAME,
STATUS INTEGER,
CITY CHAR }
PRIMARY KEY { S# } ;
VAR P BASE RELATION
{ P# P#,
PNAME NAME,
COLOR COLOR,
WEIGHT WEIGHT,
CITY CHAR }
PRIMARY KEY { P# } ;
VAR SP BASE RELATION
{ S# S#,
P# P#,
QTY QTY }
PRIMARY KEY{ S#, P# }
FOREIGN KEY{ S# } REFERENCES S
FOREIGN KEY{ P# } REFERENCES P ;
Пояснения
1. Эти три базовые переменные-отношения относятся к следующим типам (отношений).
RELATION { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR }
RELATION { P# P#, PNAME NAME, COLOR COLOR, WEIGHT WEIGHT,
CITY CHAR }
RELATION { S# S#, P# P#, QTY QTY }
170
Часть II. Реляционная модель
Очевидно, что все эти типы (отношений) действительно являются типами и могут ис-
пользоваться любым обычным способом; в частности, как тип атрибута некоторого
отношения. (Фактически тип RELATION является генератором типов, позволяющим
определять сколько угодно различных типов отношений, подобно тому как тип array
является генератором типов массивов в общепринятых языках программирования.)
2. Все возможные значения переменной-отношения принадлежат одному типу (а
именно, тому типу, который прямо или косвенно был задан при определении этой
переменной-отношения) и, следовательно, имеют одинаковые заголовки. В частно-
сти, начальным значением любой переменной-отношения является пустое отноше-
ние соответствующего типа.
3. Термины заголовок, тело, атрибут, кортеж, кардинальность и степень, уже оп-
ределенные для значений отношений, очевидным образом переносятся на пере-
менные-отношения (на все переменные-отношения, а не только на базовые пере-
менные-отношения).
4. При определении новой базовой переменной-отношения система делает в каталоге
запись — описание этой переменной-отношения.
5. Определение потенциальных ключей будет дано в главе 8. До этого времени мы
просто будем считать, что в каждом определении базовой переменной-отношения
есть ровно одно такое определение, записанное в следующем виде.
PRIMARY KEY {<список имен атрибутов»}
Определение внешних ключей также приводится в главе 8.
6. Наконец, любую существующую базовую переменную-отношение можно удалить.
DROP VAR <имя переменной-отношения»;
В результате выполнения этой операции сначала значение базовой переменной-
отношения устанавливается равным пустому отношению (т.е. из базовой переменной-
отношения удаляются все кортежи), а затем из каталога удаляются записи, соответст-
вующие этой переменной-отношению. По завершении указанных действий данная базо-
вая переменная-отношение перестает быть известной системе.
Замечание. Для простоты предполагается, что выполнение оператора DROP приведет к
ошибке, если удаляемая переменная-отношение где-либо используется, например если на
нее имеется ссылка в определении какого-либо представления. Представления будут рас-
смотрены в главе 9.
Обновление переменных-отношений
Присвоение значений переменным-отношениям, т.е. их обновление, в реляционной
модели осуществляется с помощью оператора реляционного присвоения. На языке Tu-
torial D это делается следующим образом.
<имя переменной-отношения» := реляционное выражение» •,
После вычисления реляционного выражения, заданного параметром реляционное
выражение», полученное значение присваивается переменной-отношению с именем, ко-
торое указано параметром <имя переменной-отношения», заменяя ее прежнее значение.
Разумеется, переменная-отношение и полученное в результате вычислений отношение
должны быть одного типа, т.е. иметь одинаковые заголовки.
Глава 5. Домены, отношения и базовые переменные-отношения
171
Предположим, к примеру, что задана некоторая переменная-отношение R, принадле-
жащая тому же типу, что и переменная-отношение поставщиков S.
VAR R BASE RELATION
{ S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR } ...;
Ниже приведено несколько примеров правильного реляционного присвоения.
R := S;
R := S WHERE CITY = 'London' ;
R := S MINUS ( S WHERE CITY = 'Paris' ) ;
Заметьте, что каждый из этих примеров можно рассматривать и как пример выборки
данных из отношения, заданного в правой части выражения, и как пример обновления
значения переменной-отношения, расположенной слева от оператора присвоения.
Предположим теперь, что во втором и третьем примерах переменную-отношение R
заменили переменной-отношением S.
S := S WHERE CITY = 'London' ;
S := S MINUS ( S WHERE CITY = 'Paris' ) ;
В этом случае оба присвоения обновляют значение переменной-отношения S: первое
удаляет всех поставщиков, находящихся вне Лондона, а второе удаляет всех поставщи-
ков, находящихся в Париже. Для удобства язык Tutorial D поддерживает явные операто-
ры INSERT, DELETE и UPDATE, однако каждый из них является лишь сокращенным обозна-
чением некоторой операции реляционного присвоения. Например, рассмотрим следую-
щий оператор11.
INSERT INTO S
RELATION { TUPLE { S# S# ( 'S6' ),
SNAME NAME ( 'Smith' ),
STATUS 50,
CITY 'Rome' } } ;
Он является эквивалентом операции присвоения, которая записывается так.
S := S UNION
RELATION { TUPLE { S# S# ( 'S6' ),
SNAME NAME ( 'Smith' ),
STATUS 50,
CITY 'Rome' } } ;
Обратите внимание, что эта операция присвоения будет успешной лишь в том случае,
если в переменной-отношении S уже содержится кортеж с данными о поставщике с но-
мером 'S6'. На практике аналог оператора INSERT, записанный в виде оператора при-
11 Выражение RELATION {...} в примере оператора INSERT является обращением к опера-
тору выбора (в свою очередь, выражение в фигурных скобках в фразе TUPLE {...} является об-
ращением к оператору выбора кортежа, а выражения во внутренних скобках — обращением к
оператору выбора скаляров). Подробнее об этом рассказывается в разделах 6.3 и 6.4 главы 6.
172
Часть II Реляционная модель
своения, можно было бы расширить так, чтобы подобные ситуации проверялись. Для
простоты эти усовершенствования здесь игнорируются. Разумеется, то же самое касается
операторов DELETE и UPDATE.
DELETE S WHERE CITY = 'Paris';
эквивалентно присвоению
S := S MINUS (S WHERE CITY = 'Paris' ) ;
UPDATE S WHERE CITY = 'Paris'
STATUS := 2 * STATUS,
CITY := 'Rome' ;
Эквивалент этого оператора, записанный в виде реляционного присвоения, имеет
слишком сложный на текущий момент вид, поэтому мы его опускаем (см. [3.3]).
Подводя итог, приведем несколько упрощенный синтаксис операторов INSERT,
DELETE и UPDATE.
INSERT INTO <имя переменной-отношения> реляционное выражение> ;
DELETE <имя переменной-отношения> [ WHERE Логическое выражение> ] ;
UPDATE <имя переменной-отношения > [ WHERE Логическое выражение> ]
<список обновляемых атрибутов> ;
Здесь параметр <обновляемый атрибут^ имеет следующий вид.
<имя атрибута> := <выражение>
Синтаксис выражения, помещаемого в параметр логическое выражением говорит
сам за себя, тем не менее он подробно описывается в главе 6.
В завершение этого раздела подчеркнем, что реляционное присвоение, а следова-
тельно, и операторы INSERT, DELETE и UPDATE являются операторами на уровне мно-
жеств. Например, оператор UPDATE, говоря нестрого, обновляет некоторое множество
кортежей результирующей переменной-отношения. Неформально мы также часто гово-
рим, например, об обновлении отдельного кортежа, однако при этом необходимо отчет-
ливо понимать следующее.
1. В действительности имеется в виду множество кортежей, однако в данном случае
кардинальность этого множества равна единице.
2. Иногда обновление множества кортежей с кардинальностью, равной единице, не-
возможно!
Предположим, например, что на переменную-отношение поставщиков наложено ог-
раничение целостности (подробности приводятся в главе 8), которое заключается в том,
что поставщики с номерами ' S1' и 'S4' должны иметь один и тот же статус. Тогда при
обновлении отдельного кортежа, затрагивающем статус одного из двух перечисленных
выше поставщиков, возникнет ошибка. В этом случае необходимо обновлять статус обо-
их поставщиков одновременно, например так.
UPDATE S WHERE S# = S# ( 'Si' ) OR S# = S# ( 'S4' )
STATUS := <некоторое значение> ;
Глава 5. Домены, отношения и базовые переменные-отношения
173
Следует подчеркнуть, что говорить об “обновлении кортежа” (или множества корте-
жей), как мы это только что делали, — довольно некорректно. Кортежи, как и отноше-
ния, являются значениями и не могут быть обновлены (по определению никакое значе-
ние изменить нельзя). Таким образом, для того чтобы “обновлять кортежи”, необходимо
ввести понятие переменной кортежа, что вовсе не является частью реляционной модели!
Поэтому, когда мы, например, говорим “обновление кортежа с его преобразованием в
кортеж г2”, подразумевается, что кортеж t\ (т.е. значение кортежа rj заменяется корте-
жем tz (под которым снова понимается значение кортежа). Аналогичные замечания отно-
сятся к фразам наподобие “обновление атрибута Я” (некоторого кортежа). В этой книге
мы и далее будем говорить “обновление кортежей” или “обновление атрибутов корте-
жей”, поскольку на практике это удобно. Однако не следует забывать, что такие сокра-
щения в общем случае некорректны.
5.5. Средства SQL
К рассматриваемому в этой главе материалу имеют отношение следующие SQL-
операторы.
CREATE DOMAIN CREATE TABLE INSERT
ALTER DOMAIN ALTER TABLE UPDATE
DROP DOMAIN DROP TABLE DELETE
Операторы INSERT, UPDATE и DELETE приводились в главе 4. Остальные операторы бу-
дут рассмотрены ниже.
Домены
Как отмечалось в главе 4, “домены” в языке SQL, к сожалению, далеки от настоящих
реляционных доменов (т.е. типов). Фактически эти два понятия настолько различны, что
для данной конструкции языка SQL желательно было бы использовать какое-либо другое
название. Основное назначение концепции доменов в языке SQL — разрешить присвое-
ние встроенным типам сокращенных имен, которые можно было бы использовать для
упрощения записи определения нескольких столбцов в нескольких базовых таблицах,
как, например, показано ниже.
CREATE DOMAIN S# CHAR(5) ;
CREATE DOMAIN P# CHAR(6) ;
CREATE TABLE S ( S# S#, ... ) ;
CREATE TABLE P ( P# P#, ... ) ;
CREATE TABLE SP ( S# S#, P# P#, ... ) ;
Далее перечислены некоторые основные различия между настоящими доменами и
конструкциями языка SQL.
Как уже отмечалось, на самом деле домены языка SQL — это просто синтаксиче-
ские сокращения. Они, несомненно, не относятся к истинному типу данных, опре-
деляемому пользователем.
174
Часть II. Реляционная модель
Значения доменов языка SQL не могут быть “произвольной внутренней сложно-
сти”. Сложность значений домена ограничена сложностью встроенных типов.
Домены языка SQL должны определяться в терминах одного из встроенных типов,
а не в терминах другого домена, определенного пользователем.
На практике каждый домен языка SQL должен определяться в терминах только од-
ного из существующих встроенных типов. Таким образом, в языке SQL невозможно
определить домены, аналогичные, например, типам POINT и LINESEG из раздела 5.2.
Домены языка SQL не могут иметь больше одного “допустимого” представления. В
действительности в языке SQL нет четкого различия между типом и его физическим
представлением. Например, если домены языка SQL с именами S# и P# будут опреде-
лены в терминах типа CHAR, то над номерами поставщиков и номерами деталей можно
будет выполнять те же операции, что и над строками, в частности — конкатенацию.
В языке SQL нет строгого контроля типов и выполняемая проверка правильности
типов совершенно незначительна. Если взять в качестве примера определенные
выше типы S# и Р#, следующий SQL-оператор ошибки не вызовет, хотя, если рас-
суждать логически, должен был бы вызвать.
SELECT *
FROM SP
WHERE S# = P# ;
Замечание. To же самое можно преподнести иначе, сказав, что язык SQL поддер-
живает ровно восемь истинно реляционных доменов, а именно — восемь следую-
щих “базовых типов”.
Числа
Строки символов
Строки битов
Даты
Отметки времени
Временные отметки (timestamp)
Интервалы “год/месяц”
Интервалы “день/время”
Тогда можно было бы сказать, что проверка правильности типов производится, но
только для этих восьми типов. Так, например, попытка сравнить число со строкой
битов приведет к ошибке, а сравнение двух чисел будет корректным, даже если эти
числа имеют различные представления, скажем, одно — INTEGER, а другое — FLOAT.
Язык SQL не поддерживает возможность определения пользователем операций,
применяемых к данному домену. Допустимыми являются только встроенные опе-
раторы, применяемые к соответствующим представлениям этого типа.
Ниже приводится пример создания домена с помощью SQL-оператора CREATE DOMAIN.
CREATE DOMAIN <имя домена> <имя встроенного типа>
[ Определение значения по умолчаник» ]
[ Ограничений ] ;
Глава 5. Домены, отношения и базовые переменные^-отношения
175
Пояснения
1. Список допустимых имен встроенных типов, которые можно указывать как значе-
ние параметра <имя встроенного типа>, приводится в разделе 4.2 главы 4.
2. Необязательный параметр определения значения по умолчанию задает значение по
умолчанию, которое будет применяться к каждому столбцу, определенному на
этом домене и не имеющему собственного явного заданного значения по умолча-
нию (подробности приводятся в следующем разделе). Значение этого параметра
должно иметь вид DEFAULT <значение по умолчания», где параметр <значение по
умолчания», в свою очередь, может быть литералом, именем встроенного 0-
адического оператора или ключевым словом NULL12.
Замечание. Оператор, который не имеет операндов, называется 0-адическим
(например, CURRENT_DATE).
3. В необязательном параметре <ограничениЯ> перечисляются все ограничения, при-
меняемые к определяемому домену. Обсуждение ограничений мы откладываем до
главы 8.
Существующий SQL-домен можно в любое время изменить с помощью оператора
ALTER DOMAIN. В частности, этот оператор позволяет определить для указанного домена
новое значение по умолчанию (заменяя при этом старое значение, если оно было
указано) или удалить существующее. Он также позволяет ввести новое ограничение це-
лостности для данного домена или удалить уже существующие ограничения. Подробное
изложение всех этих опций (а они довольно сложны) выходит за рамки данной книги.
Интересующийся читатель может обратиться к [4.19].
И наконец, существующий домен можно отменить с помощью оператора DROP
DOMAIN, имеющего следующий синтаксис.
DROP DOMAIN <имя домена> <режим> ;
Здесь параметр <режим> может принимать значения RESTRICT и CASCADE. Общая идея
состоит в следующем.
При выборе опции RESTRICT домен не будет уничтожен, если на него имеются ка-
кие-либо ссылки.
При выборе опции CASCADE операция будет выполнена и “каскадно” продолжена
во всех направлениях. Столбцы, которые были ранее определены на основе уда-
ляемого домена, будут рассматриваться как определенные непосредственно на ба-
зе типа данных этого домена.
Механизм такой операции достаточно сложен, и поэтому подробности опускаются.
Дополнительные сведения можно найти в [4.19].
Подробное обсуждение поддержки в языке SQL пустых значений (обозначаемых ключевым
словом NULL) мы отложим до главы 18. Однако отдельных упоминаний о пустых значениях в
этой главе не избежать.
176
Часть II. Реляционная модель
Базовые таблицы
Прежде чем обсуждать базовые таблицы, необходимо сделать пару замечаний отно-
сительно таблиц языка SQL вообще.
Во-первых, в таблицах языка SQL, в отличие от настоящих отношений, допусти-
мы повторяющиеся строки, поэтому им не требуются какие-либо первичные
ключи (или, более общо, потенциальные ключи).
Во-вторых, в таблицах языка SQL, в отличие от настоящих отношений, столбцы
рассматриваются в порядке слева направо. Например в таблице поставщиков S
столбец S# может быть первым столбцом, столбец SNAME — вторым и т.д.
Перейдем непосредственно к базовым таблицам. Они определяются с помощью опе-
ратора CREATE TABLE (обратите внимание, что ключевое слово TABLE означает здесь ис-
ключительно базовую таблицу; то же самое касается операторов ALTER TABLE и
DROP TABLE, которые описываются ниже). Синтаксис выражения следующий.
CREATE TABLE <имя базовой таблиць»
( <список элементов базовой таблиць» );
Здесь каждый параметр <элемент базовой таблиць» является либо определением
столбца, либо определением ограничения базовой таблицы. В последнем случае элемент
задает ограничение поддержки целостности данных, которое будет применяться к созда-
ваемой таблице. Подробное обсуждение подобных ограничений мы отложим до главы 8.
Каждое определение столбца (по крайней мере одно такое определение обязательно
должно присутствовать), в свою очередь, выглядит следующим образом.
<имя столбца> <тип или имя домена> [ <значение по умолчаник» ]
Здесь параметр <имя столбца> указывает название столбца, параметр <тип или имя
домена> задает используемый тип данных или домен, а необязательный параметр
<значение по умолчаник» устанавливает значение по умолчанию для описываемого
столбца, которое подавляет значение по умолчанию, указанное на уровне домена (если
такое имеется).
Замечание. Параметр <значение по умолчаник» задает значение по умолчанию, ко-
торое помещается в соответствующий столбец в том случае, если пользователь не указал
конкретное значение для этого столбца в операторе INSERT. Подобный случай проиллю-
стрирован в разделе 4.6 главы 4. Если для данного столбца собственное значение по
умолчанию явно не определено, а также если нет такового значения, наследуемого из
домена, то предполагается, что значение по умолчанию— NULL, т.е. NULL— это
“значение по умолчанию, используемое по умолчанию”.
Пример использования оператора CREATE TABLE показан на рис. 4.1 главы 4.
Существующее определение базовой таблицы можно в любое время изменить с по-
мощью оператора ALTER TABLE. Он позволяет выполнить следующие изменения.
Добавить столбец
Задать для существующего столбца новое значение по умолчанию (которое заме-
нит прежнее значение, если оно было определено)
Удалить значение по умолчанию для существующего столбца
Глава 5. Домены, отношения и базовые переменные-отношения
177
Удалить существующий столбец
Задать новые ограничения целостности
Удалить существующие ограничения целостности
Приведем пример для первого случая.
ALTER TABLE S ADD COLUMN DISCOUNT INTEGER DEFAULT -1 ;
Этот оператор добавляет в базовую таблицу поставщиков столбец с именем DISCOUNT
(имеющий тип INTEGER). Начальным значением каждой строки этого столбца во всех
случаях будет -1.
Наконец, существующую базовую таблицу можно уничтожить с помощью оператора
DROP TABLE.
DROP TABLE <имя базовой таблицъО <режиМ> ;
Здесь (как и в случае оператора DROP DOMAIN) опция <режим> принимает одно из двух
возможных значений — RESTRICT или CASCADE. При выборе опции RESTRICT базовая таб-
лица не будет уничтожена, если на нее имеются ссылки в каком-либо представлении или
ограничении целостности. При выборе опции CASCADE операция будет выполнена (будут
удалены все строки таблицы, а затем и сама таблица), при этом' также будут удалены все
представления и ограничения целостности, ссылающиеся на эту таблицу.
5.6. Резюме
В этой главе подробно рассматривалась структурная часть реляционной модели, а
именно — домены и отношения. Домен — это, в сущности, тип данных (возможно, оп-
ределенный в системе (встроенный), но в общем случае определенный пользователем).
Он представляет собой совокупность множества значений (всех возможных значений
этого типа), из которого будут получать свои значения различные атрибуты, различных
отношений, и набор операторов (операторов чтения и обновления), которые могут ис-
пользоваться для манипулирования значениями и переменными этого типа. Составляю-
щие тип значения могут быть любого вида — числа, строки, даты, время, аудио- и ви-
деозаписи, карты, геометрические точки и т.д. и т.п. Типы ограничивают возможность
выполнения операций, т.е. в общем случае требуется, чтобы используемые в операции
значения принадлежали одному домену (имеет место строгий контроль типов). Строгий
контроль типов полезен тем, что он позволяет выявить многие логические ошибки во
время компиляции, а не во время работы. К тому же, как вы узнаете из следующей главы,
строгий контроль типов имеет много важных применений при выполнении таких реля-
ционных операций, как соединение, объединение и т.д.
Тип может быть либо скалярным, либо нескалярным. Скалярные типы не содержат
видимых пользователю компонентов. Наиболее важными нескалярными типами в реля-
ционной модели являются типы отношений, которые определяются с помощью операции
генератора типов RELATION. Следует четко различать типы и их физические представ-
ления (тип — это модель, а физическое представление — это ее реализация). Кроме то-
го, каждый тип обязательно должен иметь хотя бы одно декларированное допустимое
представление. Автоматически задаются оператор выбора для каждого допустимого
представления и операторы ТНЕ_ — для каждого компонента этого допустимого пред-
178
Часть II. Реляиионная модель
ставления (в том числе THE псевдопеременная). Поддерживаются явные преобразова-
ния типов, однако не поддерживается неявное приведение типов. Для скалярных типов
можно дополнительно определить любое количество операторов, при этом для каждого
типа обязательно должен быть определен оператор равенства (с требуемой семантикой).
Перейдем теперь к отношениям. Здесь следует различать значения отношений и пе-
ременные отношений. Отношение состоит из двух частей — заголовка и тела. Заголо-
вок — это набор атрибутов, а тело — это набор кортежей, соответствующий заголовку.
Количество атрибутов называется степенью, а количество кортежей— кардинально-
стью отношения. Каждое отношение принадлежит типу отношений, а именно — типу
RELATION{H}, где Н — соответствующий заголовок. Отношение можно представить себе
как таблицу, столбцы которой являются атрибутами, а строки— кортежами, но это
только приблизительное представление. Отношения обладают четырьмя очень важными
свойствами.
В них нет одинаковых кортежей
Кортежи не упорядочены сверху вниз
Атрибуты не упорядочены слева направо
Каждый кортеж содержит ровно одно значение для каждого атрибута (т.е. отноше-
ния нормализованы или, что то же самое, заданы в первой нормальной форме)
Как говорилось в главе 3, заголовок отношения иногда называют предикатом, а кор-
тежи— истинными утверждениями, полученными из предиката в результате подста-
новки значений параметров (или местодержателей) предиката. Допущение замкнутости
мира гласит, что если заведомо корректный кортеж (т.е. удовлетворяющий заголовку
отношения) не содержится в теле отношения, то можно предположить, что соответст-
вующее ему утверждение ложно.
Поскольку природа значений, которые относятся к некоторому типу, может быть про-
извольной, допускаются отношения с атрибутами, принимающими в качестве значений
отношения (что в действительности, как будет видно из глав 6 и 11, очень удобно).
Существуют две разновидности переменных-отношений — базовые отношения и
представления. Мы научились определять базовые отношения на языке Tutorial D, ко-
торый используется в этой книге для иллюстрации излагаемого материала.
Замечание. Возможно, вы заметили, что, рассмотрев определяемые пользователем
операторы для скалярных типов, мы обошли вниманием подобные операторы для типов
отношений. Поскольку большинство необходимых реляционных операторов, таких как
выборка, проекция, объединение и реляционное присвоение, уже встроены в саму мо-
дель, другие определенные пользователем операторы фактически не нужны. Более того,
эти встроенные операторы являются общими и, следовательно, применимы к отношени-
ям всех типов. Тем не менее ничто не запрещает вам дополнить набор встроенных опе-
раторов собственными операторами.
И наконец, мы вкратце рассмотрели, как в языке SQL определяются “домены” и базо-
вые таблицы. В частности, следует отметить следующее.
“Домены” языка SQL не являются типами.
Таблицы языка SQL (базовые или другие) не являются отношениями, поскольку в
них допускается повтор строк и их столбцы всегда упорядочены слева направо. В
действительности в них даже может быть два или более столбцов с одинаковыми
Глава 5. Домены, отношения и базовые переменные-отношения
179
именами (это замечание не касается именованных таблиц, каковыми являются ба-
зовые таблицы и представления). В качестве примера рассмотрите таблицу, кото-
рая будет получена в результате выполнения следующего SQL-запроса.
SELECT *
FROM S, Р ;
Упражнения
5.1. Пусть каталог имеет структуру, которая представлена на рис. 3.6 в главе 3 для базы
данных отделов и служащих.
а) Переименуйте различные компоненты каталога с помощью формальной реля-
ционной терминологии, представленной в этой главе.
б) Как должна быть расширена структура каталога с учетом типов (доменов)?
в) Напишите запрос к этому расширенному каталогу для поиска всех именован-
ных переменных-отношений, в которых используется атрибут типа ЕМР#.
г) Как будет выглядеть запрос п. в, записанный на языке SQL, но без использова-
ния типов данных, которые определены пользователем?
5.2. На каких доменах основаны сами переменные-отношения каталога?
5.3. Для базового отношения PART_STRUCTURE (см. рис. 4.6 в главе 4) выполните следующее.
а) Используя рассмотренные в этой главе средства языка Tutorial D, определите
базовую переменную-отношение, а также соответствующие типы.
б) Предположим, что эта базовая переменная-отношение включена в базу данных
отделов и служащих из упр. 5.1. Покажите, какие изменения должна внести
система в каталог, чтобы отобразить ваш ответ к п. а.
в) Используя язык Tutorial D, напишите набор операторов DROP, необходимых для
того, чтобы отменить изменения, которые были внесены в каталог в п. б.
5.4. Используя язык Tutorial D, напишите набор необходимых определений для базы
данных поставщиков, деталей и проектов, представленной на рис. 4.5. (см. упраж-
нения в главе 4).
5.5. Как отмечалось в разделе 5.2, говорить, что объем некоторой поставки равен, на-
пример, 100 деталям, некорректно (объем поставки — это значение типа QTY, а не
INTEGER). В этом смысле рис. 4.5, например, несколько неаккуратен, так как, глядя
на него, можно предположить, что объемы поставок принадлежат типу INTEGER.
Используя ваш ответ к упр. 5.4, покажите, как следует называть различные скаляр-
ные значения, представленные на рис. 4.5.
5.6. Используя ответ к упр. 5.4, ответьте, какие из следующих скалярных выражений
корректны. Укажите тип результата выполнения каждого корректного выражения.
Для остальных выражений напишите корректный вариант выражений, которые бу-
дут давать предполагаемый результат.
a) J.CITY = P.CITY
б) JNAME || PNAME
в) QTY *100
1ЯП
Члгти JJ Ррпяиипннля мпс\рп^
г) QTY + 100
д) STATUS + 5
е) J.CITY < S.CITY
ж) COLOR = P.CITY
3) J.CITY=P.CITY || 'burg'
5.7. Дайте все возможные определения скалярного типа CIRCLE (типа, описывающего
произвольные круги на плоскости). Какие операторы выбора и операторы ТНЕ_
применяются к этому типу? Кроме того, выполните следующее.
а) Определите набор операторов чтения для вычисления диаметра, длины окруж-
ности и площади заданного круга.
б) Определите оператор обновления, удваивающий радиус заданного круга (точнее,
модифицирующий заданную переменную CIRCLE так, чтобы ее значение остава-
лось неизменным, за исключением радиуса, который будет увеличен в два раза).
5.8. Иногда домены или типы рассматриваются как обычные переменные. Например, с
расширением бизнеса для нумерации служащих компании трех цифр может ока-
заться недостаточно, и поэтому “множество всех номеров служащих” придется
модифицировать. Опишите возможные решения проблемы.
5.9. По определению отношение имеет множество атрибутов и множество кортежей.
Пустое множество в математике рассматривается как вполне приемлемое. Обычно
для теорем, формул и т.д. желательно, чтобы, если они выполняются для множест-
ва из п элементов, они выполнялись и для множества из п = 0 элементов. Может
ли отношение иметь пустое множество кортежей? Может ли оно иметь пустое
множество атрибутов?
5.10. Иногда базовые переменные-отношения рассматриваются как обычные файлы, в
которых в качестве записей выступают “кортежи”, а в качестве полей —
“атрибуты”. Обсудите этот тезис.
5.11. Как мы уже видели, операторы определения данных вызывают изменение содержания
каталога. Но каталог — это всего лишь набор переменных-отношений, как и остальная
часть базы данных. Можно ли применять обычные реляционные операторы INSERT,
UPDATE и DELETE для соответствующего изменения каталога? Обоснуйте свой ответ.
5.12. Используя язык Tutorial D, напишите набор операторов DROP, необходимый для
удаления из базы данных поставщиков, деталей и проектов всей информации, оп-
ределенной пользователем.
Список литературы
Большинство перечисленных ниже ссылок касается не только структурного аспекта, но и
всех аспектов реляционной модели.
5.1. Codd E.F. A Relational Model of Data for Large Shared Data Banks // CACM. — June,
1970.— 13, № 6. (Переиздано: Republished in Milestones of Research. — Selected
Papers 1958-1982 // CACM. — January, 1983. — 26, № 1. См. также более раннее
издание: Derivability, Redundancy, and Consistency of Relations Stored in Large Data
Banks // IBM Research Report RJ599. — August, 1969. — № 19. Замечание. Это ран-
нее издание является первой публикацией Кодда (Codd) о реляционной модели.)
Глава 5. Домены, отношения и базовые переменные-отношения
181
С этой статьи все и началось. И хотя прошло более 30 лет, она остается актуальной
и стоит того, чтобы ее перечитывали. Конечно, многие идеи со времени ее публи-
кации были в определенной степени улучшены, но по своей природе это были эво-
люционные, а не революционные изменения. Кроме того, в статье есть идеи, след-
ствия которых до сих пор полностью не исследованы.
Необходимо сделать несколько замечаний относительно терминологии. В своей
статье вместо термина “переменная-отношение” Кодд использует термин
“отношение, изменяющееся во времени”. Однако этот термин не очень удачен. Во-
первых, отношения как таковые являются значениями и не изменяются во времени
(математике неизвестны отношения, принимающие разные значения в разное вре-
мя). Во-вторых, если на каком-либо языке программирования мы пишем
DECLARE N INTEGER ;,
то мы не называем N целым числом, изменяющимся во времени; мы называем ее
переменной целого типа. В этой книге используется собственный термин
“переменная-отношение” и не используется термин “изменяющееся во времени”,
однако необходимо просто помнить о существовании этого устаревшего термина.
5.2. Codd E.F. The Relational Model for Database Management Version 2. — Reading,
Mass.: Addison-Wesley, 1990.
Длительное время в конце 1980-х годов Кодд пересматривал и расширял свою изна-
чальную модель (которую теперь называют реляционной моделью первой версии —
“the Relational Model Version 1” или RM/V1), в результате чего появилась эта книга. В
ней описывается так называемая реляционная модель второй версии — “the Rela-
tional Model Version 2” или RM/V2. Основное различие между версиями состоит в
следующем. Первая версия создавалась как абстрактный план для определенных ас-
пектов общей проблемы баз данных (по большей части, наиболее фундаментальных
аспектов), а вторая — как абстрактный план для всей системы. Поэтому, в то время
как первая версия разделена только на 3 части (структуры, манипулирование и под-
держка целостности), модель RM/V2 содержит 18 частей, которые включают не
только 3 исходные части, что само собой разумеется, но и части, касающиеся пред-
ставлений, каталогов, прав доступа, наименований, распределенных баз данных и
других аспектов управления базами данных. Для удобства ссылок ниже приводится
полный перечень этих 18 частей.
А Права доступа
В Основные операторы
С Каталог
D Принципы разработки СУБД
Е Команды администратора базы данных
F Функции
I Поддержка целостности данных
J Индикаторы
L Принципы разработки языка
М Обработка
N Наименование
Р Защита
Q Классификаторы
S Структуры
Т Типы данных
V Представления
X Распределенные базы данны
Z Дополнительные операторы
Тем не менее идеи, опубликованные в этой книге, отнюдь не имели широкого рас-
пространения. (См., в частности, статьи [5.7], [5.8] автора этой книги.) Приведем
небольшой комментарий к этой статье. Как уже говорилось в настоящей главе, до-
182
Часть II. Реляционная модель
мены ограничивают сравнения. Например, для базы данных поставщиков и дета-
лей сравнение S.S# = P.P# будет некорректным, поскольку сравниваемые величи-
ны принадлежат разным типам. Следовательно, связать поставщиков и детали пу-
тем сопоставления их номеров не удастся. Кодд, тем не менее, предложил свой ва-
риант некоторых операторов реляционной алгебры — так называемые операторы
DCO (Domain Check Override). Они выполняются, даже если при этом сравнива-
ются значения разных типов. Так, например, DCO-версия оператора, рассмотрен-
ного выше, позволяет связать поставщиков и детали несмотря на то, что атрибуты
S.S# и P.P# принадлежат разным типам (предполагается, что соединение произво-
дится путем сопоставления не типов, а их представлений).
Однако именно в этом и состоит проблема. Вся идея DCO основана на путанице
между типами и их представлениями. Считая домены тем, чем они являются на
самом деле (т.е. типами), со всеми вытекающими отсюда последствиями, мы полу-
чаем возможность контроля доменов, а также своего рода совместимость с DCO.
Следующее выражение служит примером сравнения номера поставщика с номером
детали на уровне допустимых представлений.
THE_S# ( S# ) = THEJP# ( P# )
Здесь обе части равенства принадлежат типу CHAR. Таким образом, мы утверждаем, что
предложенный в разделе 5.2 механизм обеспечивает нас всеми необходимыми средст-
вами очевидным и систематизированным образом. В частности, отпадает необходи-
мость загромождать реляционную модель новыми операторами наподобие DCO JOIN.
5.3. Darwen Н. The Duplisity of Duplicate Rows // Relational Database Writings 1989-
1991. — Reading, Mass.: Addison-Wesley, 1992.
Эта статья была написана для подтверждения аргументов, уже представленных в
[4.11], в пользу известного требования реляционной модели: в таблицах не должно
содержаться одинаковых строк. В статье не только представлены новые версии
этих аргументов, но и выдвинуты дополнительные аргументы. Основной вопрос
состоит в следующем: для того чтобы конструктивно обсуждать совпадение двух
объектов, необходим критерий идентичности для рассматриваемого класса объ-
ектов (иначе говоря, что означает для двух объектов, будь это строки в таблице или
что-нибудь еще, понятие “быть одним и тем же”).
5.4. Darwen Н. Relation-Valued Attributes И Relational Database Writings 1989-1991.—
Reading, Mass.: Addison-Wesley, 1992.
5.5. Darwen H. The Nullologist in Relationland // Relational Database Writings 1989-
1991. — Reading, Mass.: Addison-Wesley, 1992.
Нуллогия — это согласно Дарвену “учение об абсолютном ничто” или, иначе гово-
ря, учение о пустых множествах. Множества в реляционной теории вездесущи, по-
этому вопрос о том, что будет, если одно или несколько из них окажутся пустыми,
возник не случайно. На самом деле в некоторых случаях пустые множества играют
фундаментальную роль.
С темой настоящей главы (реляционными объектами данных) связаны раздел 2
этой статьи (“Таблицы без строк”) и раздел 3 (“Таблицы без столбцов”). (См. также
ответ к упр. 5.9.)
5.6. Date C.J. Why Duplicate Rows Are Prohibited // Relational Database Writings 1985-
1989. — Reading, Mass.: Addison-Wesley, 1990.
Глава 5. Домены, отношения и базовые переменные-отношения
183
Представляются многочисленные аргументы (с примерами) в пользу требования
реляционной модели того, чтобы в таблицах не было дублирующихся строк. В ча-
стности, в статье показано, что дублирующиеся строки являются главным препят-
ствием для оптимизации (см. главу 17, а также [5.3]).
5.7. Date C.J. Notes Toward a Reconstituted Definition of the Relational Model Version 1 (RM/V1) II
Relational Database Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
Приводятся критика и резюме к реляционной модели Кодда RM/V1 [5.2] и дается
альтернативное определение. Подразумевается, что крайне важно получить верную
“версию 1”, прежде чем обсуждать переход к какой-то “версии 2”.
Замечание. Версия реляционной модели, описанная в настоящей книге, — это, по
большей части, “воспроизведенная” версия, кратко описанная в данной статье (а
затем уточненная и описанная в [3.3]).
5.8. Date C.J. A Critical Review of Relational Model Version 2 (RM/V2) // Relational Data-
base Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
Приводятся критика и резюме к реляционной модели Кодда RM/V2 [5.2].
5.9. Date C.J. 30 Years of Relational (сборник из 12 статей) II Intelligent Enterprise!.—
October, 1998. — № 1-9. Замечание. Большинство этих статей можно также найти
по адресу www.intelligententerprise.com.
В данных статьях приводятся тщательный, беспристрастный обзор и оценка вклада
Кодда в реляционную модель на основании его публикаций в 1970-х годах. В част-
ности, в них детально исследованы следующие статьи (а также несколько других).
Derivbility, Redundancy, and Consistency of Relations Stored in Large Data Banks
(первое издание статьи [5.1])
A Relational Model of Data for Large Shared Banks [5.1]
Relational Completeness of Data Base Sublanguages [6.1 ]
A Data Base Sublanguage Founded on the Relational Calculus [7.1 ]
Further Normalization of the Data Base Relational Model [10.4]
Extending the Relational Database Model to Capture More Meaning [13.6]
Interactive Support for Nonprogrammers: The Relational and Network Approaches [25.8]
5.10. Mark A.R., Korth H.F., Silberschatz A. Extended Algebra and Calculus for Nested Rela-
tional Databases // ACM TODS 13. — December, 1988. — № 4.
Спустя несколько лет группой исследователей были предложены так называемые
“отношения NF2”, где NF2 = NFNF = “non first normal form” (не первая нормальная фор-
ма). Что подразумевается под термином NF2, — не совсем очевидно. Возможно, сле-
дующая интерпретация этого термина внесет некоторую ясность. Пусть пг — это NF2-
отношение и пусть “атрибут” А отношения пг принадлежит типу Т. Тогда некоторый
“кортеж” t “отношения” пг может содержать любое количество значений (возможно,
даже нулевое) “атрибута” А и разные “кортежи” могут содержать разное число значений
“атрибута” А13. (В этом случае А называется атрибутом повторяющейся группы; см. ци-
13 Некоторые авторы отбрасывают данное определение и определяют NF2-отношение как
произвольное отношение хотя бы с одним атрибутом, принимающим в качестве значений отно-
шения. Однако у нас есть свои причины не соглашаться с этим определением, поскольку факти-
чески такое отношение будет записано в первой нормальной форме.
184
Часть II. Реляционная модель
таты из предыдущего издания этой книги в разделе 5.3 этой главы.) Обратите внимание
на то, что “отношение” пг не нормализовано (оно не содержит ровно по одному значе-
нию каждого атрибута в каждом кортеже). В действительности пг вовсе не является от-
ношением в контексте реляционной модели. Как бы то ни было, в данной работе рас-
сматривается один из вариантов идеи NF2. В частности, автор определяет для NF2-
отношений исчисление и алгебру (см. главы 6 и 7) и доказывает их эквивалентность. Он
также ссылается на другие работы, посвященные этой теме. ''
Ответы к некоторым упражнениям
5.1.
а) Очевидные изменения суммированы и даны ниже.
TABLE заменяется на COLUMN RELVAR ATTRIBUTE
TABNAME RVNAME
COLCOUNT DEGREE
ROWCOUNT CARDINALITY (сокращенно — CARD)
COLNAME ATTRNAME
Обратите внимание, что переменная-отношение TABLE (теперь уже RELVAR)
должна иметь еще один атрибут (RVKIND), значения которого указывают ее тип
(базовая переменная-отношение или представление). Структура каталога будет
выглядеть таким образом.
RELVAR | RVNAME [DEGREE | CARD | RVKIND |... |
ATTRIBUTE | RVNAME | ATTRNAME J.... |
б) Нужна новая переменная-отношение каталога (TYPE), содержащая элемент для
каждого типа, а также новый атрибут (TYPENAME) в переменной-отношении
ATTRIBUTE, представляющий тип каждого атрибута каждой переменной-
отношения. Структура каталога будет подобна следующей.
TYPE | TYPENAME j... |
RELVAR | RVNAME [DEGREE |CARD |RVKIND |... |
ATTRIBUTE | RVNAME | ATTRNAME | TYPENAME |.. |
В качестве вспомогательного упражнения читатель мог бы, вероятно, учесть,
что дальнейшее расширение каталога могло бы потребоваться для представле-
ния информации о первичных и внешних ключах.
в) (ATTRIBUTE WHERE TYPENAME = NAME('EMP#')) {RVNAME}
Здесь обратите внимание на вызов оператора выбора NAME (см. ответ к упр. 5.2).
г) Если системой не поддерживаются типы, определенные пользователем, то оче-
видно, что невозможно написать запрос к каталогу относительно этих типов!
Можно только написать запрос относительно атрибутов. Вообще говоря, ре-
Глава 5. Домены, отношения и базовые переменные-отношения
185
комендуется по возможности называть атрибуты именами соответствующих
типов данных (даже если эти типы системе неизвестны) или хотя бы использо-
вать имя типа как часть имени атрибута. Если при определении базы данных вы
придерживались подобных соглашений об именах, такой запрос атрибута, воз-
можно, будет решением проблемы.
5.2. Очевидно, что дать исчерпывающий ответ на этот вопрос нельзя. Вот несколько
дополнительных указаний.
TYPENAME определен на домене NAME
RVNAME NAME
ATTRNAME NAME
DEGREE NONNEG_INTEGER
CARD NONNEG_INTEGER
RVKIND RVKIND
В свою очередь, предполагается, что эти домены определены следующим образом.
NAME — это множество всех допустимых имен.
NONNEG_INTEGER — множество неотрицательных целых чисел, не превышающих
некоторый верхний предел.
RVKIND — это, грубо говоря, множество {"Base", "View"}.
Заметьте, что мы только что нарушили собственный принцип, состоящий в том,
чтобы по возможности присваивать атрибутам имена соответствующих типов. Это
упражнение показывает, что подобные нарушения могут иметь место, если пере-
менные-отношения спроектированы раньше, чем определены лежащие в их основе
типы (это замечание относится ко всем переменным-отношениям, а не только к
переменным-отношениям каталога).
5.3.
a) TYPE P# POSSREP ( CHAR ) ;
TYPE QTY POSSREP ( INTEGER ) ;
VAR PART STRUCTURE BASE RELATION
{ MAJOR P# P#,
minor”p# P#,
QTY ” QTY }
PRIMARY KEY { MAJOR_Pj, MINORJ># } ;
б) На рис. 5.4 показаны только новые элементы каталога. Обратите внимание, что
элемент CARD в переменной-отношении RELVAR должен быть увеличен на еди-
ницу и для самой переменной-отношения RELVAR. Также кардинальность пере-
менной-отношения PART_STRUCTURE показана равной 0, а не 7 (несмотря на то,
что на рис. 4.6 она содержит семь кортежей), поскольку отношение, конечно
же, будет пустым, если оно только что создано.
в) DROP VAR PART STRUCTURE ;
DROP TYPE QTY”;
DROP TYPE P# ;
186
Часть IL Реляционная модель
TYPE
TYPENAME
P# QTY
RELVAR RVNAME DEGREE CARD RVKIND
1 PARTSTRUCTURE 3 0 Base
ATTRIBUTE
RVNAME ATTRNAME TYPENAME
PARTSTRUCTURE PART-STRUCTURE PART-STRUCTURE MAJOR_P# MINOR_P# QTY P# P# QTY ...
Рис. 5.4. Элементы каталога для переменной-отношения PART_STRUCTURE
5.4. TYPE Si POSSREP( CHAR ) ;
TYPE NAME POSSREP( CHAR ) ;
TYPE Pi POSSREP( CHAR ) ;
TYPE COLOR POSSREP( CHAR ) ;
TYPE WEIGHT POSSREP( RATIONAL
TYPE Ji POSSREP( CHAR ) ;
TYPE QTY POSSREP( INTEGER )
VAR S BASE RELATION
{ S# Si,
SNAME NAME,
STATUS INTEGER,
CITY CHAR }
PRIMARY KEY { Si };
VAR P BASE RELATION
{ Pi Pi,
PNAME NAME,
COLOR COLOR,
WEIGHT WEIGHT,
CITY CHAR }
PRIMARY KEY { Pi } ;
VAR J BASE RELATION
{Ji Ji,
JNAME NAME,
CITY CHAR }
PRIMARY KEY { Ji } ;
VAR SPJ BASE RELATION
{ Si Si,
Pi Pi,
Ji Ji,
QTY QTY }
Глава 5. Домены, отношения и базовые переменные-отношения
187
PRIMARY KEY { S#, P#, J# }
FOREIGN KEY { S# } REFERENCES S
FOREIGN KEY { P# } REFERENCES P
FOREIGN KEY { J# } REFERENCES J
5.5. Ниже приводятся примеры типичных значений для каждого атрибута. Начнем с
переменной-отношения S.
S# : S#('S1')
SNAME : NAME('Smith')
STATUS : 20
CITY : 'London'
Переменная-отношение P.
P# : P# ( 'Pl' )
PNAME : NAME ( 'Nut' )
COLOR : COLOR ( 'Red' )
WEIGHT : WEIGHT ( 12.0 )
CITY : 'London'
Переменная-отношение J.
J# : J# ( 'JI' )
JNAME : NAME ( 'Sorter' )
CITY : 'Paris'
5.6.
а) Корректно; BOOLEAN.
б) He корректно; NAME (THE_NAME(JNAME) || THE_NAME(PNAME)).
Замечание. Идея состоит в том, чтобы соединить два допустимых строковых
представления, а затем преобразовать полученную строку обратно в тип NAME.
Разумеется, если полученная строка не является корректным именем, преобра-
зование выполнено не будет.
в) Корректно; QTY.
г) Не корректно; QTY + QTY(IOO).
д) Корректно; STATUS.
е) Корректно; BOOLEAN.
ж) Не корректно; THE_COLOR(COLOR) = P.CITY.
з) Корректно.
5.7. TYPE LENGTH POSSREP ( RATIONAL ) ;
TYPE POINT POSSREP ( X RATIONAL, Y RATIONAL ) ;
TYPE CIRCLE POSSREP ( R LENGTH, CTR POINT ) ;
/* R - длина радиуса окружности, */
/* a CTR - ее центр */
Единственный оператор выбора для типа CIRCLE выглядит следующим образом.
CIRCLE (г, ctr)
/* Возвращает окружность с радиусом г и центром ctr*/
Операторы ТНЕ_ будут такими.
188
Часть II. Реляционная модель
THE_R(c)
/* Возвращает длину радиуса окружности с */
THE_CTR(c)
/* Возвращает точку, которая является центром окружности с */
a) OPERATOR DIAMETER ( С CIRCLE ) RETURNS ( LENGTH ) ;
RETURN ( 2 * THE_R ( C ) ) ;
END OPERATOR ;
OPERATOR CIRCUMFERENCE ( C CIRCLE ) RETURNS ( LENGTH ) ;
RETURN ( 3.14159 * DIAMETER ( C ) ) ;
END OPERATOR ;
OPERATOR AREA ( C CIRCLE ) RETURNS ( AREA ) ;
RETURN ( 3.14159 * ( THE_R ( C ) ** 2 ) ) ;
END OPERATOR ;
Мы предполагаем, что результат умножения целого числа на значение типа
LENGTH принадлежит типу LENGTH и что результат умножения двух значений ти-
па LENGTH принадлежит типу AREA (где AREA — новый тип, определенный поль-
зователем).
б) OPERATOR DOUBLE_R ( С CIRCLE ) UPDATES ( С ) ;
BEGIN ;
THE R ( С ) := 2 * THE_R ( C ) ;
RETURN ;
END ;
END OPERATOR ;
5.8. Следует отметить, что при определении типа множество соответствующих значений
не создается. Концептуально эти значения уже существуют и всегда будут существо-
вать (задумайтесь, например, о типе INTEGER). Таким образом, все операторы
“определения типов”, т.е. операторы TYPE языка Tutorial D, в действительности вво-
дят в употребление имя, которое далее будет использоваться для ссылок на это мно-
жество значений. Подобным образом оператор DROP TYPE фактически удаляет не со-
ответствующие значения, а только имя, установленное соответствующим оператором
TYPE. Отсюда следует, что “обновление существующего типа” означает удаление су-
ществующего имени типа, а затем повторное присвоение этого же имени другому
множеству значений. Разумеется, для упрощения этой процедуры ничто не мешает
нам использовать какое-либо сокращение наподобие оператора ALTER TYPE.
5.9. Отношение с пустым множеством кортежей имеет вполне разумный смысл и в дей-
ствительности является обычным отношением (аналогом файла, в котором нет запи-
сей). В частности, естественно, каждая базовая переменная-отношение имеет пустое
множество кортежей, когда она впервые создается, как показано в разделе 5.4. Такое
отношение принято называть, хотя это и несколько неточно, пустым отношением.
Но вот что, возможно, является совсем невероятным, так это то, что отношение с
пустым множеством атрибутов тоже имеет вполне разумный смысл! На самом деле
такие отношения оказываются исключительно важными, почти в той же степени, в
какой пустые множества важны в общей теории множеств.
Глава 5. Домены, отношения и базовые переменные-отношения
189
Чтобы рассмотреть это понятие подробнее, вначале обсудим вопрос о том, могут ли
отношения без атрибутов иметь кортежи. В действительности такие отношения мо-
гут иметь не более одного кортежа, а именно — 0-кортеж (т.е. кортеж, не имеющий
значений атрибутов). Таких кортежей не может быть более одного, поскольку все 0-
кортежи дублируют друг друга. Поэтому существует ровно два отношения степени
0: одно, содержащее ровно один кортеж, и одно, совсем не содержащее кортежей.
Эти отношения настолько важны, что, следуя Дарвену [5.5], мы называем их ласко-
выми именами: первое — TABLE_DEE и второе — TABLE_DUM, или для краткости DEE
и DUM (DEE имеет 0-кортеж, a DUM не имеет).
Мы не станем углубляться в детали этого вопроса в данный момент и удовлетво-
римся лишь следующим: значение этих отношений так важно еще и потому, что
DEE соответствует истине (true, или yes), a DUM соответствует л.жи (false, или по).
В упражнениях и ответах к ним в главах 6 и 8 предлагается более детальное изло-
жение данного материала. Подробная информация приводится в [5.5].
5.10. Можно согласиться с тем, что кортеж похож на запись (имеется в виду вхождение, а
не тип), а атрибут похож на поле (подразумевается тип, а не вхождение). Однако это
сходство только приблизительное. О базовой переменной-отношении следует гово-
рить не как об обычном файле, а как о дисциплинированном файле (см. подраздел
“Свойства отношений” в разделе 5.3). Такая “дисциплинированность” позволяет уп-
ростить структуру данных, а следовательно, и операторы, использующиеся для обра-
ботки этих данных, и, как следствие, весь пользовательский интерфейс в целом.
5.11. В принципе, ответ— можно. Изменять каталог можно с помощью обычных
средств, т.е. операций INSERT, UPDATE и DELETE. Однако возможность использова-
ния таких операций могла бы быть потенциально очень опасной, поскольку она
позволяет легко разрушить всю информацию в каталоге (по небрежности или по
иным причинам), после чего система уже не сможет корректно функционировать.
Предположим, например, что для каталога базы данных отделов и служащих до-
пустима следующая операция DELETE.
DELETE RELVAR WHERE RVNAME = NAME ( 'EMP' ) ;
В результате ее выполнения из переменной-отношения RELVAR удаляется кортеж,
описывающий переменную-отношение ЕМР. С точки зрения системы переменной-
отношения ЕМР больше не существует, т.е. система больше не имеет никаких све-
дений об этой переменной-отношении. Значит, все последующие попытки обраще-
ния к этой переменной-отношению будут безуспешными.
Поэтому в большинстве реальных продуктов операции UPDATE, DELETE и INSERT
для каталога или не разрешены вовсе (это обычная практика), или разрешены лишь
для пользователей, наделенных очень высокими правами (возможно, лишь для ад-
министратора базы данных). Вместо этих операторов для изменения каталога ис-
пользуются операторы определения данных (CREATE DOMAIN, CREATE BASE
RELATION и т.п.). Например, в результате выполнения оператора CREATE BASE
RELATION для переменной-отношения ЕМР формируется элемент в переменной-
отношении RELVAR и набор из четырех элементов (по одному для каждого из четы-
рех атрибутов переменной-отношения ЕМР) в переменной-отношении ATTRIBUTE.
(Выполнение этого оператора вызывает также множество других последствий, ко-
190
Часть II. Реляционная модель
торых, однако, мы здесь не будем касаться.) Таким образом, операция определения
нового объекта (нового типа или базовой переменной-отношения) в некотором
смысле является аналогом операции вставки INSERT для каталога. Также операция
удаления объектов DROP является аналогом операции удаления строк DELETE. В
языке SQL, который предоставляет различные операторы ALTER для изменения
элементов каталога различными способами (например, ALTER (base) TABLE), опе-
рация ALTER является аналогом операции изменения UPDATE.
Замечание. Как мы уже видели, каталог включает и элементы для самих перемен-
ных-отношений каталога. Однако эти элементы не создаются явно операцией
CREATE. Вместо этого они создаются автоматически самой системой как часть про-
цедуры инсталляции системы. В сущности, они являются “зашитыми” в систему.
5.12. DROP VAR SPJ, S, Р, J ;
DROP TYPE S#, NAME, P#, COLOR, WEIGHT, J#, QTY ;
Здесь предполагается, что операторы DROP VAR и DROP TYPE могут удалять не-
сколько переменных или типов за одно выполнение.
Глава 5. Домены, отношения и базовые переменные-отношения
191
Глава
Реляционная алгебра
6Л. Введение
Та часть реляционной модели, в которой рассматриваются операторы манипулирова-
ния данными, существенно эволюционировала со времени публикации Коддом статей
[5.1], [6.1]. Однако, как и раньше, основным ее компонентом является так называемая
реляционная алгебра, которая, в основном, состоит из набора операторов, использую-
щих отношения в качестве операндов и возвращающих отношения в качестве результата.
В главе 3 кратко обсуждались операторы выборки, проекции и соединения. В данной гла-
ве эти и некоторые другие операторы рассматриваются более подробно.
В [6.1] Кодд определяет так называемую “начальную” алгебру, т.е. набор из восьми
операторов, символически показанный на рис. 6.1. Определяя именно эти восемь опера-
торов, Кодд преследовал особую цель, речь о которой пойдет в следующей главе. Одна-
ко важно понимать, что алгебра этими восемью операторами не исчерпывается. На са-
мом деле можно было бы определить любое число операторов, которые удовлетворяли
бы простому необходимому условию: “отношение на входе— отношение на выходе”
(множество таких операторов действительно предлагалось разными авторами; см., на-
пример, [6.10]). В этой главе мы сначала рассмотрим операторы Кодда (или, по крайней
мере, его версию этих операторов), а затем используем их в качестве основы для обсуж-
дения различных алгебраических идей. В продолжение этой темы обсуждаются способы,
с помощью которых данный первоначальный набор операторов можно расширить в том
или ином направлении.
Обзор операций начальной алгебры
Как утверждалось выше, реляционная алгебра в том виде, в котором она была опре-
делена Коддом в [6.1], состоит из восьми операторов, составляющих две группы по че-
тыре оператора.
1. Традиционные операции над множествами: объединение, пересечение, разность и
декартово произведение (все они модифицированы с учетом того, что их операн-
дами являются отношения, а не произвольные множества).
2. Специальные реляционные операции: выборка, проекция, соединение и деление.
Ниже приведены упрощенные определения этих восьми операторов (рис. 6.1).
Выборка Возвращает отношение, содержащее все кортежи из заданного от-
ношения, которые удовлетворяют указанным условиям. Операцию
выборки также иногда называют операцией ограничения, поэтому
далее в этой книге будет также употребляться термин ограничение,
если подразумевается данная алгебраическая операция
192
Часть II. Реляционная модель
Соединение Пересечение Разность
а а а Ь с X У Z X У
JJ
Рис 6 1 Первоначальные восемь операторов (обзор)
Проекция Возвращает отношение, содержащее все кортежи (подкортежи) за-
данного отношения, которые остались в этом отношении после ис-
ключения из него некоторых атрибутов
Глава 6. Реляционная алгебра
193
Произведение Возвращает отношение, содержащее все возможные кортежи, кото- рые являются сочетанием двух кортежей, принадлежащих соответст- венно двум заданным отношениям
Объединение Возвращает отношение, содержащее все кортежи, которые принад- лежат либо одному из двух заданных отношений, либо им обоим
Пересечение Возвращает отношение, содержащее все кортежи, которые принад- лежат одновременно двум заданным отношениям
Разность Возвращает отношение, содержащее все кортежи, которые принад- лежат первому из двух заданных отношений и не принадлежат вто- рому
Соединение Возвращает отношение, содержащее все возможные кортежи, кото- рые представляют собой комбинацию атрибутов двух кортежей, принадлежащих двум заданным отношениям, при условии, что в этих двух комбинируемых кортежах присутствуют одинаковые значения в одном или нескольких общих для исходных отношений атрибутах (причем эти общие значения в результирующем кортеже появляются один раз, а не дважды)
Деление Для заданных двух унарных отношений и одного бинарного возвра- щает отношение, содержащее все кортежи из первого унарного от- ношения, которые содержатся также в бинарном отношении и соот- ветствуют всем кортежам во втором унарном отношении
На этом закончим краткий обзор первоначальных операторов. План остальной части
главы такой: в следующем разделе повторно и более подробно рассматривается вопрос
реляционного замыкания. Затем в разделах 6.3 и 6.4 детально обсуждаются восемь пер-
воначальных операторов, предложенных Коддом, а в разделе 6.5 даются некоторые при-
меры их использования для построения запросов. В разделе 6.6 рассматривается более
общий вопрос о назначении реляционной алгебры. В разделе 6.7 описывается несколько
полезных расширений начальной алгебры Кодда, в частности два важных оператора —
EXTEND и SUMMARIZE. В разделе 6.8 приводятся операторы отображения между отноше-
ниями, которые включают атрибуты, принимающие в качестве значений другие отноше-
ния, и между отношениями с атрибутами, которые принимают только скалярные значе-
ния. В разделе 6.9 рассматривается реляционное сравнение. И наконец в разделе 6.10
приводится краткое заключение.
И еще два предварительных замечания.
По очевидным причинам мы часто будем использовать фразы наподобие “X явля-
ется выборкой из R” (где R — некоторая переменная-отношение), в то время как
более корректно следовало бы говорить “X — выборка из отношения, которое яв-
ляется текущим значением переменной-отношения R” или даже “X — это пере-
менная, текущим значением которой является выборка из отношения, которое яв-
ляется текущим значением переменной-отношения R”. Мы надеемся, что такое со-
кращение не приведет к путанице.
Обсуждение SQL-операторов, соответствующих операторам реляционной алгеб-
ры, мы откладываем до главы 7 по причинам, которые будут объяснены в этой
главе позднее.
194
Часть II. Реляционная модель
6.2. Реляционная замкнутость
Уже не раз отмечалось, что результат выполнения любой операции над отношением также
является отношением. Эта особенность называется свойством реляционной замкнутости и
впервые упоминается в главе 3. Там же делается вывод: поскольку результат выполнения лю-
бой операции имеет тот же тип, что и исходные объекты (отношения), результат одной опера-
ции может использоваться в качестве исходных данных для другой. Другими словами, можно
записывать вложенные реляционные выражения, т.е. выражения, в которых операнды са-
ми представлены реляционными выражениями, причем произвольной сложности. (Есть явная
аналогия между возможностями использования вложенных реляционных выражений в реля-
ционной алгебре и вложенных арифметических выражений в обычной арифметике. Действи-
тельно, тот факт, что отношения с точки зрения реляционной алгебры являются замкнутыми,
исключительно важен для нее по тем же причинам, по которым в обычной алгебре важен тот
факт, что с ее точки зрения множество чисел также является замкнутым.)
При обсуждении свойства реляционной замкнутости в главе 3 сознательно умалчи-
вался один существенный момент. Напомним, что отношение имеет две части — заго-
ловок и тело. Нестрого говоря, заголовок — это атрибуты, а тело — это кортежи. Заго-
ловок для базового отношения, т.е. значения базовой переменной-отношения, очевидно,
вполне конкретен и известен системе, поскольку он задается как часть определения со-
ответствующей базовой переменной-отношения. Ну а как же в случае производных от-
ношений? Например, рассмотрим следующее выражение.
S JOIN Р
Оно представляет собой соединение отношения поставщиков и отношения деталей по
совпадению значения названия города (поскольку только атрибут CITY является общим
для этих двух отношений). Мы знаем, что собой представляет тело результата данного
соединения. А какой же будет у него заголовок? Обязательное наличие заголовка дикту-
ется реляционной замкнутостью, и системе должно быть известно, что он собой пред-
ставляет (в равной степени это необходимо знать и пользователю, как мы скоро увидим).
Иначе говоря, результат обязательно— непременно!— должен иметь вполне опреде-
ленный тип отношения. Поэтому, если рассматривать свойство реляционной замкнуто-
сти более строго, каждая реляционная операция должна быть определена таким образом,
чтобы выдавать результат с надлежащим типом отношения (в частности, с соответст-
вующим набором имен атрибутов или заголовком)1.
Основная причина, по которой мы требуем, чтобы каждое результирующее отноше-
ние обязательно имело соответствующий набор имен атрибутов, заключается в необхо-
димости иметь возможность ссылаться на эти имена атрибутов в последующих опера-
циях, в частности в последующих операциях, расположенных на более глубоких уровнях
вложенного выражения. Например, если бы мы не знали, что результат вычисления вы-
ражения S JOIN Р включает атрибут с именем CITY, то мы просто не смогли бы даже за-
писать выражение, подобное следующему.
(S JOIN Р) WHERE CITY = 'Athens'
I Отметим, что данный аспект алгебры, как правило, недооценивается в литературе (и, как
это ни печально, в языке SQL, а значит, и в SQL-продуктах). Это не относится к двум заметным
работам —Холла и др. [6.10] и Дарвена [6.2]. Представленная в данной главе версия реляционной
алгебры была выбрана в значительной мере под влиянием этих двух работ.
Глава 6. Реляционная алгебра
195
Другими словами, необходим такой встроенный в реляционную алгебру набор пра-
вил вывода типов (отношений), чтобы можно было вывести тип (отношения) на выходе
произвольной реляционной операции, зная тип или типы (отношения) на входе этой опе-
рации. Задав такие правила для всех операций, можно гарантировать, что для реляцион-
ного выражения любой сложности будет вычисляться результат, имеющий вполне опре-
деленный тип (отношения) и, в частности, известный набор имен атрибутов.
Для достижения этой цели в качестве предварительного действия введем новый опе-
ратор RENAME, предназначенный для переименования атрибутов в определенном отноше-
нии. Точнее, для заданного отношения оператор RENAME возвращает другое отношение,
которое идентично начальному, за исключением того, что по крайней мере один из атри-
бутов имеет другое имя. (Заданное отношение, конечно же, может быть результатом вы-
числения реляционного выражения, возможно, включающего другие алгебраические
операции.) Например, можно написать следующее.
S RENAME CITY AS SCITY
С помощью этого выражения (обратите внимание, что рассматриваемая запись явля-
ется выражением, а не “командой” или оператором, а значит, может быть вложена в
другие выражения) вычисляется отношение, имеющее то же самое тело, что и отноше-
ние S, но с именем атрибута SCITY вместо CITY.
S# SNAME STATUS SCITY
S1 Smith 20 London
S2 Jones 10 Paris
S3 Black 30 Paris
S4 Clark 20 London
S5 Adams 30 Athens
Важно отметить, что выражение RENAME не изменяет базовую переменную-отношение
поставщиков в базе данных — оно является выражением (точно так, как и выражение
S JOIN SP) и, следовательно, выдает некоторый результат (в данном случае этот резуль-
тат очень похож на текущее значение переменной-отношения поставщиков).
Вот еще один пример (на этот раз переименовывается сразу несколько атрибутов).
Р RENAME PNAME AS PN, WEIGHT AS WT
Результат вычисления этого выражения будет выглядеть следующим образом.
P# PN COLOR WT CITY
Pl Nut Red 12.0 London
P2 Bolt Green 17.0 Paris
P3 Screw Blue 17.0 Rome
P4 Screw Red 14.0 London
P5 Cam Blue 12.0 Paris
P6 Cog Red 19.0 London
Стоит явно подчеркнуть: наличие оператора RENAME означает, что (в отличие от языка
SQL) в реляционной алгебре не требуется использовать механизм уточнения имен атри-
бутов наподобие S.S#.
196
Часть II Реляционная модель
6.3. Синтаксис
В этом разделе представлен синтаксис (в основном, синтаксис языка Tutorial D), ко-
торый мы будем использовать для выражений реляционной алгебры.
Замечание. В большинстве работ по базам данных для обозначения реляционных
операторов используются математические или греческие символы. Например, буква а
обозначает оператор выборки, буква л — проекцию, знак п — пересечение и т.д. Мы же
предпочитаем использовать ключевые слова, такие как JOIN и WHERE. Хотя при этом дли-
на выражений увеличивается, такие выражения являются более дружественными по от-
ношению к пользователю.
реляционное выражение>
::= RELATION { <список выражений кортежей> }
<имя переменной-отношения>
реляционная операция>
( реляционное выражение> )
Здесь реляционное выражение^ — это выражение, обозначающее отношение
(конечно же, имеется в виду значение отношения). Первый формат — вызов селектора
отношения (частным случаем которого является литерал отношения); мы не заостряем
внимание на синтаксисе выражения <выражение кортежа>, надеясь, что его общая
идея будет в полной мере проиллюстрирована на примерах. Остальные форматы гово-
рят сами за себя.
реляционная операция>
::= <проекция> | <не проекция>
Мы различаем операции <проекция> и <не проекция> в синтаксисе только из-за не-
обходимости соблюдать приоритет операторов (удобнее назначать более высокий при-
оритет операторам проекции).
<проекция>
::= реляционное выражение>
{ [ ALL BUT ] <список имен атрибутов> }
Здесь параметр реляционное выражение> не должен иметь вид <не проекциЯ>.
<не проекция>
::= <переименование>
<объединение> | <пересечение> | <вычитание> | <произведение>
<выборка> | <соединение> | <деление>
<переименование>
::= реляционное выражение>
RENAME <список переименовываемых элементов>
Здесь параметр реляционное выражение> не должен иметь вид <не проекциям Син-
таксис параметра Переименовываемый элемент> можно увидеть в примерах из преды-
дущего раздела.
Глава 6. Реляционная алгебра
197
<объединение?
::= реляционное выражение?
UNION реляционное выражение?
Здесь параметры реляционное выражение? не должны иметь вид <не проекция?1, за
исключением тех случаев, когда одно или оба выражения, в свою очередь, являются вы-
ражениями типа <объединение?.
Пересечение?
::= реляционное выражение?
INTERSECT реляционное выражение?
Здесь параметры реляционное выражение? не должны иметь вид <не проекция?, за
исключением тех случаев, когда одно или оба выражения, в свою очередь, являются вы-
ражениями <Пересечение?.
<вычитание?
::= реляционное выражение?
MINUS реляционное выражение?
Здесь параметры реляционное выражение? не должны иметь вид <не проекция?.
Произведение?
::= реляционное выражение?
TIMES реляционное выражение?
Здесь параметры реляционное выражение? не должны иметь вид <не проекция?, за
исключением тех случаев, когда одно или оба выражения, в свою очередь, являются вы-
ражениями Произведение?.
<выборка?
::= реляционное выражение? WHERE <логическое выражение?
Здесь параметр реляционное выражение? не должен иметь вид <не проекция?.
Замечание. Параметр <логическое выражение? может включать ссылки на атрибуты
отношения, обозначенного как реляционное выражение?, во всех случаях, когда допус-
тимо обращение к оператору выбора (например, выражение S WHERE CITY = 'London'
является корректной формой операции Пыборка?).
Поединение?
:: = реляционное выражение?
JOIN реляционное выражение?
Здесь параметры реляционное выражение? не должны иметь вид <не проекция?, за
исключением тех случаев, когда одно или оба выражения, в свою очередь, являются вы-
ражениями типа Поединение?.
<деление?
::= реляционное выражение?
DIVIDEBY реляционное выражение? PER per?
198
Часть II. Реляционная модель
Здесь параметры реляционное выражение> не должны иметь вид <не проекциях
<рег>
::= реляционное выражение>
| ( реляционное выражение^ реляционное выражениё> )
Здесь параметры реляционное выражение> не должны иметь вид <не проекциях
6.4. Семантика
В этом разделе мы дадим толкование приведенного в разделе 6.3 синтаксиса и
обсудим некоторые конкретные примеры. Операторы будут рассматриваться в такой
последовательности: объединение, пересечение, вычитание, произведение, выборка,
проекция, естественное соединение и деление (оператор RENAME уже рассматривался
в разделе 6.2).
Объединение
В математике объединением двух множеств называется множество, состоящее из
всех элементов, принадлежащих хотя бы одному из исходных множеств. Поскольку от-
ношение является множеством (точнее, содержит множество), а именно — множеством
кортежей, очевидно, что можно получить объединение двух таких множеств. Результа-
том выполнения этой операции будет множество, состоящее из всех кортежей, которые
принадлежат хотя бы одному из исходных отношений. Например, объединение множе-
ства кортежей описания поставщиков переменной-отношения S и множества кортежей
описания деталей переменной-отношения Р, определенно, будет множеством.
Однако, хотя результатом объединения является множество, оно не всегда будет от-
ношением, поскольку в отношении не может быть кортежей разных типов. Нам же, без-
условно, требуется, чтобы результатом операции объединения обязательно было отно-
шение, поскольку необходимо соблюдать свойство реляционной замкнутости. Поэтому
объединение в реляционной алгебре — это не обычное математическое объединение, а,
скорее, специальный вид объединения, требующий, чтобы отношения на входе были со-
вместимы по типу, т.е. чтобы, например, оба отношения содержали кортежи поставщи-
ков или кортежи деталей, но не комбинацию этих типов кортежей. Если два исходных
отношения совместимы по типу, то результат их объединения также будет отношением и
свойство замкнутости будет сохранено2.
Теперь дадим точное определение оператора реляционного объединения. Для задан-
ных отношений А и В одного и того же типа объединением этих двух отношений (что за-
писывается как A UNION В) называется новое отношение того же типа с телом, состоя-
щим из множества всех кортежей t, которые принадлежат либо отношению А, либо от-
ношению В, либо обоим отношениям одновременно.
2 Исторически сложилось так, что в большинстве публикаций по базам данных (в том числе
в предыдущих изданиях этой книги) для обозначения совместимых по типу отношений использу-
ется термин совместимость относительно объединения. Однако по ряду причин этот термин
не совсем удачен. Наиболее очевидной причиной является то, что данное обозначение в действи-
тельности применяется не только к операции объединения.
Глава 6. Реляционная алгебра
199
Пример. Пусть отношения А и В будут такими, как показано на рис. 6.2 (отношение А
представляет поставщиков из Лондона, а отношение В — поставщиков, которые, скажем,
поставляют деталь под номером '₽!')• Тогда выражение A UNION В (см. рис. 6.2, а)
представляет поставщиков, которые или находятся в Лондоне, или поставляют деталь
под номером ' Р1' (или и то, и другое). Обратите внимание, что результат имеет три кор-
тежа, а не четыре — повторяющиеся кортежи удаляются по определению. Вопрос удале-
ния дубликатов не возникает в других традиционных операциях над множествами. Фак-
тически еще существует только одна операция (помимо объединения), где этот вопрос
актуален, — операция проекции (подробнее о ней речь идет далее в этом разделе).
S# SNAME STATUS CITY
S1 Smith 20 London
S4 Clark 20 London
В
S# SNAME STATUS CITY
SI Smith 20 London
S2 Jones 10 Paris
a) Объединение S# SNAME STATUS CITY
(A UNION B) SI Smith 20 London
S4 Clark 20 London
S2 Jones 10 Paris
6) Пересечение S# SNAME STATUS CITY
(A INTERSECT B) SI Smith 20 London
в) Вычитание r) Вычитание
(A MINUS B) (В MINUS A)
S# SNAME STATUS CITY S# SNAME STATUS CITY
S4 Clark 20 London S2 Jones 10 Paris
Рис. 6.2. Примеры операций объединения, пересечения и вычитания
Пересечение
Как и для оператора объединения, для реляционного оператора пересечения (и по тем
же причинам) необходимо, чтобы его операнды были совместимы по типу. Итак, пересе-
чением двух совместимых по типу отношений А и В (что записывается как A INTERSECT В)
называется отношение того же типа с телом, состоящим из множества всех кортежей t, ко-
торые принадлежат одновременно обоим исходным отношениям А и В.
Пример. Пусть вновь отношения А и В будут такими, как показано на рис. 6.2. Тогда
выражение A INTERSECT В (см. рис. 6.2, б) представляет поставщиков, которые находят-
ся в Лондоне и поставляют деталь под номером 'Р1'.
Вычитание
Как и для операторов объединения и пересечения, для реляционного оператора вычи-
тания необходимо, чтобы его операнды были совместимы по типу. Тогда вычитанием
двух совместимых по типу отношений А и В (что записывается как A MINUS В, причем
200
Часть II. Реляционная модель
порядок их указания здесь играет роль) называется отношение того же типа, что и отно-
шения А и В, с телом, состоящим из множества всех кортежей t, которые принадлежат
отношению А, но не принадлежат отношению В.
Пример. Пусть еще раз отношения А и В будут такими, как показано на рис. 6.2. Тогда
выражение A MINUS В (см. рис. 6.2, в) представляет поставщиков, которые находятся в
Лондоне и не поставляют деталь под номером 'Р1', а выражение В MINUS А (см. рис. 6.2, г)
представляет поставщиков, которые поставляют деталь под номером ' Р1' и не находятся в
Лондоне. Заметьте, что при вычитании учитывается порядок следования операндов, точно
так, как в обычной арифметике (например, 5-2и2-5 — это не одно и то же).
Произведение
В математике декартово произведение (или для краткости— просто произведение)
двух множеств является множеством всех таких упорядоченных пар элементов, что пер-
вый элемент в каждой паре берется из первого множества, а второй элемент в каждой
паре берется из второго множества. Следовательно, декартово произведение двух отно-
шений должно быть множеством упорядоченных пар кортежей. Но, опять-таки, необ-
ходимо сохранить свойство замкнутости; иначе говоря, результат должен содержать кор-
тежи, а не упорядоченные пары кортежей. Поэтому версия декартова произведения в ре-
ляционной алгебре представляет собой расширенную форму операции, в которой каждая
упорядоченная пара кортежей заменяется одним кортежем, образованным из двух сцеп-
ленных кортежей этой пары. “Сцепление” здесь означает объединение (в смысле теории
множеств, а не реляционной алгебры), т.е. кортежи { А1:а1, А2:а2, Am:am }и{
В1:Ы, В2:Ь2, Bn:bn } объединяются в один кортеж.
{ А1:а1, А2:а2, Am:am, В1:Ы, В2:Ь2, Bn:bn }
Другая проблема, возникающая в связи с декартовым произведением, заключается в том, что
результирующее отношение должно иметь правильно сформированный заголовок. Очевидно,
что заголовок результирующего отношения должен содержать все атрибуты из двух исходных
отношений. Однако, если эти два заголовка имеют какие-то общие имена атрибутов, возникает
проблема. Если допустить подобную операцию, то результирующий заголовок будет иметь два
одинаковых атрибута, а значит, будет “неверно сформированным”. Поэтому, чтобы построить
декартово произведение двух отношений, которые имеют какие-то общие имена атрибутов, не-
обходимо прежде применить оператор RENAME для переименования соответствующих атрибутов.
В результате можно определить (реляционное) декартово произведение двух отно-
шений А и В (что записывается как A TIMES В), где отношения А и В не имеют общих
имен атрибутов, как новое отношение с заголовком, представляющим собой объедине-
ние заголовков двух исходных отношений А и В, и с телом, состоящим из множества всех
кортежей t, таких, что каждый кортеж t представляет собой объединение двух кортежей,
один из которых принадлежит отношению А, а другой — отношению В. Обратите внима-
ние, что кардинальность результата равняется произведению кардинальностей исходных
отношений А и В, а степень равняется сумме их степеней.
Пример. Пусть отношения А и В будут такими, как показано на рис. 6.3 (отношение А
представляет, например, номера всех существующих на данный момент поставщиков, а
отношение В — номера всех поставляемых на текущий момент деталей). Тогда произве-
дение A TIMES В — это набор всех возможных на текущий момент пар из значений но-
мера поставщика и номера детали.
Глава 6. Реляционная алгебра
201
А S# В P#
S1 S2 S3 S4 S5 Р1 Р2 РЗ Р4 Р5 Р6
Декартово произведение (A TIMES В)
S# P#
S1 S1 S1 S1 S1 S1 Р1 Р2 РЗ Р4 Р5 Р6 : со со со от со со м м м ьэ м м Р1 S3 Р1 Р2 S3 Р2 РЗ S3 РЗ Р4 S3 Р4 Р5 S3 Р5 Р6 S3 Р6 S4 S4 S4 S4 S4 S4 Р1 Р2 РЗ Р4 Р5 Р6 |w ОТ ОТ ОТ ОТ ОТ сл сл СЛ СЛ сл СЛ Р1 Р2 РЗ Р4 Р5 Р6
Рис. 6.3. Пример операции декартова произведения
Выборка
Пусть задано отношение А с атрибутами X и Y (и, возможно, с другими атрибутами), а
символ 0 обозначает любой скалярный оператор сравнения (=, *, >, > и т.д.), такой, что
условие X 0 Y корректно определено и при заданных значениях атрибутов X и Y его
проверка дает значение истина или ложь. Тогда 0-выборкой из отношения А по атри-
бутам X и Y (что записывается, например, как S WHERE CITY = 'London', причем именно
в этом порядке) называется отношение, имеющее тот же заголовок, что и отношение А, и
тело, содержащее множество всех кортежей t отношения А, для которых проверка усло-
вия X 0 Y дает значение истина.
Необходимо отметить следующее.
1. Обращение к оператору выбора, в частности литерал, может быть указано как вме-
сто атрибута X, так и вместо атрибута Y (или вместо обоих); на практике это обыч-
ный случай. Тем не менее этот “обычный случай” следует рассматривать всего
лишь как сокращение. Например, оператор выборки
S WHERE CITY = 'London',
по сути, является всего лишь сокращенной записью следующего выражения:
( EXTEND S ADD 'London' AS TEMP ) WHERE CITY = TEMP
(здесь имя TEMP может быть произвольным). Оператор EXTEND будет рассмотрен в
разделе 6.7.
\2. Условия в форме b (где b — обращение к оператору логического выбора) являются
допустимыми.
202
Часть II. Реляционная модель
3 . В приведенном определении операции выборки в выражении WHERE допускаются
только единичные операции сравнения. Однако на основании свойства замкнутости
можно недвусмысленно расширить определение до такой формы, в которой усло-
вие в выражении WHERE будет содержать произвольное число логических сочетаний
подобных единичных сравнений благодаря следующим тождествам.
A WHERE cl AND с2 = ( A WHERE cl ) INTERSECT ( A WHERE c2 )
A WHERE cl OR c2 = ( A WHERE cl ) UNION ( A WHERE c2 )
A WHERE NOT c = A MINUS ( A WHERE c )
Поэтому впредь мы будем подразумевать, что параметр Логическое выражение> в
предложении WHERE для операции выборки содержит произвольное число логических
сочетаний единичных сравнений (с использованием круглых скобок, если необходи-
мо указать желаемый порядок вычисления), где каждое единичное сравнение, в свою
очередь, включает либо атрибуты указанного отношения, либо обращение к операто-
ру выборки, либо и то, и другое. Обратите внимание, что значение параметра
Логическое выражение> может быть истолковано как истина или ложь для каждого
заданного кортежа в отдельности независимо от остальных. Описанное выше значе-
ние параметра логическое выражений принято называть условием выборки.
В результате выполнения оператора выборки будет получено “горизонтальное” под-
множество заданного отношения, т.е. такое подмножество кортежей заданного отноше-
ния, для которого удовлетворяется указанное условие выборки. На рис. 6.4 приводится
несколько примеров операции выборки.
S WHERE CITY = ‘London’
S# SNAME STATUS CITY
S1 Smith 20 London
S4 Clark 20 London
Р WHERE WEIGHT <
WEIGHT (14.0)
P# PNAME COLOR WEIGHT CITY
Pl Nut Red 12.0 London
P5 Cam Blue 12.0 Paris
SP WHERE S# - S# ( ‘S6’ )
OR P# - P# ( ‘P7’ )
S# P# QTY
Puc. 6.4. Примеры операций выборки
Проекция
Пусть задано отношение А с атрибутами X, Y, ... , Z (и, возможно, с другими). То-
гда проекцией отношения А по атрибутам X, Y, ... , Z (что записывается как А { X,
Y, ... , Z }) называется отношение, удовлетворяющее следующим требованиям.
Его заголовок получается из заголовка отношения А посредством удаления из него
всех атрибутов, не входящих в множество {X, Y, ... , Z}.
Глава 6. Реляционная алгебра
203
Его тело содержит множество всех кортежей вида {X:x, Y:y, ... , Z:z}, таких,
для которых в отношении А значение атрибута X равно х, значение атрибута Y рав-
но у,..., значение атрибута Z равно z.
Таким образом, с помощью оператора проекции создается “вертикальное” подмноже-
ство заданного отношения, т.е. подмножество, получаемое путем исключения всех атри-
бутов, не указанных в заданном списке атрибутов, с последующим исключением дубли-
рующихся кортежей (подкортежей) из того, что осталось от исходного отношения.
Из этого определения можно сделать следующие выводы.
1. Никакой атрибут не может быть указан в списке атрибутов более одного раза
(почему?).
2. Если в списке атрибутов указаны все атрибуты отношения А, то такая проекция
представляет собой тождественную проекцию.
3. Проекция вида А{ } (т.е. такая, в которой список атрибутов пуст) также допустима.
Она представляет собой нулевую проекцию. Подробности приводятся в упр. 6.8-
6.10 в конце этой главы.
Несколько примеров операции проекции показано на рис. 6.5. Обратите внимание, что в
первом примере (проекция отношения поставщиков по атрибуту CITY), несмотря на то что
исходное отношение S имеет пять кортежей (и, следовательно, пять значений городов), в
результирующем отношении присутствует только три города, поскольку дублирующиеся
кортежи исключены. Аналогичные замечания можно сделать и для других примеров.
S { CITY } CITY London Paris Athens
Р { COLOR, CITY } COLOR CITY
Red Green Blue Blue London Paris Rome Paris
( S WHERE CITY = ‘PARIS’ ) { S# } S# S2 S3
Рис. 6.5. Примеры операций проекции
Отметим, что часто на практике удобно указывать не те атрибуты, по которым берет-
ся проекция, а те, которые проекцией “отбрасываются”. Например, удобнее сказать
“проекция, исключающая из отношения Р атрибут WEIGHT ” вместо “проекция отношения
Р по атрибутам P#, PNAME, COLOR и CITY”.
Р { ALL BUT WEIGHT }
204
Часть II. Реляционная модель
Соединение
Операция соединения имеет несколько разновидностей. Однако наиболее важным, без со-
мнения, является естественное соединение, причем настолько важным, что общий термин
соединение почти всегда используется для обозначения именно естественного соединения.
Этой практики мы будем придерживаться и в данной книге. Далее приводится определение
(оно несколько абстрактное, но мы считаем, что читатели уже знают о естественном соедине-
нии на интуитивно понятном уровне из главы 3). Пусть отношения А и В имеют заголовки
{ XI, Х2, ... , Xm, Yl, Y2, ... , Yn }
и
{ Yl, Y2, ... , Yn, Zl, Z2, ... , Zp }
соответственно, т.е. атрибуты Yl, Y2, ... , Yn (и только они) — общие для двух этих от-
ношений, XI, Х2, ... , Хш — остальные атрибуты отношения А и Zl, Z2, ... , Zp — ос-
тальные атрибуты отношения В. Далее мы будем рассматривать выражения {XI, Х2, ... ,
Xm}, {Yl, Y2, ... , Уп}и{21, Z2, ... , Zp} как три составных атрибута X, Y и Z соответ-
ственно. Тогда естественным соединением отношений А и В (что записывается как A JOIN
В) называется отношение с заголовком {X, Y, Z} и телом, содержащим множество всех
кортежей вида {Х:х, Y:y, Z:z}, таких, для которых в отношении А значение атрибута X
равно х, а значение атрибута Y равно у и в отношении В значение атрибута Y равно у, а зна-
чение атрибута Z равно z.
Пример естественного соединения (естественное соединение S JOIN Р по общему ат-
рибуту CITY) приведен на рис. 6.6.
S# SNAME STATUS CITY P# PNAME COLOR WEIGHT
S1 Smith 20 London Pl Nut Red 12.0
S1 Smith 20 London P4 Screw Red 14.0
S1 Smith 20 London P6 Cog Red 19.0
S2 Jones 10 Paris P2 Bolt Green 17.0
S2 Jones 10 Paris P5 Cam Blue 12.0
S3 Blake 30 Paris P2 Bolt Green 17.0
S3 Blake 30 Paris P5 Cam Blue 12.0
S4 Clark 20 London Pl Nut Red 12.0
S4 Clark 20 London P4 Screw Red 14.0
S4 Clark 20 London P6 Cog Red 19.0
Рис. 6.6. Естественное соединение S JOIN Р
Замечание. Хотелось бы еще раз остановиться на том факте (хотя это неоднократно
отмечалось выше и явно показано на рис. 6.6), что соединения необязательно выполня-
ются по внешнему ключу и соответствующему первичному ключу, хотя такие соедине-
ния весьма распространены и являются важным частным случаем.
Теперь обратимся к операции Q-соединения. Она предназначается для тех случаев
(сравнительно редких, но всем известных), когда нужно соединить два отношения на основе
некоторых условий, отличных от эквивалентности. Пусть отношения А и В не имеют общих
Глава 6. Реляционная алгебра
205
имен атрибутов (как и в рассмотренной выше операции декартова произведения) и 0 опреде-
ляется так же, как и в операции выборки. Тогда ©-соединением отношения А по атрибуту X с
отношением В по атрибуту Y называется результат вычисления следующего выражения.
( A TIMES В ) WHERE X 0 У
Другими словами, ©-соединение — это отношение с тем же заголовком, что и при
декартовом произведении отношений А и В, и с телом, содержащим множество кортежей
t, таких, что кортеж t принадлежит этому декартову произведению и вычисление усло-
вия X 0 Y для кортежа t дает значение истина.
В качестве примера предположим, что необходимо вычислить “больше чем”-
соединение отношения S по атрибуту CITY с отношением Р по атрибуту CITY
(предполагается, что операция “>” имеет смысл для сравнения названий городов и ин-
терпретируется просто как “далее в алфавитном порядке”). Соответствующим выраже-
нием реляционной алгебры будет следующее.
( ( S RENAME CITY AS SCITY ) TIMES
( P RENAME CITY AS PCITY ) )
WHERE SCITY > PCITY
Обратите внимание на переименование атрибутов в этом примере. Конечно, доста-
точно было бы переименовать лишь один из двух атрибутов CITY. Единственный смысл
двойного переименования — это симметрия. Результат вычисления данного выражения
показан на рис. 6.7.
S# SNAME STATUS SCITY P# PNAME COLOR WEIGHT PCITY
S2 Jones 10 Paris Pl Nut Red 12 London
S2 Jones 10 Paris P4 Screw Red 14 London
S2 Jones 10 Paris P6 Cog Red 19 London
S3 Blake 30 Paris Pl Nut Red 12 London
S3 Blake 30 Paris P4 Screw Red 14 London
S3 Blake 30 Paris P6 Cog Red 19 London
Рис. 6.7. “Больше чем ’’-соединение отношений поставщиков и деталей по атрибуту на-
звания города
Если условие 0 является условием “равно”, то ©-соединение называется равно-
соединением. Из определения следует, что результат равно-соединения должен вклю-
чать два атрибута, значения которых должны быть равны в каждом кортеже отношения.
Если исключить один из этих атрибутов (с помощью операции проекции), результатом
будет обычное естественное соединение! Например, выражение, представляющее есте-
ственное соединение отношений поставщиков и деталей (по атрибуту города) S JOIN Р,
эквивалентно следующему более сложному выражению.
( ( S TIMES ( Р RENAME CITY AS PCITY ) )
WHERE CITY = PCITY )
{ ALL BUT CITY }
Замечание. В языке Tutorial D нет прямой поддержки оператора ©-соединения, по-
скольку он не так уж часто используется на практике и, как мы уже видели, не является
примитивным.
206
Часть II. Реляционная модель
Деление
В [6.3] вводятся два разных оператора деления— Small Divide и Great Divide. В языке
Tutorial D оператору <делениё>, список <рег> которого состоит только из одного парамет-
ра реляционное выражение^ соответствует операция Small Divide, а оператору <деление>,
список <рег> которого состоит из двух разделенных запятыми параметров реляционное
выражение^ соответствует операция Great Divide. Приведенное далее описание относится
только к частному ограниченному случаю операции Small Divide. Оператор Great Divide и
подробности, касающиеся операции Small Divide, приводятся в [6.3].
Необходимо сказать, что рассмотренная здесь версия оператора Small Divide отлича-
ется от оригинального оператора, предложенного Коддом. Фактически это улучшенная
версия, в которой исправлены недостатки, вызывавшие трудности при работе с пустыми
отношениями. Данная версия также отличается от оператора Small Divide, рассмотрен-
ного в нескольких первых изданиях настоящей книги.
Дадим теперь определение оператора деления. Пусть отношения А и В имеют заго-
ловки {XI, Х2, ... , Xm } и { Yl, Y2, ... , Yn } соответственно (т.е. заголовки от-
ношений А и В не пересекаются). Пусть также отношение С имеет следующий заголовок.
{ XI, Х2, ... , Xm, Yl, Y2, ... , Yn } .
(Иначе говоря, заголовок отношения С является объединением заголовков отноше-
ний А и В.) Далее будем рассматривать множества { XI, Х2, ... , Xm } и { Yl, Y2,
... , Yn } как составные атрибуты X и Y соответственно. Тогда результатом деления
отношения А на отношение В по отношению С (что записывается как A DIVIDEBY В
PER С, где отношение А представляет собой делимое, отношение В — делитель, а от-
ношение С— “посредник”) называется отношение с заголовком {X} и телом, содер-
жащим множество всех кортежей вида {Х:х}, таких, что кортеж вида {X:х, Y:у} при-
надлежит отношению В для всех кортежей вида {Y:у}, принадлежащих отношению В. С
Нестрого это можно сформулировать так: результат содержит такие Х-значения из от-
ношения А, для которых соответствующие Y-значения из отношения С включают все
Y-значения из отношения В.
На рис. 6.8 показаны некоторые простые примеры операции деления. В каждом слу-
чае делимое (отношение DEND) — это проекция текущего значения переменной-
отношения S по атрибуту S#, посредник (MED)— это проекция текущего значения пере-
менной-отношения SP по атрибутам S# и Р#, а три делителя (отношения DOR)— такие,
как показано на рисунке. В частности, обратите внимание на последний пример, в кото-
ром делителем является отношение, содержащее номера всех известных в данный мо-
мент деталей. В результате, очевидно, получим номера поставщиков, поставляющих все
типы этих деталей. Как видно из примера, оператор DIVIDEBY полезен именно для запро-
сов такого рода. Более того, если запрос на обычном языке включает слово “все”
(“определить поставщиков всех типов деталей”), то почти наверняка понадобится ис-
пользовать операцию деления3. Тем не менее следует отметить, что подобные запросы
удобнее записывать в терминах реляционных сравнений (раздел 6.9).
3 Действительно, операция деления задумывалась Коддом как алгебраический аналог кванто-
ра всеобщности (глава 7), а проекция — как алгебраический аналог квантора существования.
Глава 6. Реляционная алгебра
207
DEND S# MED S# P# • •
S1 SI Pl S2 Pl
S2 SI P2 S2 P2
S3 SI P3 S3 P2
S4 SI P4 S4 P2
S5 SI P5 S4 P4
SI P6 S4 |P5
DOR P# ( I DOR P# DOR P#
pi. P2 Pl
P4 P2
P3
P4
P5
P6
DEND DIVIDEBY DOR PER MED
S# S# S#
SI SI SI
|S2 S4
Рис. 6.8. Примеры операции деления
Ассоциативность и коммутативность
Легко проверить, что операция объединения (UNION) ассоциативна, т.е. если А, В и
С — произвольные реляционные выражения (дающие совместимые по типу результаты),
то приведенные ниже два выражения логически эквивалентны.
( A UNION В ) UNION С
A UNION ( В UNION С )
Следовательно, для удобства можно разрешить запись последовательных операторов
объединения без использования круглых скобок. Поэтому предыдущие выражения мож-
но однозначно упростить следующим образом.
A UNION В UNION С
Аналогичные замечания можно сделать и для операций пересечения (INTERSECT), де-
картова произведения (TIMES) и соединения (JOIN) (но не операции вычитания MINUS).
Заметим также, что операции объединения (UNION), пересечения (INTERSECT), декар-
това произведения (TIMES) и соединения (JOIN) (но не операция вычитания MINUS) еще и
коммутативны, т.е. выражения A UNION В и В UNION А эквивалентны, что справедливо и
для операций пересечения, декартова произведения и соединения.
208
Часть II. Реляционная модель
Замечание. К вопросу ассоциативности и коммутативности мы еще вернемся в гла-
ве 17. А относительно операции декартова произведения мимоходом заметим, что в тео-
рии множеств она не является ни ассоциативной, ни коммутативной, но ее расширенная
версия, как мы ее здесь определили, и ассоциативна, и коммутативна.
Наконец, отметим, что если отношения А и В не имеют общих атрибутов, то операция
A JOIN В эквивалентна операции A TIMES В [5.5], т.е. в таком случае естественное со-
единение вырождается в декартово произведение. По этой причине в версии языка
Tutorial D, описанной в [3.3] оператор TIMES не поддерживается.
6.5. Примеры
В этом разделе представлено несколько примеров использования выражений реляци-
онной алгебры для формулирования запросов к базе данных. Читателю рекомендуется
проверить их выполнение на примере данных, приведенных на рис. 3.8.
6.5.1. Получить имена поставщиков детали
с номером ‘Р2’
( ( SP JOIN S ) WHERE P# = P# ('P2') ) ) { SNAME }
Пояснение. Первым выполняется естественное соединение отношений SP и S по но-
мерам поставщиков, и в результирующем отношении каждый кортеж отношения SP
(концептуально) дополняется соответствующей информацией о поставщике (т.е. соот-
ветствующими значениями атрибутов SNAME, STATUS и CITY). Затем из результата соеди-
нения просто выбираются такие кортежи, в которых значение атрибута P# равно 'Р2'. И
наконец выполняется проекция полученной выборки по атрибуту SNAME. Конечный ре-
зультат имеет единственный атрибут SNAME.
6.5.2. Получить имена поставщиков по крайней мере
одной красной детали
( ( ( Р WHERE COLOR = COLOR ( 'Red' ) )
JOIN SP ) { S# } JOIN S ) { SNAME }
И снова в результате получаем единственный атрибут SNAME.
Вот другой вариант формулировки этого же запроса.
( ( ( Р WHERE COLOR = COLOR ( 'Red' ) ) { P# }
JOIN SP ) JOIN S ) { SNAME }
Таким образом, в примере подчеркивается одно важное обстоятельство: как правило,
существует возможность формулирования одного и того же запроса несколькими способа-
ми. Некоторые следствия существования этой возможности обсуждаются далее, в главе 17.
6.5.3. Получить имена поставщиков всех типов деталей
( ( S { S# } DIVIDEBY Р { P# } PER SP { S#, P# } )
JOIN S) { SNAME }
И вновь в результате получаем единственный атрибут SNAME.
Глава 6. Реляционная алгебра
209
6.5.4. Получить номера поставщиков по крайней мере
тех типов деталей, которые поставляет поставщик
с номером ‘S2’
S { S# } DIVIDEBY ( SP WHERE S# = S# ( 'S2' ) ) { P# }
PER SP { S#, P# }
В результате получаем единственный атрибут S#.
6.5.5. Получить все пары номеров поставщиков,
находящихся в одном городе
( ( ( S RENAME S# AS SA ) { SA, CITY } JOIN
( S RENAME S# AS SB ) { SB, CITY } )
WHERE SA < SB ) { SA, SB }
В результате получаем отношение из двух атрибутов — SA и SB. Конечно, достаточно
было бы переименовать лишь один атрибут в одном из операндов соединения. Мы пере-
именовали оба атрибута для симметрии.
Замечание. Предполагается, что для типа S# определен оператор Условие SA<SB
необходимо по следующим двум причинам.
Чтобы исключить из результата пары номеров поставщиков вида (х, х)
Чтобы избежать наличия в результате одновременно двух пар вида (х, у) и (у, х)
Для того чтобы проиллюстрировать использование предложения WITH, сформулируем
этот же запрос иначе. Данное предложение позволяет ввести сокращенные имена для
выражений и, следовательно, упростить написание длинных запросов. (В действительно-
сти мы уже использовали оператор WITH в разделе 5.2 главы 5.)
WITH ( S RENAME S# AS SA ) { SA, CITY } AS Tl,
( S RENAME S# AS SB ) { SB, CITY } AS T2,
Tl JOIN T2 AS T3
T3 WHERE SA < SB AS T4 :
T4 { SA, SB }
Благодаря использованию предложения WITH громоздкие выражения можно записать
в пошаговой форме, не нарушая при этом принципов непроцедурное™ реляционной ал-
гебры. Мы продолжим обсуждение этого вопроса в следующем примере.
6.5.6. Получить имена поставщиков, которые
не поставляют деталь с номером ‘Р2’
( ( S { S# } MINUS ( SP WHERE P# = P# ( 'Р2' ) ) { S# } )
JOIN S ) { SNAME }
В результате получаем единственный атрибут SNAME.
210
Часть IL Реляционная модель
Разберем последний пример несколько подробнее, чтобы проиллюстрировать еще
один важный момент. Не всегда просто представить себе, как можно выразить опреде-
ленный запрос в виде одной вложенной формулы (особенно если запрос сложный). Од-
нако это и необязательно. Вот пошаговый вариант решения нашей проблемы.
WITH S { S# } AS Т1,
SP WHERE P# = P# ( 'P2' ) AS T2,
T2 { S# } AS T3,
T1 MINUS T3 AS T4,
T4 JOIN S AS T5,
T5 { SNAME } AS T6 :
T6
Отношение Тб содержит требуемый результат.
Пояснение. Предполагается, что имена, которые вводятся с помощью предложения
WITH, т.е. имена вида Ti, в этом примере локальны по отношению к содержащему их вы-
ражению. Затем, если система поддерживает возможность отсрочки вычислений (как,
например, это делает система PRTV [6.9]), разбиение запроса на последовательность не-
больших шагов предложенным способом абсолютно не будет связано с какими-либо не-
желательными издержками в плане производительности. В действительности весь запрос
можно будет выполнить следующим образом.
Выражения, предшествующие двоеточию, не требуют немедленного вычисления;
система просто должна помнить о них вместе со всеми именами, введенными с
помощью соответствующих операторов AS.
Выражение, следующее за двоеточием, обозначает окончательный результат за-
проса (в нашем примере это выражение представляет собой просто Тб). Дойдя до
этого места, система не может больше откладывать вычисления и должна каким-
то образом получить требуемое значение (т.е. значение Тб).
Для того чтобы вычислить значение Тб, которое является проекцией отношения Т5
по атрибуту SNAME, система должна сначала вычислить значение отношения Т5.
Но чтобы вычислить значение отношения Т5, которое является соединением от-
ношений Т4 и S, система должна предварительно вычислить значение отношения
Т4 и т.д. Иными словами, система должна эффективно вычислять исходные вло-
женные выражения точно так, как пользователь, в первую очередь, должен эффек-
тивно писать такие вложенные запросы.
В следующем разделе мы кратко познакомимся с общими принципами вычисле-
ния подобных вложенных выражений (к этой теме мы еще вернемся впоследствии, в
главе 17).
6.6. Зачем нужна реляционная алгебра
Подведем некоторый итог сказанному в этой главе. Здесь было введено понятие ре-
ляционной алгебры, т.е. набора операторов для обработки отношений. В этот набор вхо-
дят следующие операторы: операторы выборки, проекции, произведения, объединения,
пересечения, вычитания, соединения и деления плюс оператор переименования атрибу-
Глава 6. Реляционная алгебра
211
тов RENAME. (За исключением RENAME, эти операторы составляют набор, впервые опреде-
ленный Коддом в [6.1].) Для этих операций также был представлен конкретный синтак-
сис, который и использовался в нескольких приведенных выше примерах.
Как уже отмечалось, восемь операторов Кодда не представляют минимального набора
операторов (они задумывались не с этой целью), так как не все из них примитивны и
часть из них можно определить в терминах других операторов. В действительности три
операции из этого набора, а именно — соединение, пересечение и деление, можно опре-
делить через остальные пять (упр. 6.2). Пять данных операций (выборка, проекция, про-
изведение, объединение и вычитание)4 можно рассматривать как примитивные в том
смысле, что ни одна из них не выражается через другие. Поэтому минимальный набор
(безусловно, необязательно единственно возможный) будет состоять из этих пяти при-
митивных операций. Однако на практике остальные три операции (в особенности опера-
ция соединения) используются настолько часто, что имеет смысл обеспечить их непо-
средственную поддержку, несмотря на то что они не являются примитивными.
Теперь пришло время объяснить один важный момент. До сих пор предполагалось
(хотя явно и не указывалось), что главное назначение алгебры — только выборка дан-
ных. Однако это не так. Основная цель алгебры— обеспечить запись реляционных
выражений. Такие выражения, в свою очередь, хотя и предполагают различное приме-
нение, включая, конечно, и выборку информации, не ограничены лишь этой одной функ-
цией. Ниже перечислены некоторые из возможных применений подобных выражений.
Определение области выборки, т.е. тех данных, которые должны быть дос-
тавлены в результате выполнения операции выборки (что детально рассмат-
ривалось выше).
Определение области обновления, т.е. данных, которые должны быть вставлены,
изменены или удалены в результате выполнения операции обновления (глава 5).
Определение правил поддержки целостности данных, т.е. некоторых особых
требований, которым должна удовлетворять база данных (глава 8).
Определение производных переменных-отношений, т.е. тех данных, которые
должны быть включены в представления или “моментальные снимки” состояния
базы данных (глава 9).
Определение требований устойчивости, т.е. данных, которые должны быть
включены в контролируемую область для некоторых операций управления парал-
лельным доступом к информации (глава 15).
Определение ограничений защиты, т.е. данных, для которых осуществляется тот
или иной тип контроля доступа (глава 16).
В целом, выражения реляционной алгебры служат для символического высокоуровне-
вого представления намерений пользователя (например, в отношении некоторого опре-
деленного запроса). И именно потому, что подобные выражения являются символиче-
скими и высокоуровневыми, ими можно манипулировать в соответствии с различными
4 Поскольку произведение является специальным видом соединения, в этом перечне прими-
тивных операторов его можно заменить соединением. Более того, в перечень необходимо так-
же добавить оператор RENAME, поскольку наша алгебра (в отличие от алгебры, определенной в
[6.1 ]) опирается на имена атрибутов, а не на их порядковые номера.
212
Часть II. Реляционная модель
символическими высокоуровневыми правилами преобразования. Например, рассмот-
рим следующее выражение (“Получить имена поставщиков детали с номером 'Р2'”;
пример 6.5.1).
( ( SP JOIN S ) WHERE P# = P# ( 'P2' ) ) { SNAME }
Его можно преобразовать в логически эквивалентное, но, вероятно, более рациональ-
ное выражение следующего вида.
( ( SP WHERE P# = P# ( 'Р2' ) ) JOIN S ) { SNAME }
(Упражнение. В каком смысле последнее выражение можно считать более рацио-
нальным? Почему только “вероятно”?)
Таким образом, реляционная алгебра может служить хорошим основанием для вы-
полнения оптимизации (чтобы вспомнить, что такое оптимизация, обратитесь к разде-
лу 3.5 главы 3). Следовательно, если пользователь выразил свой запрос с помощью пер-
вого из двух приведенных выше выражений, то перед выполнением оптимизатор должен
преобразовать его во второе выражение (в идеальном случае производительность не
должна зависеть от формы, в которой пользователь выражает свой запрос). К этой теме
мы еще вернемся в главе 17.
В заключение отметим, что благодаря своей фундаментальной природе реляционная
алгебра часто используется в качестве критерия возможностей выражения пользова-
тельских намерений для некоторого определенного реляционного языка (например, та-
кого, как язык SQL). В общем случае язык называют реляционно полным [6.1], если
его возможности, по крайней мере, соответствуют возможностям, обеспечиваемым ал-
гебраическими операциями; иначе говоря, если выражения этого языка позволяют опре-
делить каждое отношение, которое может быть определено с помощью алгебраических
выражений (первоначальной алгебры, т.е. выражений, описанных в предыдущих разде-
лах). Понятие реляционной полноты подробнее обсуждается в следующей главе.
6.7. Дополнительные операторы
Многие авторы предлагали новые алгебраические операторы после определения Код-
дом первоначальных восьми. В этом разделе детально рассматривается несколько таких
операторов — SEMIJOIN (полусоединение), SEMIMINUS (полувычитание), EXTEND
(расширение), SUMMARIZE (обобщение) и TCLOSE (транзитивное замыкание). В терминах
языка Tutorial D синтаксис этих операторов выглядит следующим образом.
<полусоединение>
::= реляционное выражение>
SEMIJOIN реляционное выражение>
<полувычитание>
::= реляционное выражение>
SEMIMINUS реляционное выражениё>
расширение>
::= EXTEND реляционное выражение>
ADD <список добавляемых расширений»
Глава 6. Реляционная алгебра
213
добавляемое расширение>
::= <выражение> AS <имя атрибута>
<обобщение>
::= SUMMARIZE реляционное выражение>
PER реляционное выражение>
ADD <список добавляемых обобщений^
<добавляемое обобщение>
::= <тип обобщения> [ ( <скалярное выражение> ) ]
AS <имя атрибута>
<тип обобщения>
::= COUNT | SUM | AVG | MAX | MIN | ALL | ANY
| COUNTD | SUMD | AVGD
<транзитивное замыкание>
:: = TCLOSE реляционное выражение>
Значения различных параметров реляционное выражение^ упомянутые в этом син-
таксисе BNF, не должны иметь тип <не проекция*.
Полусоединение
Пусть обозначения А, В, X, Y и Z будут иметь тот же смысл, который был им присвоен
при определении оператора JOIN в разделе 6.4. Тогда полусоединением отношения А с
отношением В (что записывается как A SEMI JOIN В, причем именно в таком порядке) по
определению называется операция, эквивалентная следующей.
( A JOIN В ) { X, Y }
Другими словами, полусоединением отношения А с отношением В называется резуль-
тат соединения отношений А и В, для которого дополнительно выполнена операция про-
екции по атрибутам отношения А. Тело полученного в результате выполнения этой опе-
рации отношения, неформально говоря, состоит из тех кортежей отношения А, которые
имеют соответствие в отношении В.
Пример. Получить значения атрибутов S#, SNAME, STATUS и CITY для всех поставщи-
ков детали с номером ' Р2'.
S SEMIJOIN ( SP WHERE P# = P# ( 'P2' ) )
Полувычитание
Снова пусть обозначения А, В, X, Y и Z имеют тот же смысл, что и при определении
оператора JOIN в разделе 6.4. Тогда полувычитанием отношений А и В (что записывает-
ся как A SEMIMINUS В, причем именно в таком порядке) называется операция, эквива-
лентная следующему оператору.
A MINUS ( A SEMIJOIN В )
214
Часть II. Реляционная модель
Неформально говоря, тело полученного в результате выполнения этой операции отноше-
ния состоит из тех кортежей отношения А, которые не нашли соответствия в отношении В.
Пример. Получить значения атрибутов S#, SNAME, STATUS и CITY для всех поставщи-
ков, не поставляющих деталь с номером 'Р2'.
S SEMIMINUS ( SP WHERE P# = P# ( 'P2' ) )
Операция расширения
Читатель, возможно, заметил, что в описанной нами алгебре нет средств для скаляр-
ных вычислений. Конечно, на практике такие возможности просто необходимы. Напри-
мер, может понадобиться запросить из базы данных результат вычисления некоторого
арифметического выражения, подобного выражению WEIGHT*454, или сослаться на такое
значение в выражении WHERE при выборке. (Вспомним, что в нашем примере вес деталей
приведен в фунтах; тогда выражение WEIGHT*454 переводит этот вес в граммы5.) Для
обеспечения таких возможностей и предназначена операция расширения. Точнее, с ее
помощью из определенного отношения (по крайней мере, концептуально) создается но-
вое отношение. Оно похоже на начальное, но содержит дополнительный атрибут, значе-
ния которого получены посредством некоторых скалярных вычислений. Например,
можно написать следующее.
EXTEND Р ADD ( WEIGHT * 454 ) AS GMWT
С помощью этого выражения (заметьте, именно выражения, а не команды или опера-
тора, что разрешает вложение подобных выражений в другие выражения) создается но-
вое отношение с таким же заголовком, как и у отношения Р, за исключением дополни-
тельного атрибута GMWT. Каждый кортеж этого отношения совпадает с соответствующим
кортежем отношения Р, но содержит еще одно дополнительное значение атрибута GMWT,
вычисляемое в соответствии с указанным выражением, как показано на рис. 6.9.
P# PNAME COLOR WEIGHT CITY GMWT
Р1 Nut Red 12,0 London 5448,0
Р2 Bolt Green 17,0 Paris 7718,0
РЗ Screw Blue 17,0 Rome 7718,0
Р4 Screw Red 14,0 London 6356,0
Р5 Cam Blue 12,0 Paris 5448,0
Р6 Cog Red 19,0 London 8626,0
Рис. 6.9. Пример выполнения операции расширения
Обратите внимание, что это выражение EXTEND не изменяет содержимое базовой пере-
менной-отношения деталей в базе данных. Это всего лишь выражение, такое же, как, на-
пример, S JOIN SP, и значит, оно создает определенный результат. В нашем случае этот ре-
зультат подобен текущему значению базовой переменной-отношения деталей. (Иначе го-
воря, операция расширения — это не реляционный аналог SQL-оператора ALTER TABLE.)
5 В это.м примере предполагается корректность операции умножения “ ★” веса детали на це-
лое число. А каков тип результата этой операции?
Глава 6. Реляционная алгебра
215
Теперь можно использовать вновь созданный атрибут GMWT в любых операциях про-
екции, выборки и т.д., как, например, показано ниже.
( ( EXTEND Р ADD ( WEIGHT * 454 ) AS GMWT )
WHERE GMWT > WEIGHT ( 10000.0 ) ) { ALL BUT GMWT }
Замечание. Конечно, более дружественный пользователю язык должен позволять
вставлять подобные выражения непосредственно в предложение WHERE, например, сле-
дующим образом.
Р WHERE ( WEIGHT * 454 ) > WEIGHT ( 10000.0 )
Однако такая возможность — это всего лишь синтаксическое усовершенствование.
Обратимся к обобщенному представлению данного выражения.
EXTEND A ADD exp AS Z
В общем случае результатом вычисления подобного выражения будет отношение с
заголовком, эквивалентным заголовку исходного отношения А, но с расширенным новым
атрибутом Z. Тело результирующего отношения будет состоять из всех кортежей t, где t
является кортежем отношения А, дополненного значением нового атрибута Z, который
определяется посредством вычисления скалярного выражения ехр для данного кортежа
отношения А. При этом отношение А не должно иметь атрибута Z и выражение ехр не
должно ссылаться на атрибут Z. Заметьте, что кардинальность результата равна карди-
нальности отношения А, а степень результата равна степени отношения А плюс единица.
Типом переменной Z в этом случае будет тип выражения ехр.
Приведем еще несколько примеров.
1. EXTEND S ADD 'Supplier' AS TAG
Это выражение эффективно дополняет каждый кортеж отношения S символьным
значением 'Supplier' (очевидно, что скалярный литерал (символьное значение)
является простейшим случаем скалярного выражения).
2. EXTEND ( Р JOIN SP ) ADD ( WEIGHT * QTY ) AS SHIPWT
Этот пример иллюстрирует применение оператора EXTEND к результату реляцион-
ного выражения, более сложного, чем просто имя переменной-отношения.
3. ( EXTEND S ADD CITY AS SCITY ) { ALL BUT CITY }
Имя атрибута, такое как CITY, — также допустимое скалярное выражение. Заметь-
те, что этот пример равносилен следующему выражению.
S RENAME CITY AS SCITY
Иными словами, оператор RENAME не примитивен! Он может быть определен через
оператор EXTEND (и проекцию). Разумеется, мы не собираемся отвергать уже зна-
комый оператор RENAME, поскольку он действительно полезен. Однако тот факт, что
оператор RENAME — в действительности просто сокращение, является, по крайней
мере, интересным.
4. EXTEND Р ADD WEIGHT * 454 AS GMWT, WEIGHT * 16 AS OZWT
Этот пример служит иллюстрацией “множественного” расширения.
216
Часть II. Реляционная модель
5. EXTEND S
ADD COUNT ( ( SP RENAME S# AS X ) WHERE X = S# )
AS NP
Результат вычисления этого выражения показан на рис. 6.10.
S# SNAME STATUS CITY NP
S1 Smith 20 London 6
S2 Jones 10 Paris 2
S3 Black 30 Paris 1
S4 Clark 20 London 3
S5 Adams 30 Athens 0
Рис. 6.10. Еще один пример операции расширения
Пояснения
Для данного поставщика в текущем значении переменной-отношения S вы-
ражение
( ( SP RENAME S# AS X ) WHERE X = S# )
позволяет возвратить множество кортежей поставок, соответствующих кор-
тежу поставщика в текущем значении переменной-отношения SP.
Затем для этого множества поставок применяется обобщающая функция
COUNT, возвращающая соответствующее значение кардинальности (которое
является, конечно же, скалярным значением).
Атрибут NP в результирующем отношении представляет количество деталей, кото-
рые поставляются поставщиком, определяемым соответствующим значением атри-
бута S#. В частности, обратите внимание на значение атрибута NP для поставщика с
номером 'S5' — множество кортежей отношения SP для этого поставщика пусто,
поэтому функция COUNT возвращает значение “нуль”.
Рассмотрим вкратце обобщающие функции. Общее назначение этих функций со-
стоит в том, чтобы на основе значений некоторого атрибута определенного отно-
шения получить скалярное значение. Типичными примерами являются функции
COUNT, SUM, MAX, MIN, ALL и ANY. В языке Tutorial D параметр <вызов обобщающей
функции> является особым случаем параметра <скалярное выражение> и в общем
случае имеет следующий вид.
<имя функции> ( реляционное выражение> [, <имя атрибута> ] )
Если параметр <имя функции> имеет значение COUNT, то параметр <имя
атрибута> недопустим и должен быть опущен. В остальных случаях параметр
<имя атрибута> может быть опущен тогда и только тогда, когда параметр
реляционное выражение> задает отношение со степенью, равной единице. Тогда
единственный атрибут результирующего отношения, получаемого после вычис-
ления выражения реляционное выражение^ будет использоваться по умолча-
нию. Вот несколько примеров.
Глава 6. Реляционная алгебра
217
SUM ( SP WHERE S# = S# ( 'SI' ), QTY)
SUM ( ( SP WHERE S# = S#( 'SI' ) ) { QTY } )
Обратите внимание на различие между этими двумя выражениями. Первое выра-
жение позволяет подсчитать суммарный объем всех поставок для поставщика с
номером ' S1', а второе — суммарный объем всех поставок различных комплектов
деталей для поставщика с номером ' S1'.
Если аргумент обобщающей функции оказывается пустым множеством, то функ-
ции COUNT и SUM возвращают значение “нуль”, а функции MIN и МАХ — наименьшее
и наибольшее значения соответствующего домена. Функции ALL и ANY в этом слу-
чае возвращают соответственно значения истина и ложь, а функция AVG генериру-
ет исключительную ситуацию.
Операция обобщения
Начиная этот раздел, следует сказать, что данная версия оператора SUMMARIZE отлича-
ется от версий, рассмотренных в предыдущих изданиях настоящей книги. Фактически
это улучшенная версия, в которой учтены определенные трудности, возникавшие в пре-
дыдущих версиях при работе с пустыми отношениями.
Как мы уже убедились, в реляционной алгебре операция расширения позволяет вы-
полнять “горизонтальные” вычисления в отношении отдельных строк. Оператор обоб-
щения выполняет аналогичную функцию для “вертикальных” вычислений в отношении
отдельного столбца. Например, рассмотрим следующее выражение.
SUMMARIZE SP PER SP { P# } ADD SUM ( QTY ) AS TOTQTY
В результате его вычисления создается отношение с заголовком {P#,TOTQTY}, содер-
жащее один кортеж для каждого значения атрибута P# в проекции SP{P#}. Каждый из
этих кортежей содержит значение атрибута P# и соответствующее общее количество де-
талей (рис. 6.11). Другими словами, концептуально исходное отношение Р
“перегруппировано” в множество групп кортежей (по одной группе для каждого уни-
кального значения атрибута Р#), после чего для каждой полученной группы сгенерирован
один кортеж, помещаемый в окончательный результат.
P# TOTQTY
Р1 Р2 РЗ Р4 Р5 Р6 600 1000 400 500 500 100
Рис. 6.11. Пример выполнения операции SUMMARIZE
В общем случае значение выражения
SUMMARIZE A PER В ADD <обобщение> AS Z
определяется следующим образом.
218
Часть II. Реляционная модель
Отношение В должно иметь такой же тип, как и некоторая проекция отношения А,
т.е. каждый атрибут отношения В должен одновременно присутствовать в отно-
шении А. Примем, что атрибутами этой проекции (или, что эквивалентно, атрибу-
тами отношения В) являются атрибуты А1, А2, ... , Ап.
Результатом вычисления данного выражения будет отношение с заголовком {А1,
А2, ... , An, Z}, где Z является новым добавленным атрибутом.
Тело результата содержит все кортежи t, где t является кортежем отношения В,
расширенным значением нового атрибута Z. Это значение нового атрибута Z под-
считывается посредством вычисления обобщающего выражения по всем корте-
жам отношения А, которое имеет те же значения для атрибутов Al, А2, ... , Ап,
что и кортеж t. (Разумеется, если в отношении А нет кортежей, принимающих те
же значения для атрибутов Al, А2, ... , Ап, что и кортеж t, то обобщающее вы-
ражение будет вычислено для пустого множества.) Отношение В не должно со-
держать атрибут с именем Z, а обобщающее выражение не должно ссылаться на
атрибут Z. Заметьте, что кардинальность результата равна кардинальности отно-
шения В, а степень результата равна степени отношения В плюс единица. Типом
переменной Z р этом случае будет тип обобщающего выражения.
Вот еще один пример.
SUMMARIZE ( Р JOIN SP ) PER Р { CITY } ADD COUNT AS NSP
Результат его вычисления будет выглядеть так.
CITY NSP
London 5
Paris 6
Rome 1
Другими словами, результат содержит по одному кортежу для каждого из трех упо-
минаемых в отношении Р городов (Лондона, Парижа и Рима), причем в каждом кортеже
показано количество поставок деталей из соответствующего города. '
Сделаем некоторые выводы.
1. Предложенный синтаксис позволяет выполнять множественные операции обоб-
щения, как, например, показано ниже.
SUMMARIZE SP BY { P# } ADD SUM ( QTY ) AS TOTQTY,
AVG ( QTY ) AS AVGQTY
2. Общая форма параметра <обобщение> (повторимся) имеет следующий вид.
SUMMARIZE реляционное выражение>
PER реляционное выражение>
ADD <список добавляемых обобщений*
Каждый элемент робавляемое обобщение^ в свою очередь, имеет следующий
вид.
<тип обобщения* [ ( <скалярное выражение> ) ] AS <имя атрибута>
Глава 6. Реляционная алгебра
219
Чаще всего параметр <тип обобщения» задает одну из функций COUNT, SUM, AVG,
MIN, MAX, ALL, ANY, COUNTD, SUMD и AVGD. Буква “D” (distinct — различный) в названии
функций COUNTD, SUMD и AVGD означает следующее: “перед выполнением этой
обобщающей операции удалить все избыточные повторяющиеся значения”. Пара-
метр Дкалярное выражение» может содержать ссылки на атрибуты отношения, ко-
торое определяется параметром реляционное выражение», размещенным непо-
средственно за ключевым словом SUMMARISE.
Замечание. Параметр Дкалярное выражение» (вместе с квадратными скобками)
можно опустить лишь в том случае, если параметр <тип обобщения» имеет значе-
ние COUNT.
Обратите также внимание на то, что параметр Добавляемое обобщение» — это не
вызов обобщающей функции, задаваемый параметром <вызов обобщающей
функции». Параметр <вызов обобщающей функция» задает скалярное выражение и
может использоваться в любом месте, где допустим вызов оператора выборки (в
частности, скалярного литерала). Параметр Добавляемое обобщение> — это не
скалярное значение; он является операндом оператора SUMMARIZE и имеет смысл
только в контексте операции обобщения.
3. Как вы, наверное, догадались, оператор SUMMARIZE не примитивен— его можно
моделировать с помощью оператора EXTEND. Например, рассмотрим следующее
выражение.
SUMMARIZE SP PER S { S# } ADD COUNT AS NP
По сути, это сокращенная запись представленного ниже более сложного выраже-
ния.
{ EXTEND S { S# }
ADD ( ( SP RENAME S# AS X ) WHERE X = S# ) AS Y,
COUNT ( Y ) AS NP )
{ S#, NP }
Возможен еще один эквивалентный вариант записи.
WITH ( S { S# } ) AS Tl,
( SP RENAME S# AS X ) AS T2,
( EXTEND Tl ADD ( T2 WHERE X = S# ) AS Y ) AS T3,
( EXTEND T3 ADD COUNT ( Y ) AS NP ) AS T4:
T4 { S#, NP }
4. Рассмотрим следующий пример.
SUMMARIZE SP PER SP { } ADD SUM ( QTY ) AS GRANDTOTAL
В нем группирование и подведение итогов производятся для отношения, которое
вообще не имеет атрибутов. Пусть sp — это текущее значение базовой перемен-
ной-отношения SP. Предположим, что отношение sp содержит по крайней мере
один кортеж. Тогда все кортежи отношения sp будут иметь “одинаковые значения”
по пустому множеству атрибутов, а именно— по “0-кортежу” [5.5]. Таким обра-
зом, в этом контексте они образуют единственную группу, для которой в конечном
результате будет построен всего один кортеж. Другими словами, обобщающая
220
Часть II. Реляционная модель
функция вычисляется только один раз и для всего отношения sp в целом. Следова-
тельно, вычисление представленного выше выражения SUMMARIZE даст в результате
отношение с одним атрибутом (с именем GRANDTOTAL) и одним кортежем, причем
единственное скалярное значение в единственном результирующем кортеже явля-
ется общим итогом по всем значениям атрибута QTY в исходном отношении sp.
Если, с другой стороны, исходное отношение sp совсем не имеет кортежей, то нет
и групп, а следовательно, нет и результирующих кортежей, т.е. результирующее
отношение также будет пустым. Однако приведенное ниже выражение, напротив,
“будет работать” (т.е. будет возвращать корректное значение, а именно — нуль),
даже если отношение sp пустое 6.
SUMMARIZE SP PER RELATION { TUPLE { } }
ADD SUM ( QTY ) AS GRANDTOTAL
Точнее, это выражение будет возвращать отношение с одним лишь атрибутом
GRANDTOTAL и одним кортежем, в котором значение GRANDTOTAL будет равно нулю.
Поэтому автор предлагает разрешить опускать предложение PER в выражении
SUMMARIZE, как это сделано в следующем примере.
SUMMARIZE SP ADD SUM ( QTY ) AS GRANDTOTAL
Подразумевается, что пропуск предложения PER эквивалентен определению этого
предложения в следующей форме.
PER RELATION { TUPLE { } }
Транзитивное замыкание
Операция транзитивного замыкания упоминается здесь, в основном, для полноты из-
ложения. Ее детальное обсуждение выходит за рамки данной главы. Тем не менее мы да-
дим здесь определение этой операции. Пусть А — произвольное бинарное отношение с ат-
рибутами X и Y, принадлежащими одному типу Т. Тогда транзитивным замыканием от-
ношения А (что записывается как TCLOSE А) называется отношение А+, заголовок которого
такой же, как заголовок отношения А, а тело является супермножествам отношения А.
Супермножество отношения А определяется следующим образом. Кортеж { Х:х,
Y:y } принадлежит отношению А+ тогда и только тогда, когда он принадлежит отноше-
нию А или когда существует последовательность значений zl, z2, ... , zn
(принадлежащих типу Т), такая, что все кортежи { Х:х, Y:zl }, { X:zl, Y:z2 }, ... ,
{ X:zn, Y:y } принадлежат отношению А. Иначе говоря, кортеж (х,у) принадлежит от-
ношению А+ только тогда, когда (нестрого говоря) в представляющем отношение А графе
есть линия, соединяющая точку х с точкой у. Обратите внимание на то, что тело отноше-
ния А всегда содержится в теле отношения А+ как подмножество.
Обсуждение этого вопроса будет продолжено в главе 23.
Выражение RELATION { TUPLE { } } в предложении PER этого примера обозначает от-
ношение (в действительности единственное в своем роде отношение), которое не имеет атри-
бутов, но имеет один кортеж (а именно — 0-кортеж). Это выражение можно сокращенно на-
зывать TABLE_DEE [3.3], [5.5], [6.2].
Глава 6. Реляционная алгебра
221
6.8. Группирование и разгруппирование
Поскольку значениями атрибутов отношений могут быть другие отношения, было бы
желательным наличие дополнительных реляционных операторов, называемых операто-
рами группирования и разгруппирования [3.3]. Рассмотрим сначала пример операции
группирования.
SP GROUP ( Р#, QTY ) AS PQ
Результат выполнения этого выражения будет выглядеть так, как показано на
рис. 6.12.
Замечание. Этот рисунок наверняка будет очень полезен при разборе последующих
пояснений, поскольку они, к сожалению (но неизбежно), несколько абстрактны.
S# PQ
S1 р# QTY
pi 100
Р2 200
РЗ 400
Р4 200
Р5 100
Р6 100
S2 P# QTY
Р1 300
Р2 400
S3 P# QTY
Р2 200
S4 P# QTY
Р2 200
Р4 300
Р5 400
Рис. 6.12. Группирование отношения SP по атрибуту S#
Начнем с того, что исходное выражение
SP GROUP ( Р#, QTY ) AS PQ
можно прочесть как “сгруппировать отношение SP по атрибуту S#”, поскольку атри-
бут S# является единственным атрибутом отношения SP, не упомянутым в предложении
GROUP. В результате получится отношение, заголовок которого выглядит так.
{ S# S#, PQ RELATION { P# Р#, QTY QTY } }
222
Часть II. Реляционная модель
Другими словами, он состоит из атрибута PQ, принимающего в качестве значений от-
ношения (PQ, в свою очередь, имеет атрибуты P# и QTY), а также из всех остальных атри-
бутов отношения SP (в нашем случае “все остальные атрибуты” — это атрибут S#). Тело
этого отношения содержит ровно по одному кортежу для всех различных значений атри-
бута S# исходного отношения SP (и никаких других кортежей). Каждый кортеж в теле
содержит соответствующее значение атрибута S# (обозначим его через s), а также значе-
ние атрибута PQ (обозначим его через pq), полученное следующим образом.
Каждый кортеж отношения SP концептуально заменяется кортежем (обозначим
его через х), в котором компоненты P# и QTY как бы “упакованы” в один компо-
нент, принимающий в качестве значений кортежи (обозначим его через у).
Компоненты у всех кортежей х, значение S# которых равно s, “группируются” в
отношение pq, и таким образом получается результирующий кортеж, в котором
значение S# равно s, а значение PQ равно pq.
Окончательный результат будет выглядеть так, как показано на рис. 6.12. |
Перейдем теперь к операции разгруппирования. Пусть SPQ— это отношение, пока-
занное на рис. 6.12. Тогда выражение
SPQ UNGROUP PQ
возвращает нас к отношению SP (как и следовало ожидать). Точнее, оно выдает в ка-
честве результата отношение, заголовок которого выглядит так.
{ S# S#, P# Р#, QTY QTY }
Иными словами, его заголовок состоит из атрибутов P# и QTY (полученных из атрибу-
та PQ), а также из всех остальных атрибутов отношения SPQ (в нашем случае это только
атрибут S#). Тело полученного отношения содержит ровно по одному кортежу для каж-
дой комбинации кортежа отношения SPQ с кортежем значения PQ, являющегося элемен-
том кортежа SPQ (других кортежей в нем нет). Каждый такой кортеж содержит соответ-
ствующее значение атрибута S# (обозначим его через s), а также значения атрибутов P# и
QTY (обозначим их через р и q), которые получены следующим образом.
Каждый кортеж отношения SPQ мысленно заменяется множеством кортежей, ко-
торое содержит по одному кортежу (обозначим его через х) для каждого кортежа
из значения PQ. Каждый кортеж х содержит компонент S# (обозначим его через s),
равный компоненту S# рассматриваемого кортежа SPQ, а также компонент
(обозначим его через у), равный некоторому кортежу из компонента PQ рассмат-
риваемого кортежа SPQ.
Компоненты у каждого такого кортежа х, значение S# которых равно s,
“разворачиваются” в отдельные компоненты P# и QTY (обозначим их через р и q).
В результате получается кортеж, значение компонента S# которого равно s, значе-
ние компонента P# равно р и значение компонента QTY равно q.
Таким образом, в результате разгруппирования получилось отношение SP. |
Глава 6. Реляционная алгебра
223
Операторы GROUP и UNGROUP иначе называют средствами “вложения” и “извлечения”
отношений. Однако мы предпочитаем использовать термины “группирование” и
“разгруппирование”, поскольку термины “вложение” и “извлечение” тесно связаны с
№2-отношениями — концепцией, которую мы считаем противоречивой и которая здесь
не рассматривается.
Для полноты в завершение этого раздела сделаем несколько замечаний относительно
обратимости операций группирования и разгруппирования (эти замечания, возможно,
будут не совсем понятными при первом чтении). Итак, если определенным образом
сгруппировать некоторое отношение г, то всегда будет существовать обратная операция
разгруппирования, позволяющая вернуться к отношению г. Однако если сначала раз-
группировать некоторое отношение г, то обратная операция группирования, возвра-
щающая нас к отношению г, будет существовать не всегда. Приведем один пример (он
основан на примере из статьи [5.4]). Предположим, что сначала выполняется разгруппи-
рование отношения TWO (рис. 6.13) с получением в качестве результата отношения THREE.
Теперь, если сгруппировать отношение THREE по атрибуту А, в результате получится не
отношение TWO, а отношение ONE.
Рис. 6.13. Операции разгруппирования и группирования необязательно являются обра-
тимыми
Обратите внимание на то, что в отношении ONE атрибут RVX (обязательно) функцио-
нально зависит от А, задавая тем самым потенциальный ключ (подробности приводятся в
главах 8 и 9). Если теперь разгруппировать отношение ONE, можно снова вернуться к от-
ношению THREE, а отношение THREE, очевидно, может быть сгруппировано так, чтобы в
результате получилось отношение ONE. Таким образом, для этой пары отношений опера-
ции группирования и разгруппирования действительно являются обратными. В общем
случае решающим моментом в вопросе обратимости операции разгруппирования являет-
ся функциональная зависимость. В действительности для отношения г с атрибутом RVX,
принимающим в качестве значений отношения, операция разгруппирования
(относительно атрибута RVX) обратима тогда и только тогда, когда выполнены два сле-
дующих условия.
Ни один кортеж отношения г не принимает в качестве значения атрибута RVX пус-
тое отношение.
224
Часть II. Реляционная модель
Атрибут RVX функционально зависит от комбинации всех остальных атрибутов от-
ношения г. Иначе говоря, у отношения г должен быть потенциальный ключ, не
содержащий атрибут RVX как компонентов.
6.9. Реляционные сравнения
Реляционная алгебра в том виде, в котором она была изначально определена, не под-
держивает прямого сравнения двух отношений (например, проверки их равенства или
того, является ли одно из них подмножеством другого). Одно из следствий данного упу-
щения состоит в том, что некоторые запросы выражаются весьма неуклюже (примером
может служить упр. 6.48). Однако это упущение легко исправить. Сначала определим
новый вид условия — реляционное сравнение — со следующим синтаксисом.
реляционное выражение> 0 реляционное выражение>
Здесь параметр реляционное выражение> — это в обоих случаях выражения реляци-
онной алгебры, представляющие совместимые по типу отношения, а символ 0— это
один из следующих операторов сравнения.
= Равно
Ф Не равно
< Подмножество
< Собственное подмножество
> Супермножество
> Собственное супермножество
Замечание. Возможно, выбор обозначений операторов не совсем удачен, так как от-
рицание утверждения “А— собственное подмножество В” не является утверждением
“А — супермножество В” (т.е. условия “<” и “>” не противоположны). Однако по техни-
ческим причинам в этой книге используются именно такие обозначения.
Приведем примеры.
1. S { CITY } = Р { CITY }
Смысл выражения. Совпадает ли проекция отношения поставщиков S по атрибуту
CITY с проекцией отношения деталей Р по атрибуту CITY?
2. S { S# } > SP { S# }
Смысл выражения (несколько перефразировано). Есть ли поставщики, вообще не
поставляющие деталей?
Теперь можно разрешить использование этих новых видов условий в реляционных
выражениях, как, например, показано ниже.
S WHERE ( ( SP RENAME S# AS X ) WHERE X = S# ) { P# } = P { P# }
При вычислении этого выражения получаем отношение, содержащее кортежи для по-
ставщиков всех типов деталей.
Глава 6. Реляционная алгебра
225
Пояснение
Для заданного поставщика выражение
( ( SP RENAME S# AS X ) WHERE X = S# ) { P# }
дает множество номеров деталей, поставляемых этим поставщиком.
Затем это множество номеров деталей сравнивается с множеством всех номеров
деталей. Если эти два множества совпадают, то соответствующий кортеж постав-
щика заносится в результат.
Этот запрос можно также сформулировать по-другому.
S JOIN ( S { S# } DIVIDEBY Р { P# } PER SP { S#, P# } )
Однако вариант с реляционным сравнением кажется более простым для восприятия.
Тем не менее следует прояснить один важный вопрос: реляционные сравнения не явля-
ются условиями выборки (этот термин был определен в разделе 6.4.), а приведенный вы-
ше пример, включающий подобное сравнение, вообще не является настоящей операцией
выборки! Это, скорее, сокращение для выражения, подобного следующему.
WITH ( EXTEND S
ADD ( ( SP RENAME S# AS X ) WHERE X = S# ) { P# }
AS A ) AS Tl,
( EXTEND Tl
ADD P { P# }
AS В ) AS T2 :
T2 WHERE A = В
Здесь А и В — атрибуты, принимающие в качестве значений отношения, а последнее
выражение Т2 WHERE А=В теперь является типичным условием выборки.
Замечание. Из всего сказанного следует, что для поддержки реляционных сравнений
требуется по меньшей мере поддержка атрибутов, принимающих в качестве значений
отношения.
На практике часто требуется определить, является ли данное отношение пустым (т.е.
не содержащим ни одного кортежа). Поэтому имеет смысл ввести соответствующее со-
кращение. Определим соответствующий оператор, возвращающий логическое значение.
IS_EMPTY ( реляционное выражение> )
Этот оператор возвращает значение истина, если вычисленное значение параметра
реляционное выражение> оказывается пустым, и значение ложь в противном случае.
Не менее часто требуется проверить, присутствует ли данный кортеж t в данном от-
ношении г. Для этой цели подойдет следующее реляционное сравнение.
RELATION { t } < г
Однако, с точки зрения пользователя, удобнее применять следующее сокращение
(знакомое читателям, знающим язык SQL), которое, безусловно, покажется ему более
дружественным.
t IN г
Здесь ключевое слово IN заменяет оператор принадлежности множеству, обычно
обозначаемый символом е.
226
Часть II. Реляционная модель
6.10. Резюме
Данная глава посвящена реляционной алгебре. В ее начале обсуждается важность
реляционной замкнутости и допущения вложенности реляционных выражений; за-
тем выясняется, что при серьезном подходе к понятию замкнутости необходимо иметь
правила наследования типа отношения (разумеется, наша версия алгебры включает в
себя эти правила).
Начальный вариант реляционной алгебры определяет восемь операторов: традицион-
ный набор операторов обработки множеств (объединение, пересечение, вычитание и
произведение, причем каждая из этих операций была некоторым образом модифициро-
вана, поскольку реляционные операторы применимы не к произвольным множествам, а к
отношениям специального вида) и набор специальных реляционных операторов
(выборки, проекции, соединения и деления). К этому изначальному набору операто-
ров мы добавили операторы RENAME (переименование), SEMIJOIN (полусоединение),
SEMIMINUS (полувычитание), EXTEND (расширение) и SUMMARIZE (обобщение). Также бы-
ли рассмотрены оператор TCLOSE (транзитивное замыкание) и вкратце — операторы
GROUP (группирование) и UNGR0UP (разгруппирование). Некоторые из них требуют, что-
бы два отношения были совместимы по типу (ранее такие отношения назывались
“совместимыми для объединения”). Здесь же подчеркивалось, что не все упомянутые
выше операторы примитивны (одни из них можно определить посредством других).
Далее было показано, как эти операторы можно комбинировать в выражения, исполь-
зуемые для различных целей: выполнения выборки, обновления и других операций.
Также кратко обсуждалась идея преобразования записываемых выражений для их оп-
тимизации (подробнее эта идея будет обсуждаться в главе 17). Дополнительно рассмат-
ривалась возможность пошагового подхода при построении сложных запросов с ис-
пользованием предложения WITH, позволяющего ввести новые имена для отдельных вы-
ражений. И наконец, обсуждалась идея реляционных сравнений, которые часто упро-
щают формулирование запросов (например, таких, которые в противном случае требовали
бы использования оператора DIVIDEBY).
Упражнения
6.1. Выше упоминалось, что операции объединения, пересечения, произведения и есте-
ственного соединения обладают свойством коммутативности и ассоциативности.
Проверьте справедливость этих утверждений.
6.2. В предложенном Коддом первоначальном наборе из восьми операций пять
(объединение, вычитание, произведение, выборка и проекция) можно рассматривать
как примитивные. Дайте определение операций естественного соединения, пересече-
ния и (что значительно сложнее) деления в терминах этих примитивных операций.
6.3. Рассмотрим выражение A JOIN В. Если заголовки отношений А и В не пересекают-
ся (т.е. в заголовках нет общих атрибутов), то это выражение эквивалентно выра-
жению A TIMES В. А какому выражению оно будет эквивалентно, если заголовки
отношений будут одинаковы?
6.4. Покажите, что пять примитивных операторов, упомянутых в упр. 6.2, действитель-
но примитивны, т.е. что никакой из них нельзя выразить через четыре остальных.
Глава 6. Реляционная алгебра
227
6.5. В обычной арифметике умножение и деление — взаимообратные операции. Явля-
ются ли взаимообратными операции TIMES и DIVIDEBY в реляционной алгебре?
6.6. Пусть дана обычная база данных поставщиков и деталей. Чему в этом случае будет
равно выражение S JOIN SP JOIN Р? {Предостережение. Здесь есть ловушка!)
6.7. Пусть А — отношение степени п. Сколько существует различных проекций отно-
шения А?
6.8. В обычной арифметике существует специальное число 1, обладающее для любого
числа п следующим свойством.
П*1 = 1*П = П
Мы говорим, что число 1 является тождественным элементом по отношению к
операции умножения. Существует ли отношение, обладающее аналогичными еди-
нице свойствами, но в реляционной алгебре? Если существует, то какое?
6.9. В обычной арифметике существует специальное число 0, обладающее для любого
числа п следующим свойством.
п * 0 = 0 * п = О
Существует ли отношение, обладающее аналогичными нулю свойствами, но в ре-
ляционной алгебре? Если существует, то какое?
6.10. Выясните, как ведут себя описанные в этой главе алгебраические операции в слу-
чае их применения к отношениям, представляющим собой ответы к двум преды-
дущим упражнениям.
6.11. В разделе 6.2 говорилось, что реляционное свойство замкнутости так же важно,
как и арифметическое свойство замкнутости. Однако в арифметике существует од-
на неприятная ситуация, в которой свойство замкнутости нарушается, а именно —
деление на нуль. Существует ли аналогичная ситуация в реляционной алгебре?
6.12. Операции объединения, пересечения, произведения и соединения были определены
как бинарные операции (т.е. действующие на двух операндах). Тем не менее в этой
главе мы показали, как их можно расширить до n-арных для любого п>1. Таким обра-
зом, выражение A UNION В UNION С можно однозначно назвать тройным объедине-
нием отношений А, В и С. А что можно сказать в случае, когда п=1 или п=0 ?
Упражнения по составлению запросов
В основу всех остальных упражнений положена база данных поставщиков, деталей и
проектов (см. рис. 4.5 в главе 4 и ответ к упр. 5.4 в главе 5). В каждом упражнении
вам предлагается по словесному описанию запроса составить соответствующее ал-
гебраическое выражение. (В качестве интересной вариации можно предложить пред-
варительно обратиться к ответам к некоторым упражнениям и попытаться составить
по ним словесное описание задания соответствующих упражнений.) Для удобства
ниже повторно приводится (в общих чертах) структура используемой базы данных.
S { S#, SNAME, STATUS, CITY }
PRIMARY KEY { S# }
P { P#, PNAME, COLOR, WEIGHT, CITY }
PRIMARY KEY { P# }
228
Часть IL Реляционная модель
J {J#, JNAME, CITY }
PRIMARY KEY { J# }
SPJ { S#, P#, J#, QTY }
PRIMARY KEY { S#, P#, J# }
FOREIGN KEY { S# } REFERENCES S
FOREIGN KEY { P# } REFERENCES P
FOREIGN KEY { J# } REFERENCES J
6.13. Выбрать полную информацию обо всех проектах.
6.14. Выбрать полную информацию обо всех проектах в Лондоне.
6.15. Выбрать номера поставщиков деталей для проекта с номером 'Л'.
6.16. Выбрать все поставки, в которых количество деталей находится в диапазоне от 300
до 750 штук включительно.
6.17. Найти все существующие сочетания вида “цвет детали— город, из которого по-
ставляются детали”.
Замечание. Здесь и в последующих упражнениях слово “все” используется в значе-
нии “все, представленные в настоящий момент в базе данных”, а не “все возможные”.
6.18. Найти все такие тройки значений “номер поставщика— номер детали — номер про-
екта”, для которых указанные поставщик, деталь и проект находятся в одном городе.
6.19. Найти все такие тройки значений “номер поставщика — номер детали — номер проек-
та”, для которых указанные поставщик, деталь и проект не находятся в одном городе.
6.20. Найти все такие тройки значений “номер поставщика— номер детали— номер
проекта”, для которых никакие из двух указанных поставщиков, деталей и проек-
тов не находятся в одном городе.
6.21. Выбрать номера деталей, поставляемых поставщиком в Лондоне.
6.22. Выбрать номера деталей, поставляемых поставщиком в Лондоне для проекта в
Лондоне.
6.23. Найти все пары названий городов, для которых поставщик из первого города по-
ставляет детали для проекта во втором городе.
6.24. Выбрать номера деталей, поставляемых для всех проектов поставщиком из того же
города, в котором находится проект.
6.25. Найти все номера проектов, детали для которых поставляются по крайней мере
одним поставщиком не из того же города.
6.26. Выбрать все пары номеров деталей, в которых обе детали поставляются одним и
тем же поставщиком.
6.27. Определить общее число проектов, детали для которых поставляются поставщи-
ком с номером 'S1'.
6.28. Определить общее количество деталей с номером 'Р1', поставляемых поставщи-
ком с номером ' S1'.
6.29. Для каждой детали, поставляемой для проекта, выбрать номер детали, номер про-
екта и соответствующее общее количество.
6.30. Выбрать номера деталей, поставляемых для некоторого проекта, со средним коли-
чеством, составляющим более 350 штук.
Глава 6. Реляционная алгебра
229
6.31. Выбрать названия проектов, детали для которых поставляются поставщиком с но-
мером 'S1'.
6.32. Определить цвета деталей, поставляемых поставщиком с номером ' S1'.
6.33. Установить номера деталей, поставляемых для какого-либо проекта в Лондоне.
6.34. Выбрать номера проектов, в которых используется по крайней мере одна деталь,
имеющаяся у поставщика с номером ' S1'.
6.35. Определить номера поставщиков по крайней мере одной детали, поставляемой по
крайней мере одним поставщиком, который поставляет по крайней мере одну
красную деталь.
6.36. Выбрать номера поставщиков со статусом, меньшим, чем статус поставщика с но-
мером 'S1'.
6.37. Определить номера проектов, находящихся в городе, который указан первым в ал-
фавитном списке городов.
6.38. Выбрать номера проектов, для которых среднее количество поставляемых деталей
с номером 'Р1' больше, чем наибольшее количество любых деталей, поставляе-
мых для проекта с номером ' Л'.
6.39. Определить номера поставщиков детали с номером ' Р1' для некоторого проекта в
количестве, большем среднего количества деталей с номером 'Р1' в поставках для
этого проекта.
6.40. Найти номера проектов, для которых поставщиками из Лондона не поставляются
красные детали.
6.41. Определить номера проектов, детали для которых полностью поставляются по-
ставщиком с номером ' S1'.
6.42. Определить номера деталей, поставляемых для лондонских проектов.
6.43. Установить номера поставщиков одной и той же детали для всех проектов.
6.44. Выбрать номера проектов, в состав которых входят как минимум все типы деталей,
поставляемые поставщиком с номером ' S1'.
6.45. Установить все города, в которых находится по крайней мере один поставщик, од-
на деталь или один проект.
6.46. Определить номера деталей, поставляемых либо лондонским поставщиком, либо
для лондонского проекта.
6.47. Найти все пары типа “номер поставщика— номер детали”, причем только такие, в
которых данный поставщик не поставляет данную деталь.
6.48. Выбрать все пары номеров поставщиков (скажем, Sx и Sy), причем такие, что оба
эти поставщика поставляют в точности одно и то же множество деталей.
(Выражаю благодарность г-ну Фатма Мили (Fatma Mili) из Оклендского универси-
тета (Рочестер, Мичиган), предложившему эту задачу.)
6.49. Подготовить в виде бинарного отношения “сгруппированную” версию всех поста-
вок, в которой для каждой пары “номер поставщика — номер детали” показан со-
ответствующий номер проекта и количество поставленных деталей.
6.50. Получить “разгруппированную” версию отношения из предыдущего упражнения.
230
Часть II Реляционная модель
Список литературы
6.1. Codd. E.F. Relational Completeness of Data Base Sublanguages in Randall J. Rustin
(ed.) 11 Data Base Systems, Courant Computer Science Symposia Series 6. —
Englewood Cliffs, N.J.: Prentice-Hall, 1972.
В этой статье Кодд впервые дает формальное определение операторов исходной
версии реляционной алгебры (определения операторов приводились также в [5.5],
однако они были неполными и менее формальными).
Эта статья обладает одним недостатком. В ней “для удобства объяснения” предпо-
лагается, что атрибуты отношений упорядочены слева направо и, следовательно,
могут быть идентифицированы по своему порядковому номеру. (Тем не менее
Кодд говорит, что на практике лучше использовать имена, а не порядковые номе-
ра. То же самое он говорил в [5.1].) В этой статье ничего не сказано об операторе
RENAME и не рассмотрен вопрос о наследовании типа результата. Возможно, вслед-
ствие этих упущений те же критические замечания применимы сегодня ко многим
рассуждениям в литературе по реляционной алгебре, к SQL-продуктам и (в мень-
шей степени) к стандартам языка SQL.
Другие комментарии к этой статье можно найти в главе 7, в частности в разделе 7.4.
Замечание. В [3.3] описана так называемая алгебра А с “сокращенным набором инст-
рукций”, которая позволяет систематически определять более сложные операторы в
виде определенной комбинации небольшого числа примитивных операторов. Фактиче-
ски в [3.3] показано, что вся функциональность оригинальной алгебры Кодда может
быть получена с помощью всего лишь двух примитивных операторов — remove и пог.
6.2. Darven Н. (writing as Andrew Warden). Adventures in Relationland // Date C.J. Rela-
tional Database Writings 1985-1989. — Reading, Mass.: Addison-Wesley, 1990.
Это серия коротких статей, в которых в оригинальном, развлекательном и инфор-
мативном стиле исследуются различные стороны реляционной модели и реляци-
онных СУБД. Ниже перечислены названия этих статей.
1. The Naming of Columns (Наименования столбцов)
2. In Praise of Marriage (О пользе супружества)
3. The Keys of the Kingdom (Ключи от королевства)
4. Chivalry (Рыцарство)
5. A Constant Friend (Верный друг)
6. Table Dee and Table Dum (Таблица_Чертовка и Таблица Пустышка)
7. Into the Unknown (В неведомое)
6.3. Darwen H. and Date C.J. Into the Great Divide // Darwen H. and Date C.J. Relational
Database Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
В данной статье анализируется оригинальный оператор деления, определенный
Коддом в [6.1], а также обобщение этого оператора, сделанное Холлом (Hall),
Хитчкоком (Hitchcock) и Тоддом (Todd) [6.10], которое в отличие от определенно-
го Коддом оригинального оператора деления позволяет делить любые отношения
на любые другие отношения. (Оригинальный оператор деления Кодда был опреде-
лен только для таких делимых и делителей, заголовок делителя которых является
подмножеством заголовка делимого.) В этой статье описаны трудности, возни-
Глава 6. Реляционная алгебра
231
кающие при использовании данных операторов для пустых отношений, причем ни
один из них не позволил решить проблему, которую предполагалось решить пер-
воначально (т.е. ни один из них не смог стать аналогом квантора общности, как то-
го хотелось бы). Для преодоления трудностей предложены переделанные версии
операторов деления (“Small Divide” и “Great Divide”).
Замечание. Как видно из синтаксиса языка Tutorial D, эти два оператора различны. В
частности, оператор Great Divide представляет собой (к сожалению) не вполне со-
вместимое сверху вниз расширение оператора Small Divide. В данной статье также
предлагается не называть переделанные операторы “делением” (см. упр. 6.5).
Для дальнейших ссылок приведем определение оригинального оператора деления
Кодда. Пусть даны отношения А и В с заголовками {X,Y} и {Y} соответственно. (X и Y
могут быть составными.) Тогда результатом вычисления выражения A DIVIDEBY В
будет отношение с заголовком {X} и телом, состоящим из всех кортежей {Х:х}, та-
ких, что кортеж {X: х, Y: у} содержится в теле отношения А для всех кортежей {Y: у},
содержащихся в отношении В. Другими словами, результат состоит из тех значений
атрибута X из отношения А, для которых соответствующие значения атрибута Y (в от-
ношении А) содержат все значения атрибута Y в отношении В.
6.4. C.J. Date. Quota Queries (в трех частях) // Date C.J., Darven Н., and McGoveran D.
Relational Database Writings 1994-1997. — Reading, Mass.: Addison-Wesley, 1998.
Квота-запрос — это запрос, в котором указывается желаемый предел для кардиналь-
ности результирующего отношения. Например, это может быть запрос “Найти три са-
мые тяжелые детали”. На языке Tutorial D его можно записать следующим образом.
Р QUOTA ( 3, DESC WEIGHT )
Это выражение является сокращенной записью следующего оператора.
( ( EXTEND Р
ADD COUNT ( ( Р RENAME WEIGHT AS WT ) WHERE WT > WEIGHT )
AS #_HEAVIER )
WHERE #_HEAVIER < 3 ) { ALL BUT #_HEAVIER }
(Здесь имена WT и #_HEAVIER могут быть произвольными.) Если взять за основу
наши обычные данные, то результат будет состоять из деталей с номерами ' Р2',
'РЗ' и 'Р6'.
Данная статья состоит из трех частей. В ней детально анализируются квота-
запросы, а также предлагается несколько синтаксических сокращений как для за-
писи этих запросов, так и для других целей.
6.5. Carey M.J. and Kossmann D. On Saying ‘Enough Already’ in SQL // Proc. 1997 Int.
Conf. On Management of Data. — Tucson, Ariz., May, 1997.
Еще одна работа, посвященная квота-запросам. В отличие от [6.4], здесь основное
внимание уделяется вопросам реализации, а не моделирования. Запрос “Найти три
самые тяжелые детали” в контексте этой статьи будет выглядеть так.
SELECT *
FROM Р
ORDER BY WEIGHT DESC
STOP AFTER 3;
232
Часть IL Реляционная модель
Проблема подобного подхода состоит в том, что операция STOP AFTER применяется к
результату выполнения оператора ORDER BY, который (как видно из раздела “Свойства
отношений” главы 5) является не отношением, а массивом или списком. Следователь-
но, окончательный результат, по-видимому, также не будет отношением, а значит, бу-
дет нарушено свойство замкнутости. Этот вопрос в данной статье не обсуждается.
Разумеется, полученный результат можно снова преобразовать в отношение, но тогда
мы столкнемся с еще одной проблемой, поскольку результат выполнения оператора
STOP AFTER в общем случае непредсказуем. Например, если взять за основу наши
обычные данные и в предыдущем SQL-запросе заменить строку STOP AFTER 3 стро-
кой STOP AFTER 2, то результат выполнения этого запроса будет неопределенным.
Оператор STOP AFTER был реализован в исследовательском прототипе компании
IBM и, таким образом, может получить распространение в продуктах IBM, а затем
попасть в стандарт языка SQL (мы надеемся, что не раньше, чем будут решены
указанные выше проблемы).
6.6. Goldstein R.C. and Stmad A. J. The MacAIMS Data Management System 11 Proc. 1970
ACM SICFIDET Workshop on Data Description and Access. — November, 1970.
См. аннотацию к [6.7].
6.7. Stmad A.J. The Relational Approach to the Management of Data Bases П Proc. IFIP
Congress. — Ljubljana, Yugoslavia. — August, 1971.
Мы упоминаем систему MacAIMS [6.6], [6.7], в основном, ради исторического ин-
тереса. Она является наиболее ранним примером системы, поддерживающей п-
арные отношения и алгебраический язык. Интересным также является то, что эта
система разрабатывалась параллельно (и, по меньшей мере, частично независимо)
с работой Кодда над реляционной моделью. Однако, в отличие от работы Кодда,
система MacAIMS не получила существенного развития в будущем.
6.8. Notley M.G. The Peterlee IS/1 System 11 IBM UK Scientific Centre Report UKSC-
0018. —March, 1972.
См. аннотацию к [6.9].
6.9. Todd S.J.P. The Peterlee Relational Test Vehicle—A System Overview 11 IBM Sys.
J. — 1976. — 15, №4.
Peterlee Relational Test Vehicle (PRTV)— это экспериментальная система, разработан-
ная в научном центре компании IBM UK, в городе Петерли, Англия. Она была разрабо-
тана на основе более ранней системы IS/1 [6.8], которая, вероятнее всего, являлась пер-
вой реализацией идей Кодда. В ней поддерживались n-арные отношения и версия ал-
гебры под названием 1SBL (Information System Base Language — базовый язык инфор-
мационных систем). Эта версия реляционной алгебры основывалась на предложениях,
изложенных в [6.10]. Первоисточником идей, приведенных в этой главе относительно
вывода типов отношений, являются алгебра ISBL и предложения из [6.10].
Система PRTV обладала следующими важными свойствами.
Поддерживала операторы RENAME, EXTEND и SUMMARIZE
Включала в себя сложные средства для преобразования выражений (глава 17)
Включала средство отложенного вычисления, что важно как для оптимизации,
так и для поддержки представлений (см. обсуждение предложения WITH в дан-
ной главе)
Глава 6. Реляционная алгебра
233
Обеспечивала “функцию расширяемости”, т.е. возможность расширять систему,
добавляя определенные пользователем операторы
6.10. Hall P.A.V., Hitchcock Р., and Todd S.J.P. An Algebra of Relations for Machine
Computation 11 Conf. Record of the 2nd ACM Symposium on Principles of Programming
Languages. — Palo Alto, Calif. — January, 1975.
6.11. Hall P.A.V. Relational Algebra, Logic and Functional Programming // Proc. 1984 ACM
SIGMOD Int. Conf, on Management of Data. — Boston, Mass. — June, 1984.
В статье представлена функциональная интерпретация реляционной алгебры, чтобы
(как говорится в статье) изложить теоретические основы так называемых “языков
четвертого поколения” (4GL) (см. главу 2) и интегрировать функциональные, логиче-
ские (глава 23) и реляционные языки таким образом, чтобы они могли совместно ис-
пользоваться в технологиях реализации. Автор утверждает, что, хотя логическое про-
граммирование и базы данных уже на протяжении некоторого времени сближаются
друг с другом, во время написания функциональных или аппликативных языков об-
ращается мало внимания на требования баз данных или технологии реализации. По-
этому статья, главным образом, вносит вклад в сближение между ними.
6.12. Klug A. Equivalence of Relational Algebra and Relational Calculus Query Languages
Having Aggregate Functions // JACM 29. — July, 1982. — № 3.
В статье определяется множество расширений реляционной алгебры и реляцион-
ного исчисления (глава 7), предназначенных для включения поддержки обобщаю-
щих функций, и демонстрируется эквивалентность двух расширенных языков.
Ответы к некоторым упражнениям
Замечание. Ответы к упр. 6.13-6.50 не являются единственно возможными.
6.2. Операция соединения JOIN уже рассматривалась в разделе 6.4. Операция пересече-
ния INTERSECT может быть определена одним из двух представленных ниже экви-
валентных вариантов.
A INTERSECT В = A MINUS (A MINUS В )
A INTERSECT В = В MINUS (В MINUS А )
Эти два равносильных выражения хотя и допустимы, но несколько неудовлетвори-
тельны, поскольку A INTERSECT В — симметричное выражение относительно опе-
рандов А и В, а остальные два выражения не симметричны. Для сравнения ниже
приводится симметричный вариант.
( A MINUS ( A MINUS В ) ) UNION ( В MINUS ( В MINUS А ) )
Замечание. Если дано, что отношения А и В совместимы по типу, то получаем сле-
дующее.
A INTERSECT В = A JOIN В
Теперь о делении. Можно записать следующее.
A DIVIDEBY В PER С = А { X }
MINUS ( ( А { X } TIMES В { Y } )
MINUS С { X, Y } ) { X }
234
Часть II. Реляционная модель
Здесь X — множество атрибутов, общих для отношений А и С, a Y — множество ат-
рибутов, общих для отношений В и С.
Замечание. Определенный таким образом оператор DIVIDEBY является обобщением
оператора деления, рассмотренного ранее в этой главе, но все еще не оператором
Small Divide [6.3] ввиду предположения о том, что отношение А не содержит атрибу-
тов, отличных от атрибутов X, отношение В не содержит атрибутов, отличных от Y, и
отношение С не имеет атрибутов, отличных от атрибутов X и Y. Приведенное выше
обобщение позволяет записать запрос “Получить номера поставщиков всех деталей”
в более простой форме S DIVIDEBY Р PER SP вместо развернутой формулировки.
S { S# } DIVIDEBY Р { P# } PER SP { S#, P# }
6.3. A INTERSECT В (см. ответ к упр. 6.2).
Замечание. Поскольку операция произведения является специальным случаем опе-
рации соединения, в роли примитивного оператора вместо TIMES может выступать
оператор JOIN, тем более что он является более общим.
6.4. Здесь мы даем только неформальное (очень неформальное) схематическое
“доказательство”.
Оператор произведения — это единственный оператор, увеличивающий количе-
ство атрибутов, а значит, его нельзя имитировать любыми другими операторами.
Поэтому произведение — примитивная операция.
Оператор проекции — это единственный оператор, уменьшающий количество
атрибутов, а значит, его нельзя имитировать любыми другими операторами. По-
этому проекция — примитивная операция.
Оператор объединения — единственный оператор, увеличивающий количество
кортежей, кроме оператора произведения, но произведение к тому же увеличива-
ет количество атрибутов. Пусть отношения А и В должны быть объединены. Об-
ратите внимание, что отношения А и В должны быть совместимы по типу и в их
объединении должны быть те же атрибуты, что и в них самих. Если мы образуем
произведение отношений А и В, а затем используем проекцию, чтобы уменьшить
множество атрибутов в произведении до множества атрибутов в отношении А
(или В), мы просто снова вернемся к исходному отношению А (или В).
( A TIMES В ) { <все атрибут^ А } = А
(Но только если отношение В не пустое.) Следовательно, произведение не может
быть использовано для моделирования операции объединения, а значит, опера-
ция объединения примитивна.
Оператор вычитания не может быть смоделирован через произведение
(поскольку операция произведения увеличивает количество кортежей), через
объединение (аналогично) или через проекцию (поскольку проекция сокращает
количество атрибутов). Также он не может быть смоделирован с помощью вы-
борки, поскольку вычитание реагирует на значения во втором отношении, кото-
рого не может быть при выборке (в силу природы условия выборки). Следова-
тельно, операция вычитания также примитивна.
Глава 6. Реляционная алгебра
235
Оператор выборки является единственной операцией, которая позволяет сравни-
вать значения атрибутов с определенными литералами (т.е. со значениями, кото-
рые не являются частью какого-либо отношения). Следовательно, операция вы-
борки также примитивна.
6.5. Короткий ответ— нет. Оригинальный оператор Кодда DIVIDEBY удовлетворяет
следующему условию.
( A TIMES В ) DIVIDEBY В = А
Однако необходимо принять к сведению следующее.
Оператор деления Кодда был бинарным, а наш оператор DIVIDEBY является
триадическим; следовательно, он не может удовлетворять подобному свойству.
В любом случае, даже если, используя оператор Кодда, разделить А на В, а затем
найти декартово произведение результата и отношения В, может получиться от-
ношение, совпадающее с А, хотя, вероятнее всего, оно будет некоторым собст-
венным подмножеством А.
( A DIVIDEBY В ) TIMES В < А
Оператор DIVIDEBY Кодда больше похож на целочисленное деление в обычной
арифметике (т.е. он игнорирует остаток).
6.6. Ловушка заключается в том, что в операции JOIN атрибуты CITY используются так
же, как и атрибуты S# и P# (в силу нашего определения оператора JOIN). Результат
будет подобен следующему.
S# SNAME STATUS CITY P# QTY PNAME COLOR WEIGHT
S1 Smith 20 London Pl 300 Nut Red 12.0
S1 Smith 20 London P4 200 Screw Red 14.0
S1 Smith 20 London P6 100 Cog Red 19.0
S2 Jones 10 Paris P2 400 Bolt Green 17.0
S3 Black 30 Paris P2 200 Bolt Green 17.0
S4 Clark 20 London P4 200 Screw Red 14.0
6.7. Количество возможных проекций равно 2П. К ним относятся идентичная проекция
(т.е. проекция по всем п атрибутам, которая дает результат, идентичный исходному
отношению А) и “нулевая” проекция (т.е. проекция по никаким атрибутам), которая
дает в результате TABLE_DUM, если исходное отношение А пустое, и TABLE_DEE в
противном случае [5.5].
6.8. Да, есть такое отношение, а именно— TABLE_DEE. Отношение TABLE_DEE (далее
для краткости — просто DEE) — аналог числа 1 по отношению к умножению в
обычной арифметике, поскольку для всех отношений R имеем следующее.
R TIMES DEE = DEE TIMES R = R
Иначе говоря, DEE — это тождественный элемент для операции TIMES (и конечно,
для операции JOIN).
6.9. Не существует отношения, ведущего себя относительно операции TIMES аналогич-
но числу нуль относительно операции умножения. Однако поведение отношения
TABLE_DUM (или сокращенно — DUM) несколько сходно с поведением нуля, так как
для всех отношений R имеем следующее.
236
Часть II. Реляционная модель
R TIMES DUM = DUM TIMES R = <пустое отношение с тем же
заголовком, что и заголовок R>
6.10. Отношениями, которые совместимы с DEE и DUM при объединении, пересечении и
вычитании, являются сами отношения DEE и DUM. В результате имеем следующее.
UNION DEE DUM INTERSECT DEE DUM MINUS DEE DUM
DEE DEE DEE DEE DEE DUM DEE DUM DEE
DUM DEE DUM DUM DUM DUM DUM DUM DUM
В случае вычитания первый операнд показан слева в таблице, а второй — вверху
(для других операторов, конечно, операнды могут меняться местами). Обратите
внимание, как это напоминает таблицы истинности для логических операций OR,
AND, AND NOT соответственно. Конечно, такое совпадение не случайно.
Рассмотрев затем выборку и проекцию, получим следующее.
Любая выборка из отношения DEE дает отношение DEE, если значение условия
выборки равно значению истина, и DUM, если оно равно значению ложь.
Любая выборка из отношения DUM дает отношение DUM.
Проекция любого отношения по пустому множеству атрибутов дает отношение
DUM, если исходное отношение пустое, и отношение DEE в противном случае. В
частности, проекция отношения DEE или отношения DUM (обязательно по пустому
множеству атрибутов) возвращает исходное отношение.
Для операций расширения и подведения итогов имеем следующее.
Расширение отношения DEE или DUM для добавления новых атрибутов дает отношение
с одним атрибутом и тем же количеством кортежей, что и в исходном отношении.
Суммирование отношения DEE или DUM (обязательно по пустому множеству ат-
рибутов) дает отношение с одним атрибутом и тем же количеством кортежей,
что и в исходном отношении.
6.11. Нет!
6.12. Мы можем определить (и определяем) объединение, пересечение, произведение
или соединение одного отношения R как само R. Рассмотрим случай, когда п=0.
Пусть RT — некоторый тип отношений. Тогда имеем следующее.
Объединением нулевого числа отношений типа RT будет пустое отношение типа
RT. Обратите внимание, что при этом должен существовать какой-либо способ
указания того, что RT — операнд операции объединения.
Пересечением нулевого числа отношений типа RT является “универсальное” отноше-
ние типа RT, где термин “универсальное отношение типа RT” обозначает отношение
типа RT, тело которого состоит из всевозможных кортежей, удовлетворяющих заго-
ловку отношения (при этом, опять-таки, должен быть какой-то способ указания того,
что RT — операнд операции пересечения). Заметьте, что термин “универсальное от-
ношение” часто употребляется в литературе с другим значением [12.19]!
Произведением и пересечением нулевого числа отношений будет TABLE_DEE.
6.13. J
Глава 6. Реляционная алгебра
237
6.14. J WHERE CITY = 'London'
6.15. ( SPJ WHERE J# = J# ( 'JI' ) ) { S# }
6.16. SPJ WHERE QTY > QTY ( 300 ) AND QTY < QTY ( 750 )
6.17. P { COLOR, CITY }
6.18. ( S JOIN P JOIN J ) { S#, P#, J# }
6.19. ( ( ( S RENAME CITY AS SCITY ) TIMES
( P RENAME CITY AS PCITY ) TIMES
( J RENAME CITY AS JCITY ) )
WHERE SCITY * PCITY
OR PCITY * JCITY
OR JCITY * SCITY ) { S#, P#, J# }
6.20. ( ( ( S RENAME CITY AS SCITY ) TIMES
( P RENAME CITY AS PCITY ) TIMES
( J RENAME CITY AS JCITY ) )
WHERE SCITY Ф PCITY
AND PCITY * JCITY
AND JCITY * SCITY ) { S#, P#, J# }
6.21. P SEMIJOIN ( SPJ SEMIJOIN ( S WHERE CITY = 'London' ) )
6.22. Для того чтобы напомнить о такой возможности, приводим пошаговое решение
этой задачи.
WITH ( S WHERE CITY = 'London' ) AS Tl,
( J WHERE CITY = 'London' ) AS T2,
( SPJ JOIN Tl ) AS T3,
T3 { P#, J# } AS T4,
( T4 JOIN T2 ) AS T5 :
T5 { P# }
Вот как выглядит этот же запрос без использования WITH.
( ( SPJ JOIN ( S WHERE CITY = 'London' ) ) { P#, J# }
JOIN ( J WHERE CITY = 'London' ) ) { P# }
Далее приводятся ответы к следующим упражнениям (как с предложением WITH так
и без него).
6.23. ( ( S RENAME CITY AS SCITY ) JOIN SPJ JOIN
( J RENAME CITY AS JCITY ) ) { SCITY, JCITY }
6.24. ( J JOIN SPJ JOIN S ) { P# }
6.25. ( ( ( J RENAME CITY AS JCITY ) JOIN SPJ JOIN
( S RENAME CITY AS SCITY ) )
WHERE JCITY * SCITY ) { J# }
6.26. WITH ( SPJ { S#, P# } RENAME S# AS XS#, P# AS XP# ) AS Tl,
( SPJ { S#, P# } RENAME S# AS YS#, P# AS YP# ) AS T2,
( Tl TIMES T2 ) AS T3,
238
Часть II. Реляционная модель
( ТЗ WHERE XS# = YS# AND XP# < YP# ) AS T4 :
T4 { XP#, YP# }
6.27. ( SUMMARIZE SPJ { S#, J# }
PER RELATION { TUPLE { S# S# ( 'Si' ) } }
ADD COUNT AS N ) { N }
Напоминаем, что фигурирующее в предложении PER выражение является вызовом
оператора выбора (в действительности это отношение-литерал).
6.28. ( SUMMARIZE SPJ { S#, Р#, QTY }
PER RELATION { TUPLE { S# S# ( 'Si' ), P# P# ( 'Pl' ) } }
ADD SUM ( QTY ) AS Q ) { Q }
6.29. SUMMARIZE SPJ PER SPJ { P#, J# } ADD SUM ( QTY ) AS Q
6.30. WITH ( SUMMARIZE SPJ PER SPJ { P#, J# }
ADD AVG ( QTY ) AS Q ) AS Tl,
( Tl WHERE Q > QTY ( 350 ) ) AS T2 :
T2 { P# }
6.31. ( J JOIN ( SPJ WHERE S# = S# ( 'SI' ) ) ) { JNAME }
6.32. ( P JOIN ( SPJ WHERE S# = S# ( 'SI' ) ) ) { COLOR }
6.33. ( SPJ JOIN ( J WHERE CITY = 'London' ) ) { P# }
6.34. ( SPJ JOIN ( SPJ WHERE S# = S# ( 'Si' ) ) { P# } ) { J# }
6.35. ( ( ( SPJ JOIN
( P WHERE COLOR = COLOR ( 'Red' ) ) { P# } ) { S# }
JOIN SPJ ) { P# } JOIN SPJ ) { S# }
6.36. WITH ( S { S#, STATUS } RENAME S# AS XS#,
STATUS AS XSTATUS ) AS Tl,
( S { S#, STATUS } RENAME S# AS YS#,
STATUS AS YSTATUS ) AS T2,
( Tl TIMES T2 ) AS T3,
( T3 WHERE XS# = S# ( 'SI' ) AND
XSTATUS > YSTATUS ) AS T4 :
T4 { YS# }
6.37. ( ( EXTEND J ADD MIN ( J, CITY ) AS FIRST )
WHERE CITY = FIRST ) { J# }
Каким будет результат выполнения этого запроса в случае, когда базовая перемен-
ная-отношение J пуста?
6.38. WITH ( SPJ RENAME J# AS ZJ# ) AS Tl,
( Tl WHERE ZJ# = J# AND P# = P# ( 'Pl' ) ) AS T2,
( SPJ WHERE P# = P# ( 'Pl' ) ) AS T3,
( EXTEND T3 ADD AVG ( T2, QTY ) AS QX ) AS T4,
T4 { J#, QX } AS T5,
( SPJ WHERE J# = J# ( 'JI' ) ) AS T6,
Глава 6. Реляционная алгебра
239
( EXTEND Тб ADD MAX ( Тб, QTY ) AS QY ) AS T7,
( T5 TIMES T7 { QY } ) AS T8,
( T8 WHERE QX > QY ) AS T9 :
T9 { J# }
6.39. WITH ( SPJ WHERE P# = P# ( 'Pl' ) ) AS Tl,
Tl { S#, J#, QTY } AS T2,
( T2 RENAME J# AS XJ#, QTY AS XQ ) AS T3,
( SUMMARIZE Tl PER SPJ { J# }
ADD AVG ( QTY ) AS Q AS T4,
( T3 TIMES T4 ) AS T5,
( T5 WHERE XJ# = J# AND XQ > Q ) AS Тб :
Тб { S# }
6.40. WITH ( S WHERE CITY = 'London' ) { S# } AS Tl,
( P WHERE COLOR = COLOR ( 'Red' ) ) AS T2,
( Tl JOIN SPJ JOIN T2 ) AS T3 :
J { J# } MINUS T3 { J# }
6.41. J { J# } MINUS ( SPJ WHERE S# * S# ( 'SI' ) ) { J# }
6.42. WITH ( ( SPJ RENAME P# AS X ) WHERE X = P# ) { J# } AS Tl,
( J WHERE CITY = 'London' ) { J# } AS T2,
( P WHERE Tl > T2 ) AS T3 :
T3 { P# }
6.43. S { S#, P# } DIVIDEBY J { J# } PER SPJ { S#, P#, J# }
6.44. ( J WHERE
( ( SPJ RENAME J# AS Y ) WHERE Y = J# ) { P# } >
( SPJ WHERE S# = S# ( 'SI' ) ) { P# } ) { J# }
6.45. S { CITY } UNION P { CITY } UNION J { CITY }
6.46. ( SPJ JOIN ( S WHERE CITY = 'London' ) ) { P# }
UNION
( SPJ JOIN ( J WHERE CITY = 'London' ) ) { P# }
6.47. ( S TIMES P ) { S#, P# } MINUS SP { S#, P# }
6.48. Предоставляем два решения этой задачи. В первом решении, принадлежащем Хью
Дарвену, используются только операторы из разделов 6.2 и 6.3.
WITH ( SP RENAME S# AS SA ) { SA, P# } AS Tl,
/* Tl {SA, P#} : SA поставляет деталь P# */
( SP RENAME S# AS SB ) { SB, P# } AS T2,
/* T2 {SB, P#} : SB поставляет деталь P# */
Tl { SA } AS T3,
/* T3 {SA} : SA поставляет некоторую деталь */
T2 { SB } AS T4,
/* T4 {SB} : SB поставляет некоторую деталь */
240
Часть II. Реляционная модель
( Tl TIMES T4 ) AS T5,
/* T5 {SA,SB,P#} : SA поставляет некоторую деталь, и
SB поставляет деталь P# */
( Т2 TIMES ТЗ ) AS Тб,
/* Тб {SA,SB,P#} : SB поставляет некоторую деталь, и
SA поставляет деталь P# */
( Tl JOIN Т2 ) AS Т7,
/* Т7 {SA,SB,P#} : SA и SB поставляют деталь P# */
( ТЗ TIMES Т4 ) AS Т8,
/* Т8 {SA,SB} : SA поставляет некоторую деталь, и
SB поставляет некоторую деталь */
SP { P# } AS T9,
/* T9 {Р#} : деталь P# поставляется некоторым поставщиком */
( Т8 TIMES T9 ) AS Т10,
/* Т10 {SA,SB,P#} :
SA поставляет некоторую деталь,
SB поставляет некоторую деталь, и
деталь P# поставляется некоторым поставщиком */
( Т10 MINUS Т7 ) AS Til,
/* Til {SA,SB,P#} : деталь P# поставляется,
но не поставщиками SA и SB */
( Тб INTERSECT Til ) AS Т12,
/* Т12 {SA,SB,P#} : деталь P# поставляется поставщиком SA,
но не SB */
( Т5 INTERSECT Til ) AS T13,
/* T13 {SA,SB,P#} : деталь P# поставляется поставщиком SB,
но не SA */
Т12 { SA, SB } AS T14,
/* T14 {SA,SB} : SA поставляет некоторую деталь,
не поставляемую поставщиком SB */
Т13 { SA, SB } AS T15,
/* T15 {SA,SB} : SB поставляет некоторую деталь,
не поставляемую поставщиком SA */
( Т14 UNION Т15 ) AS Т1б,
/* Т16 {SA,SB} : некоторая деталь поставляется
поставщиком SA или SB, но не обоими */
Глава 6. Реляционная алгебра
241
Т7 { SA, SB } AS T17,
/* T17 {SA,SB} : некоторая деталь поставляется
как поставщиком SA,
так и поставщиком SB */
( Т17 MINUS Т16 ) AS Т18,
/* Т18 {SA,SB} : некоторая деталь поставляется
как поставщиком SA, так
и поставщиком SB,
ни одна деталь, поставляемая SA,
не поставляется поставщиком SB,
и ни одна деталь, поставляемая SB,
не поставляется поставщиком SA
— таким образом, SA и SB поставляют
в точности одни и те же детали */
( Т18 WHERE SA < SB ) AS T19 :
/* завершающий шаг */
Т19
Во втором решении, которое является более прямолинейным, используются реля-
ционные сравнения, рассмотренные в разделе 6.9.
WITH ( S RENAME S# AS SA ) { SA } AS RA ,
( S RENAME S# AS SB ) { SB } AS RB :
( RA TIMES RB)
WHERE ( SP WHERE S# = SA ) { P# } =
( SP WHERE S# = SB ) { P# }
AND SA < SB
6.49. SPJ GROUP ( J#, QTY ) AS JQ
6.50. Обозначим через SPQ результат выполнения выражения, полученного в ответе к
упр. 6.49. Тогда имеем следующее.
SPQ UNGROUP JQ
242
Часть II. Реляционная модель
Глава
Реляционное исчисление
7Л. Введение
В главе 6 отмечалось, что часть реляционной модели, которая связана с операторами
манипулирования данными, основывается на использовании реляционной алгебры. Однако
с тем же основанием можно сказать, что она построена на базе реляционного исчисления.
Другими словами, реляционная алгебра и реляционное исчисление представляют собой два
альтернативных подхода. Принципиальное различие между ними следующее. Реляционная
алгебра в явном виде предоставляет набор операций (соединение, объединение, проекция и
т.д.), которые можно использовать, чтобы сообщить системе, как в базе данных из опреде-
ленных отношений построить некоторое требуемое отношение, а реляционное исчисление
просто представляет систему обозначений для определения требуемого отношения в тер-
минах данных отношений. Например, рассмотрим запрос “Выбрать номера поставщиков и
названия городов, в которых находятся поставщики детали с номером 'Р2'”.
Алгебраическая версия этого запроса выглядит приблизительно так (мы умышленно не ис-
пользуем формальный синтаксис, приведенный в главе 6).
Сначала выполнить соединение отношения поставщиков S и отношения поставок
SP по атрибуту S#.
Далее выбрать из результата этого соединения кортежи с номером детали 'Р2'.
И наконец выполнить для результата этой выборки операцию проекции по атри-
бутам S# и CITY.
Этот же запрос в терминах реляционного исчисления формулируется приблизительно так.
Получить атрибуты S# и CITY для таких поставщиков, для которых в отношении
SP существует запись о поставке с тем же значением атрибута S# и со значением
атрибута Р|, равным 'Р2'.
В этой формулировке пользователь лишь указывает определенные характеристики
требуемого результата, оставляя системе решать, что именно и в какой последовательно-
сти соединять, проецировать и т.д., чтобы получить необходимый результат.
Итак, можно сказать, что по крайней мере внешне формулировка запроса в терминах
реляционного исчисления носит описательный характер, а в терминах реляционной ал-
гебры — предписывающий. В реляционном исчислении просто описывается, в чем за-
ключается проблема, тогда как в реляционной алгебре задается процедура решения этой
проблемы. Или, говоря очень неформально, алгебра имеет процедурный характер (пусть
на высоком уровне, но все же процедурный, поскольку задает необходимые для выпол-
нения процедуры), а исчисление — непроцедурный.
Глава 7. Реляционное исчисление
243
Подчеркнем, однако, что упомянутые отличия существуют только внешне. На
самом деле реляционная алгебра и реляционное исчисление логически эквивалентны.
Каждому выражению в алгебре соответствует эквивалентное выражение в исчисле-
нии, и точно так каждому выражению в исчислении соответствует эквивалентное
выражение в алгебре. Это означает, что между ними существует взаимно-
однозначное соответствие, а различия связаны лишь с разными стилями выражения:
исчисление ближе к естественному языку, а алгебра — к языку программирования.
Но, повторим еще раз, эти различия только кажущиеся, а не реальные. В частности,
ни один из подходов нельзя назвать “более непроцедурным” по сравнению с другим.
Подробнее вопрос эквивалентности этих двух подходов будет рассматриваться в
разделе 7.4 настоящей главы.
Реляционное исчисление основано на разделе математической логики, который назы-
вается исчислением предикатов. Идея использования исчисления предикатов в качестве
основы языка баз данных впервые была высказана в статье Кунса (Kuhns) [7.6]. Понятие
реляционного исчисления, т.е. специального применения исчисления предикатов в реля-
ционных базах данных, впервые было предложено Коддом в [6.1], а в [7.1] Кодд пред-
ставил язык, основанный непосредственно на реляционном исчислении и названный
“подъязык данных ALPHA”. Сам язык ALPHA никогда не был реализован, однако язык
QUEL [7.5], [7.10]-[7.12], который действительно был реализован и некоторое время
серьезно конкурировал с языком SQL, очень походил на язык ALPHA, оказавший замет-
ное влияние на построение языка QUEL.
Основным средством реляционного исчисления является понятие переменной кор-
тежа (также называемой переменной области значений). Коротко говоря, переменная
кортежа — это переменная, “изменяющаяся на” некотором заданном отношении, т.е. пе-
ременная, допустимыми значениями которой являются кортежи заданного отношения.
Другими словами, если переменная кортежа V изменяется в пределах отношения г, то в
любой заданный момент переменная V представляет некоторый кортеж t отношения г.
Например, запрос “Получить номера поставщиков из числа тех, которые находятся в
Лондоне” может быть выражен на языке QUEL так.
RANGE OF SX IS S;
RETRIEVE ( SX.S# ) WHERE SX.CITY = "London";
Переменной кортежа здесь является переменная SX, которая изменяется на отно-
шении, представляющем собой текущее значение переменной-отношения S
(оператор RANGE — оператор определения этой переменной). Оператор RETRIEVE оз-
начает следующее: “Для каждого возможного значения переменной SX выбирать
компонент S# этого значения тогда и только тогда, когда его компонент CITY имеет
значение 'London'”.
В связи с тем, что реляционное исчисление основано на переменных кортежа, его
первоначальную версию (для отличия от исчисления доменов, речь о котором пойдет
ниже) называют также исчислением кортежей. Исчисление кортежей подробно описано
в разделе 7.2.
Замечание. Для удобства примем следующее соглашение: далее в этой книге тер-
мины исчисление и реляционное исчисление, приведенные без уточнения “кортежей”
или “доменов”, будут означать именно исчисление кортежей (там где это играет ка-
кую-то роль).
244
Часть II. Реляционная модель
В статье Лакруа (Lacroix) и Пиротте (Pirotte) [7.7] предлагается альтернативная
версия исчисления, называемая исчислением доменов, в которой переменные кортежа
изменяются на доменах, т.е. являются переменными, изменяемыми на доменах, а не на
отношениях1. В литературе предлагается множество языков исчисления доменов. Наи-
более известный из них—пожалуй, Query-By-Example, или QBE [7.14] (в действи-
тельности он является смешанным, так как в языке QBE присутствуют и элементы ис-
числения кортежей). Существует несколько коммерческих реализаций этого языка. В
общих чертах исчисление доменов будет описано в разделе 7.6, а язык QBE вкратце
рассматривается в комментариях к [7.14].
Замечание. Пытаясь сделать эту главу короче, мы умышленно опускаем подробное
описание некоторых вопросов, рассмотренных в главе 6, а именно: транзитивное замы-
кание, группирование, разгруппирование и реляционные сравнения. Мы также опускаем
рассмотрение соответствующих версий реляционных операторов обновления. Все эти
элементы можно перенести “на почву” реляционного исчисления (в версии кортежей или
доменов) вполне очевидным способом. Кратко эти вопросы обсуждаются в [3.3].
7.2. Исчисление кортежей
Как и при описании реляционной алгебры в главе 6, сначала введем для реляци-
онного исчисления конкретный синтаксис, взяв за образец (хотя умышленно не со-
всем точно) версию исчисления языка Tutorial D, определенного в [3.3], а затем пе-
рейдем к обсуждению семантики. В следующих ниже подразделах обсуждаются
синтаксис и семантика.
Синтаксис
Замечание. Многие из приведенных здесь синтаксических правил не будут понятны
вам до тех пор, пока вы не изучите семантический материал, следующий далее. Однако
мы все же решили собрать все правила вместе для удобства ссылок.
Начнем с повторения синтаксиса параметра реляционное выражение^ приведенного
в главе 6.
реляционное выражение>
::= RELATION { < список выражений кортежей > }
< имя переменной-отношения >
реляционная операция?
( реляционное выражение> )
Иными словами, синтаксис параметра реляционное выражение> остается прежним,
однако один из наиболее важных его подпараметров, реляционная операция?, теперь
будет иметь совершенно иное определение.
<определение переменной кортежа>
::= RANGEVAR <имя переменной кортежа>
RANGES OVER <список реляционных выражений ;
1 Данный термин нелогичен: если исчисление доменов называется так по указанной причине,
то исчисление кортежей следовало бы назвать исчислением отношений.
Глава 7. Реляционное исчисление
245
Параметр <имя переменной кортежа> может использоваться как <выражение
кортежа>2, однако лишь в определенном контексте, а именно:
перед точкой и последующим уточнением в параметре <ссылка на атрибут кортежа>;
сразу после квантора в параметре Логическое выражение с квантором>;
как операнд в параметре Логическое выражение^,
как параметр <прототип кортежа> или как (операнд) подпараметр <выражение> в
параметре <прототип кортежа>.
< ссылка на атрибут кортежа>
::= <имя переменной кортежа>.<ссылка на атрибут*
[ AS <имя атрибута> ]
Параметр <ссылка на атрибут кортежа> может использоваться как параметр
<выражение>, но только в определенном контексте, а именно:
как операнд параметра <логическое выражение^,
как параметр <прототип кортежа> или как (операнд) подпараметр <выражениё> в
параметре <прототип кортежа>.
Логическое выражение>
::= ... все обычные возможности вместе с:
| Логическое выражение с кванторов»
Ссылки на переменные кортежей в значении параметра <логическое выражение> мо-
гут быть свободными в пределах этого параметра тогда и только тогда, когда выполнены
два следующих условия.
Параметр Логическое выражение> расположен непосредственно после параметра
реляционная операция* (т.е. параметр Логическое выражение> следует сразу за
ключевым словом WHERE).
Ссылка (обязательно свободная) именно на эту переменную кортежа непосредственно
присутствует в значении параметра <прототип кортежа>, непосредственно содержа-
щегося в том же выражении реляционная операция* (т.е. параметр <прототип
кортежа> располагается непосредственно перед ключевым словом WHERE).
Замечание по терминологии. В контексте реляционного исчисления (в версии исчис-
ления доменов или исчисления кортежей) логические выражения часто называют пра-
вильно построенными формулами (well-formed formulas— WFF, что произносится как
“вэфф”). Далее мы также будем часто пользоваться этой терминологией.
Логическое выражение с квантороК>
::= EXISTS <имя переменной кортежа> ( логическое выражение> )
| FORALL <имя переменной кортежа> ( логическое выражение> )
2 Как и в главе 6, мы не приводим здесь подробного описания параметра <выражение
кортежа>, надеясь, что общая идея его построения будет понятна из примеров
246
Часть II. Реляционная модель
реляционная операция>
:: = <прототип кортежа> [ WHERE Логическое выражение> ]
В реляционной алгебре, рассмотренной в главе 6, параметр реляционная
операциЯ> представлял собой одну из форм параметра реляционное выражение^ од-
нако здесь он определяется иначе. Другие формы параметра реляционное выражение>
(в основном, имена переменных-отношений и обращение к операторам выбора) допус-
тимы, как и ранее.
<прототип кортежа>
::= <выражение кортежа>
Все ссылки на переменные кортежа, помещенные непосредственно в значение пара-
метра <прототип кортежах должны быть свободными в пределах данного параметра
<прототип кортежах
Замечание. Прототип кортежа — термин удачный, но не стандартный.
Переменные кортежей
Приведем несколько примеров определения переменных кортежей (выраженных, как
обычно, в контексте базы данных поставщиков и деталей).
RANGEVAR SX RANGEVAR SY RANGEVAR SPX RANGES OVER S ; RANGES OVER S ; RANGES OVER SP ; RANGES OVER SP ;
RANGEVAR RANGEVAR SPY PX
RANGES OVER P ;
RANGEVAR SU RANGES । OVER
SX WHERE SX.CITY = 'London' ) ,
I SX WHERE EXISTS SPX ( SPX.S# = SX.S# AND
SPX.P# SPX = P# ( 'Р1' ) ) ) ;
Переменная кортежа SU из последнего примера определена на объединении множест-
ва кортежей поставщиков, находящихся в Лондоне, и множества кортежей поставщиков
детали с номером 'Р1'. Обратите внимание, что в определении переменной кортежа SU
используются переменные кортежей SX и SPX. Также обратите внимание на то, что в по-
добных определениях переменных, построенных на объединении отношений, объеди-
няемые отношения, безусловно, должны быть совместимы по типу.
Замечание. Переменные кортежей не являются переменными в обычном смысле (как
в языках программирования); они являются переменными в логическом смысле. В дейст-
вительности они в значительной мере аналогичны местодержателям или параметрам
предикатов, обсуждавшихся в главе 3. (Различие состоит в том, что на место параметров
предикатов, обсуждавшихся в этой главе, подставляются значения из некоторого домена,
а на место переменных кортежей подставляются кортежи.)
Далее в этой главе предполагается, что приведенные выше определения переменных
кортежей остаются в силе. Следует отметить, что в реальном языке должны быть опре-
деленные правила относительно области действия таких определений. В настоящей главе
этот вопрос не рассматривается.
Глава 7. Реляционное исчисление
247
Свободные и связанные переменные кортежей
Каждая ссылка на переменную кортежа (в некотором контексте, в частности в фор-
муле WFF) является или свободной, или связанной. Сначала поясним это утверждение
в чисто синтаксических терминах, а затем перейдем к обсуждению его смысла.
Пусть V — переменная кортежа. Тогда имеем следующее.
Ссылки на переменную V в формулах WFF типа NOT р свободны или связаны в
пределах этой формулы в зависимости от того, свободны ли они в формуле р.
Ссылки на переменную V в формулах WFF типа (р AND q) и (р OR q) свободны
или связаны в зависимости от того, свободны ли они в формулах р и q.
Ссылки на переменную V, которые свободны в формуле WFF р, связаны в форму-
лах WFF типа EXISTS V(p) и FORALL V(p). Другие ссылки на переменные корте-
жей в формуле р будут свободны или связаны в формулах WFF типа EXISTS V(p)
и FORALL V(p) в соответствии с тем, свободны ли они в формуле р.
Для полноты необходимо добавить следующие замечания.
Единственная ссылка на переменную V в значении параметра <имя переменной
кортежа> является свободной в пределах этого параметра <имя переменной
кортежа>.
Единственная ссылка на переменную V в значении параметра <ссылка на
атрибут кортежа> V.А является свободной в пределах этого параметра <ссылка
на атрибут кортежа>.
Если ссылка на переменную V является свободной в некотором выражении ехр, то
эта ссылка будет также свободной в любом выражении ехр', непосредственно со-
держащем выражение ехр как подвыражение, если только в выражении ехр' не
вводится квантор, связывающий переменную V.
Приведем несколько примеров формул WFF, содержащих переменные кортежей.
Простые сравнения
SX.S# = S# ( 'SI' )
SX.S# = SPX.S#
SPX.P# * PX.P#
Здесь все ссылки на переменные SX, РХ и SPX являются свободными.
Логические выражения из простых сравнений
РХ.WEIGHT < WEIGHT ( 15.5 ) OR PX.CITY = 'Rome'
NOT ( SX.CITY = 'London' )
SX.S# = SPX.S# AND SPX.P# * PX.P#
PX.COLOR = COLOR ( 'Red' ) OR PX.CITY = 'London'
Здесь также все ссылки на переменные SX, РХ и SPX являются свободными.
248
Часть II. Реляционная модель
Формулы WFF с кванторами
EXISTS SPX ( SPX.S# = SX.S# AND SPX.P# = P# ( 'P2' ) )
FORALL РХ ( PX.COLOR = COLOR ( 'Red' ) )
В этих примерах ссылки на переменные SPX и РХ являются связанными, а ссылка на
переменную SX является свободной. Подробнее данные примеры объясняются ниже.
Кванторы
Существует два квантора: EXISTS и FORALL. Квантор EXISTS является квантором су-
ществования, a FORALL — квантором всеобщности. По сути, если выражение р — форму-
ла WFF, в которой переменная V свободна, то выражения
EXISTS V ( р )
и
FORALL V ( р )
также являются допустимыми формулами WFF, но переменная V в них обеих будет
связанной. Первая формула означает следующее: “Существует по крайней мере одно
значение переменной V, такое, что вычисление формулы р дает для него значение ис-
тина". Вторая формула означает следующее: “Для всех значений переменной V вы-
числение формулы р дает значение истина". Предположим, например, что переменная
V изменяется на множестве “Члены сената США в 1999 году”, и предположим также,
что выражение р — следующая формула WFF: “V — женщина” (разумеется, мы не пы-
таемся использовать здесь формальный синтаксис). Тогда выражение EXISTS V(p) бу-
дет допустимой формулой WFF, имеющей значение истина (true); выражение
FORALL V(p) также будет допустимой формулой WFF, но вычисление его значения бу-
дет давать значение ложь (false).
Теперь рассмотрим квантор существования EXISTS более внимательно. Еще раз обра-
тимся к примеру из предыдущего раздела.
EXISTS SPX ( SPX.S# = SX.S# AND SPX.P# = P# ( 'P2' ) )
Из приведенных ранее рассуждений следует, что эта формула WFF может быть про-
читана следующим образом.
В текущем значении переменной-отношения SP существует кортеж (скажем, SPX),
такой, для которого значение атрибута St в этом кортеже равно значению атрибу-
та SX. St (какое бы оно ни было), а значение атрибута Pt в кортеже SPXравно 'Р2'.
Каждая ссылка на переменную SPX в этом примере является связанной. Единственная
ссылка на переменную SX свободна.
Формально квантор существования EXISTS определяется как повторение операции OR
(ИЛИ). Другими словами, если г — это отношение с кортежами tl, t2, ... , tm, V — это
переменная кортежа, изменяющаяся на данном отношении, и р(V) — это формула WFF, в
которой переменная V используется как свободная переменная, то формула WFF вида
EXISTS V ( р ( V ) )
Глава 7. Реляционное исчисление
249
равносильна следующей формуле WFF.
false OR р ( tl ) OR ... OR p ( tm )
В частности, обратите внимание, что если отношение R пустое (т.е. ш=0), то результа-
том вычисления данного выражения будет значение ложь.
Рассмотрим в качестве примера отношение г, содержащее следующие кортежи.
(1,2,3)
(1,2,4)
(1,3,4)
Для простоты предположим, что три атрибута, идущие по порядку слева направо,
имеют имена А, В и С соответственно и каждый из этих атрибутов имеет тип INTEGER. То-
гда приведенные ниже выражения будут иметь указанные значения.
EXISTS V ( V.C > 1 ) : true
EXISTS V ( V.B > 3 ) : false
EXISTS V ( V.A > 1 OR V.C = 4 ) : true
Теперь рассмотрим квантор общности FORALL, для чего вернемся к соответствующе-
му примеру из предыдущего раздела.
FORALL РХ ( РХ.COLOR = COLOR ( 'Red' ) )
Эта формула WFF может быть прочитана следующим образом.
В текущем значении переменной-отношения Р для всех кортежей (скажем, РХ)
значение их атрибута COLOR равно 'Red'.
Обе ссылки на переменную РХ в этом примере связаны.
Подобно тому, как квантор EXISTS был определен как повторение операции OR, кван-
тор существования FORALL определяется как повторяющаяся операция AND (И). Други-
ми словами, если обозначения г, V и p(V) имеют тот же смысл, что и в приведенном вы-
ше определении квантора EXISTS, то формула WFF вида
FORALL V ( р ( V ) )
равносильна следующей формуле WFF.
true AND р ( tl ) AND ... AND p ( tm )
В частности, обратите внимание, что если отношение г пустое, то результатом вы-
числения данного выражения будет значение истина.
В качестве примера рассмотрим отношение R, содержащее те же кортежи, что и
в предыдущем примере. Тогда приведенные ниже выражения будут иметь указан-
ные значения.
FORALL V ( V.A > 1 ) : false
FORALL V ( V.B > 1 ) : true
FORALL V ( V.A = 1 AND V.C > 2 ) : true
250
Часть II. Реляционная модель
Замечание. Квантор FORALL включен в реляционное исчисление просто для удобства.
Он не является необходимым, так как приведенное ниже тождество показывает, что лю-
бая формула WFF, использующая квантор FORALL, всегда может быть заменена эквива-
лентной формулой WFF, использующей квантор EXISTS.
FORALL V ( р ) = NOT EXISTS V ( NOT р )
(Проще говоря, выражение “все значения V, удовлетворяющие формуле р” — это то же
самое, что и выражение “нет таких значений V, которые бы не удовлетворяли формуле р”.)
Например, утверждение (истинное)
Для любого целого х существует целое у, такое, что у > х
равносильно утверждению
Не существует целого х, такого, что не существует целого у, такого, что у > х.
(Иначе говоря, не существует наибольшего целого числа.) Но обычно легче выразить
подобное утверждение в терминах квантора FORALL, чем в терминах квантора EXISTS, с
использованием двойного отрицания. Другими словами, на практике гораздо удобнее
использовать оба квантора.
Еще раз о свободных и связанных переменных
Предположим, что переменная х изменяется на множестве всех целых чисел, и рас-
смотрим следующую формулу WFF.
EXISTS х ( х > 3 )
Связанная переменная х в этой формуле WFF является своего рода фиктивной пере-
менной. Она служит лишь для связи внутренних параметров выражения с внешним кван-
тором. В формуле WFF просто утверждается, что существует целое число (скажем, х),
которое больше 3. Следовательно, заметьте, значение этой формулы WFF осталось бы
полностью неизменным, если бы все экземпляры х были заменены экземплярами некото-
рой другой переменной (скажем, у). Другими словами, формула WFF EXISTS у (у > 3)
семантически идентична формуле, приведенной ранее.
Теперь рассмотрим другую формулу WFF.
EXISTS х ( х > 3 ) AND х < О
Здесь имеется три ссылки на переменную х, обозначающие две различные перемен-
ные. Первые две ссылки связаны и могли бы быть заменены ссылкой на другую пере-
менную у без изменения общего смысла формулы. Третья ссылка на переменную х не
может быть безболезненно изменена. Таким образом, из двух приведенных ниже формул
WFF первая эквивалентна рассмотренной формуле, а вторая — нет.
EXISTS у ( у > 3 ) AND х < О
EXISTS у ( у > 3 ) AND у < О
Кроме того, обратите внимание, что окончательное значение первоначальной форму-
лы WFF не может быть определено, если неизвестно значение свободной переменной х.
В отличие от нее формула WFF, в которой все ссылки на переменные являются связан-
ными, всегда однозначно имеет значение либо истина, либо ложь.
Глава 7. Реляционное исчисление
251
Дополнительная терминология. Формула WFF, в которой все переменные связаны,
называется закрытой формулой WFF (фактически она является высказыванием). От-
крытая формула WFF — это формула, которая не является закрытой, т.е. такая форму-
ла, которая содержит по крайней мере одну ссылку на свободную переменную.
Реляционные операции
Параметр реляционная операция? не совсем уместен в контексте исчисления — бо-
лее подходящим вариантом был бы параметр реляционное определение^ Однако мы
будем использовать именно первый вариант для согласованности с обозначениями в гла-
ве 6. В качестве напоминания приводим следующий синтаксис.
реляционная операция?
::= <прототип кортежа> [ WHERE <логическое выражение> ]
<прототип кортежа>
:: = <выражение кортежа>
Напоминаем также, что следующие синтаксические правила теперь несколько упрощены.
Во-первых, все ссылки на переменные кортежей в параметре <прототип кортежа>
должны быть свободными в пределах значения этого параметра.
Во-вторых, ссылка на переменную кортежа в предложении WHERE может быть сво-
бодной только в случае, если ссылка на эту же переменную (обязательно свобод-
ная) присутствует в соответствующем значении параметра <прототип кортежа>.
Например, следующее выражение является допустимым значением параметра
реляционная операция? (“Получить номера поставщиков, находящихся в Лондоне”).
SX.S# WHERE SX.CITY = 'London'
Здесь ссылка на переменную SX в прототипе кортежа является свободной. Ссылка на
переменную SX в предложении WHERE также является свободной, поскольку ссылка на ту
же переменную (обязательно свободную) имеется и в значении параметра <прототип
кортежа> этого выражения.
Замечание. Далее термин “прототип кортежа” будет употребляться без скобок.
Приведем другой пример (“Получить имена поставщиков детали с номером 'Р2
см. обсуждение квантора существования, которое приводилось выше).
SX.SNAME WHERE EXISTS SPX ( SPX.S# SX.S# AND
SPX.P# = P# ( 'P2' ) )
Здесь все ссылки на переменную SX являются свободными, тогда как все ссылки на
переменную SPX (в предложении WHERE) являются связанными, как и должно быть, по-
скольку на них нет ссылок в прототипе кортежа.
Интуитивно понятно, что результатом выполнения операции, заданной параметром
реляционная операция?, будет отношение, содержащее все возможные значения кор-
тежей, определяемых параметром <прототип кортежа>, для которых результат вычисле-
ния логического выражения, заданного в предложении WHERE параметром логическое
выражениё>, принимает значение истина. (Если предложение WHERE опущено, это экви-
валентно указанию выражения WHERE true.) Сделаем некоторые уточнения.
252
Часть II. Реляционная модель
Прежде всего, прототип кортежа — это список разделенных запятыми элементов
(возможно, заключенный в скобки), каждый элемент которого является либо
ссылкой на атрибут кортежа (который может содержать предложение AS для вве-
дения нового имени атрибута), либо просто именем переменной кортежа3. Тем не
менее отметим следующее.
а) В этом контексте имя переменной кортежа чаще всего является сокращен-
ным обозначением списка разделенных запятыми ссылок на атрибуты, по
одной для каждого атрибута отношения, на котором задана данная пере-
менная кортежа.
б) Ссылка на атрибут кортежа без предложения AS, в принципе, является сокра-
щенным обозначением ссылки с предложением AS, в которой новое имя атри-
бута совпадает со старым.
Следовательно, без потери общности прототип кортежа можно рассматривать как
список, состоящий из разделенных запятыми ссылок на атрибуты в виде
Vi.Ai AS Bj. Обратите внимание, что ссылки Vi- и Aj-e могут повторяться, тогда
как ссылки В j-e должны быть разными.
Пусть VI, V2, ..., Vm будут различными переменными кортежей, упоминаемыми в
прототипе кортежа, и пусть эти переменные будут определены на отношениях rl,
г2, ..., rm соответственно. Примем, что гГ, г2', ..., rm' — это новые отношения,
полученные после переименования атрибутов в предложении AS, и пусть г' — это
декартово произведение отношений г Г, г2', ..., rm'.
Пусть отношение г — это выборка из отношения г', удовлетворяющая формуле
WFF в предложении WHERE.
Замечание. Здесь предполагается, что на предыдущем шаге были также пере-
именованы атрибуты, упоминающиеся в предложении WHERE; в противном
случае функция WFF в предложении WHERE может не иметь смысла. Как мы
увидим в следующем разделе, в вопросе устранения неоднозначности предло-
женный здесь конкретный синтаксис полагается не на это предположение, а
на уточнения.
Конечное значение реляционной операции, заданной параметром реля-
ционное выражение^ определяется как проекция отношения г по всем задан-
ным атрибутам Bj.
В следующем разделе приводится несколько примеров подобных выражений.
7.3. Примеры
Представляем несколько примеров использования реляционного исчисления корте-
жей для формулирования запросов. В качестве упражнения рекомендуется решить эти
задачи средствами реляционной алгебры (для сравнения).
3 Существуют и другие возможности, однако для экономии времени мы ограничимся только
этими двумя.
Глава 7. Реляционное исчисление
253
7.3.1. Определить номера поставщиков из Парижа
со статусом, большим 20
( SX.S#, SX.STATUS )
WHERE SX.CITY = 'Paris' AND
SX.STATUS >20
7.3.2. Найти все такие пары номеров поставщиков,
в которых два поставщика находятся в одном городе
( SX.S# AS SA, SY.S# AS SB )
WHERE SX.CITY = SY.CITY AND
SX.S# < SY.S#
Обратите внимание, что спецификации AS в прототипе кортежа используются для
именования атрибутов результата. Следовательно, эти имена недоступны для использо-
вания в фразе WHERE, и потому второе сравнение в фразе WHERE записано как
SX.S# < SY.S#, а не в виде SA < SB.
7.3.3. Определить имена поставщиков детали
с номером 6Р2’
SX
WHERE EXISTS SPX ( SPX.S# = SX.S# AND
SPX.P# = P# ( 'P2' ) )
Обратите внимание на использование имени переменной кортежа в прототипе корте-
жа. Этот пример является сокращенной записью следующего выражения.
(SX.S#, SX.NAME, SX.STATUS, SX.CITY )
WHERE EXISTS SPX ( SPX.S# = SX.S# AND
SPX.P# = P# ( 'P2' ) )
7.3.4. Определить имена поставщиков по крайней мере
одной красной детали
SX.SNAME
WHERE EXISTS SPX ( SX.S# = SPX.S# AND
EXISTS PX ( PX.P# = SPX.P# AND
PX.COLOR = COLOR ( 'Red' ) ) )
Эквивалентная формула (но записанная в предваренной нормальной форме, в кото-
рой все кванторы помещаются в начало формулы WFF) имеет следующий вид.
SX.SNAME
WHERE EXISTS SPX ( EXISTS PX ( SX.S# = SPX.S# AND
SPX.P# = PX.P# AND
PX.COLOR = COLOR ( 'Red' ) ) )
254
Часть IL Реляционная модель
Предваренная нормальная форма не является более (или менее) правильной по отно-
шению к другим формам, но, немного попрактиковавшись, можно убедиться, что в
большинстве случаев это наиболее естественный метод формулирования запросов Кро-
ме того, она позволяет уменьшить количество используемых скобок, как показано ниже.
Например, рассмотрим следующую формулу WFF.
quantl vblel ( quant2 vble2 ( wff ) )
Здесь каждый из кванторов quantl и quant2 представляет или квантор EXISTS, или
квантор FORALL. При необходимости ее всегда можно однозначно привести к следую-
щему виду.
quantl vblel quant2 vble2 ( wff )
Таким образом, это выражение реляционного исчисления можно переписать (при не-
обходимости) следующим образом.
SX.SNAME
WHERE EXISTS SPX EXISTS PX ( SX.S# = SPX.S# AND
SPX.P# = PX.P# AND
PX.COLOR = COLOR ( 'Red' ) )
Однако для ясности будем продолжать показывать все скобки во всех остальных
примерах.
7.3.5. Найти имена поставщиков по крайней мере одной
детали, поставляемой поставщиком с номером ‘S2’
SX.SNAME
WHERE EXISTS SPX ( EXISTS SPY ( SX.S# = SPX.S# AND
SPX.P# = SPX.P# AND
SPY.S# = S# ( 'S2' ) ) )
7.3.6. Выбрать имена поставщиков всех типов деталей
SX.SNAME WHERE FORALL PX ( EXISTS SPX ( SPX.S# = SX.S# AND
SPX.P# = PX.P# ) )
Равносильное выражение можно записать без использования квантора FORALL.
SX.SNAME WHERE NOT EXISTS PX ( NOT EXISTS SPX
( SPX.S# = SX.S# AND
SPX.P# = PX.P# ) )
7.3.7. Определить имена поставщиков, которые
не поставляют деталь с номером 6Р2’
SX.SNAME WHERE NOT EXISTS SPX
( SPX.S# = SX.S# AND SPX.P# = P# ( 'P2' ) )
Обратите внимание, как просто это решение можно получить из решения приме-
ра 7.3.3.
Глава 7. Реляционное исчисление
255
7.3.8. Определить номера поставщиков по крайней мере
всех типов деталей, поставляемых поставщиком
с номером ‘S2’
SX.S# WHERE FORALL SPX ( SPX.S# * S# ( 'S2' ) OR
EXISTS SPY ( SPY.S# = SX.S# AND
SPY.P# = SPX.P# ) )
Переформулируем запрос в соответствии со следующим выражением: “Получить но-
мера поставщиков (скажем, SX), таких, что для всех поставок SPY поставка осуществля-
ется либо не от поставщика с номером 'S2', либо существует поставка SPY всех типов
деталей, входящих в поставку SPX от поставщика SX”.
Чтобы упростить формулировку таких сложных запросов, как этот, введем другое
синтаксическое соглашение, называемое явной синтаксической формой для оператора
логической импликации. Если р и q — формулы WFF, то выражение логической им-
пликации вида
IF р THEN q END IF
также будет формулой WFF с семантикой, идентичной семантике следующей формулы.
( NOT р ) OR q
Таким образом, приведенное выше выражение может быть переписано так.
SX.S# WHERE FORALL SPX ( IF SPX.S# = S# ( 'S2' ) THEN
EXISTS SPY ( SPY.S# = SX.S# AND
SPY.P# = SPX.P# )
END IF )
Дадим словесную формулировку этого запроса: “Получить номера поставщиков
(скажем, SX), таких, что для всех поставок SPX в случае поставки от поставщика с номе-
ром 'S2' существует поставка SPY всех типов деталей, входящих в поставку SPXzot по-
ставщика SX”.
7.3.9. Получить номера деталей, которые либо весят
более 16 фунтов, либо поставляются поставщиком
с номером ‘S2’, либо и то, и другое
RANGEVAR PU RANGES OVER
( PX.P# WHERE PX.WEIGHT > WEIGHT ( 16.0) ),
( SPX.P# WHERE SPX.S# = S# ( 'S2' ) ) ;
PU.P#
В эквивалентном выражении реляционной алгебры здесь могло бы использоваться
явное объединение.
Ради интереса покажем альтернативную формулировку этого запроса. Однако тот факт,
что каждый номер детали в переменной-отношении SP присутствует и в переменной-
отношении Р, делает вторую формулировку не соответствующей “стилю объединения”.
256
Часть II. Реляционная модель
PX.P# WHERE PX.WEIGHT > WEIGHT ( 16.0 )
OR EXISTS SPX ( SPX.P# = PX.P# AND
SPX.S# = S# ( 'S2' ) )
7.4. Сравнительный анализ реляционного
исчисления и реляционной алгебры
В начале этой главы утверждалось, что реляционная алгебра и реляционное исчисление
в своей основе эквивалентны. Обсудим это утверждение более подробно. Вначале Кодд в
[6.1] показал, что алгебра по крайней мере мощнее исчисления. Он сделал это, придумав
алгоритм, называемый алгоритмом редукции Кодда, с помощью которого любое выраже-
ние исчисления можно преобразовать в семантически эквивалентное выражение алгебры.
Мы не станем приводить здесь этот алгоритм полностью, а ограничимся довольно слож-
ным примером, иллюстрирующим в общих чертах, как он функционирует4.
S S# SNAME STATUS CITY SPJ S# P# J# QTY
S1 Smith 20 London SI Pl JI 200
S2 Jones 10 Paris SI Pl J4 700
S3 Black 30 Paris S2 P3 JI 400
S4 Clark 20 London S2 P3 J2 200
S5 Adams 30 Athens S2 P3 J3 200
S2 P3 J4 500
S2 P3 J5 600
р P# PNAME COLOR WEIGHT CITY S2 P3 J6 400
Р1 Nut Red 12.0 London S2 P3 J7 800
Р2 Bolt Green 17.0 Paris S2 P5 J2 100
РЗ Screw Blue 17.0 Rome S3 P3 JI 200
Р4 Screw Red 14.0 London S3 P4 J2 500
Р5 Cam Blue 12.0 Paris S4 P6 J3 300
Р6 Cog Red 19.0 London S4 P6 J7 300
S5 P2 J2 200
S5 P2 J4 100
J J# JNAME CITY S5 P5 J5 500
Л Sorter Paris S5 P5 J7 100
J2 Display Rome S5 P6 J2 200
J3 OCR Athens S5 Pl J4 100
J4 Console Athens S5 P3 J4 200
J5 RAID London S5 P4 J4 800
J6 EDS Oslo S5 P5 J4 400
J7 Tape London S5 P6 J4 500
Рис. 7.1. База данных поставщиков, деталей и проектов (значения для примера)
4 В действительности алгоритм, представленный в [6.1], содержит небольшую ошибку [7.2].
Более того, определенная в этой статье версия реляционного исчисления не включала аналога опе-
ратора объединения, следовательно, исчисление Кодда значительно менее мощное, чем его алгебра.
Как бы там ни было, утверждение о том, что алгебра и исчисление, включающее аналог операции
объединения, эквивалентны, является истиной, что доказано многими авторами [6.12].
Глава 7. Реляционное исчисление
257
В качестве основы для нашего примера используется не привычная база данных по-
ставщиков и деталей, а ее расширенная версия, упоминавшаяся в упражнениях главы 4 и
в других главах. Для удобства на рис. 7.1 приводится пример возможных значений для
этой базы данных (это копия рис. 4.5 главы 4).
Рассмотрим теперь следующий запрос: “Получить имена поставщиков и названия го-
родов, в которых находятся поставщики деталей по крайней мере для одного проекта в
Афинах ('Athens'), поставляющих по крайней мере 50 штук каждой детали”. Выраже-
ние реляционного исчисления для этого запроса следующее.
( SX.SNAME, SX.CITY ) WHERE EXISTS JX FORALL PX EXISTS SPJX
( JX.CITY = 'Athens' AND
JX.J# = SPJX.J# AND
PX.P# = SPJX.P# AND
SX.S# = SPJX.S# AND
SPJX.QTY > QTY ( 50 ) )
Здесь SX, PX, JX и SPJX — переменные кортежей, получающие свои значения из пере-
менных-отношений S, Р, J и SPJ соответственно. Теперь покажем, как можно вычислить
это выражение, чтобы достичь требуемого результата.
Этап I. Для каждой переменной кортежа выбираем ее область значений (т.е. набор
всех значений для переменной), если это возможно. Выражение “выбираем, если воз-
можно” подразумевает, что существует условие выборки, встроенное в фразу WHERE, ко-
торую можно использовать, чтобы сразу исключить из рассмотрения некоторые корте-
жи. В нашем случае выбираются следующие наборы кортежей.
SX : Все кортежи отношения S 5 кортежей
РХ : Все кортежи отношения Р 6 кортежей
JX : Кортежи отношения J, в которых CITY = 'Athens' 2 кортежа
SPJX ; Кортежи отношения SPJ, в которых CITY >50 24 кортежа
Этап 2. Строим декартово произведение диапазонов, выбранных на первом этапе.
Вот результат.
S# SN STA- TUS CITY P# PN COLOR WEIGHT CITY J# JN CITY S# p# J# QTY
S1 Sm 20 Lon Pl Nt Red 12.0 Lon J3 OR Ath SI Pl JI 200
S1 Sm 20 Lon Pl Nt Red 12.0 Lon J3 OR Ath SI Pl J4 700
(И т.д.) Все произведение содержит 5*6*2*24 = 1 440 кортежей.
Замечание. Для экономии места здесь это отношение полностью не приводится. Мы
также не переименовывали атрибуты (хотя это следовало бы сделать во избежание дву-
смысленности), а просто расположили их в таком порядке, чтобы было видно, какой ат-
рибут S# относится, например, к отношению S, а какой — к отношению SPJ. Это также
сделано для сокращения изложения.
258
Часть II. Реляционная модель
Этап 3. Осуществляем выборку из построенного на этапе 2 произведения в соответ-
ствии с частью “условие соединения” фразы WHERE. В нашем примере эта часть выглядит
следующим образом.
JX.J# = SPJX.J# AND PX.P# = SPJX.P# AND SX.S# =SPJX.S#
Поэтому из произведения исключаются кортежи, для которых значение атрибута S#
из отношения поставщиков не равно значению атрибута S# из отношения поставок, зна-
чение атрибута P# из отношения деталей не равно значению атрибута P# из отношения
поставок, значение атрибута J# из отношения проектов не равно значению атрибута J#
из отношения поставок. Затем получаем подмножество декартова произведения, состоя-
щее (как оказалось) только из десяти кортежей.
S# SN STA- TUS CITY P# PN COLOR WEIGHT CITY J# JN CITY S# P# J# QTY
S1 Sm 20 Lon Pl Nt Red 12.0 Lon J4 Cn Ath SI Pl J4 700
S2 Jo 10 Par P3 Sc Blue 17.0 Rom J3 OR Ath S2 P3 J3 200
S2 Jo 10 Par P3 Sc Blue 17.0 Rom J4 Cn Ath S2 P3 J4 200
S4 Cl 20 Lon P6 Cg Red 19.0 Lon J3 OR Ath S4 P6 J3 300
S5 Ad 30 Ath P2 Bt Green 17.0 Par J4 Cn Ath S5 P2 J4 100
S5 Ad 30 Ath Pl Nt Red 12.0 Lon J4 Cn Ath S5 Pl J4 100
S5 Ad 30 Ath P3 Sc Blue 17.0 Rom J4 Cn Ath S5 P3 J4 200
S5 Ad 30 Ath P4 Sc Red 14.0 Lon J4 Cn Ath S5 P4 J4 800
S5 Ad 30 Ath P5 Cm Blue 12.0 Par J4 Cn Ath S5 P5 J4 400
S5 Ad 30 Ath P6 Cg Red 19.0 Lon J4 Cn Ath S5 P6 J4 500
(Это отношение, конечно, представляет собой эквивалент результата операции со-
единения.)
Этап 4. Применяем кванторы в порядке справа налево следующим образом.
Для квантора EXISTS RX (где RX — переменная кортежа, принимающая значение
на некотором отношении г) проецируем текущий промежуточный результат, что-
бы исключить все атрибуты отношения г.
Для квантора FORALL RX делим текущий промежуточный результат на отно-
шение “выбранной области значений”, соответствующее RX, которое было по-
лучено выше. При выполнении этой операции также будут исключены все ат-
рибуты отношения г.
Замечание. Под делением здесь подразумевается оригинальная операция деления
Кодда (см. аннотацию к [6.3]).
В нашем примере имеем следующие кванторы.
EXISTS JX FORALL РХ EXISTS SPJX
Значит, выполняются следующие операции.
1. (EXISTS SPJX) Проецируем, исключая атрибуты переменной-отношения SPJ
(SPJ.S#, SPJ.P#, SPJ. J# и SPJ.QTY). В результате получаем следующее.
Глава 7. Реляционное исчисление
259
S# SN STATUS CITY P# PN COLOR WEIGHT CITY J# JN CITY
S1 Sm 20 Lon Pl Nt Red 12.0 Lon J4 Cn Ath
S2 Jo 10 Par P3 Sc Blue 17.0 Rom J3 OR Ath
S2 Jo 10 Par P3 Sc Blue 17.0 Rom J4 Cn Ath
S4 Cl 20 Lon P6 Cg Red 19.0 Lon J3 OR Ath
S5 Ad 30 Ath P2 Bt Green 17.0 Par J4 Cn Ath
S5 Ad 30 Ath Pl Nt Red 12.0 Lon J4 Cn Ath
S5 Ad 30 Ath P3 Sc Blue 17.0 Rom J4 Cn Ath
S5 Ad 30 Ath P4 Sc Red 14.0 Lon J4 Cn Ath
S5 Ad 30 Ath P5 Cm Blue 12.0 Par J4 Cn Ath
S5 Ad 30 Ath P6 Cg Red 19.0 Lon J4 Cn Ath
2. (FORALL PX) Делим полученный результат на отношение Р. В результате имеем сле-
дующее.
S# SN STATUS CITY J# JNAME CITY
S5 Adams 30 Athens J4 Console Athens
(Теперь у нас есть место, чтобы показать отношение полностью, без сокращений.)
1. (EXISTS JX) Проецируем, исключая атрибуты отношения J (J. J#, J.NAME и J.CITY).
В результате получаем следующее.
S# SN STATUS CITY
S5 Adams 30 Athens
Этап 5. Проецируем результат этапа 4 в соответствии со спецификациями в прото-
типе кортежа. В нашем примере прототип кортежа имеет следующий вид.
(SX.SNAME, SX.CITY)
Значит, конечный результат вычислений будет таков.
SNAME CITY
Adams Athens
Из сказанного выше следует, что начальное выражение исчисления семантически эк-
вивалентно определенному вложенному алгебраическому выражению, и, если быть бо-
лее точным, это проекция от проекции результата деления проекции выборки из произ-
ведения четырех выборок (!).
Этим мы завершаем обсуждение примера. Конечно, можно намного улучшить ис-
пользуемый алгоритм (глава 17, в частности аннотация к [17.5]). И хотя многие подроб-
ности в пояснениях были опущены, этот пример вполне адекватно отражает общую идею
работы алгоритма редукции.
Кстати, теперь можно объяснить одну из причин (и не только одну) определения
Коддом ровно восьми алгебраических операторов. Эти восемь реляционных операторов
образуют удобный целевой язык как средство возможной реализации реляционного ис-
числения. Другими словами, для заданного языка, построенного на основе реляционного
исчисления (подобно языку QUEL), один из возможных подходов реализации заключа-
260
Часть II. Реляционная модель
ется в том, что организуется получение запроса в том виде, в каком он предоставляется
пользователем. По существу, он будет являться просто выражением реляционного ис-
числения, к которому затем можно будет применить определенный алгоритм редукции,
чтобы получить эквивалентное алгебраическое выражение. Это алгебраическое выраже-
ние, конечно, будет включать набор алгебраических операций, которые по определению
реализуемы по самой своей природе. (Следующий этап состоит в оптимизации получен-
ного алгебраического выражения, о чем речь пойдет в главе 17.)
Также следует отметить, что восемь алгебраических операторов Кодда являются мерой
оценки выразительной силы любого языка баз данных. Это обстоятельство уже кратко
упоминалось в главе 6, в конце раздела 6.6, а сейчас пришло время обсудить его подробнее.
Некоторый язык принято называть реляционно полным, если он по своим возмож-
ностям по крайней мере не уступает реляционному исчислению. Иначе говоря, любое
отношение, которое можно определить с помощью реляционного исчисления, можно
определить и с помощью некоторого выражения рассматриваемого языка [6.1]. (В гла-
ве 6 отмечалось, что “реляционно полный” значит “не уступающий по возможностям ре-
ляционной алгебре”, а не исчислению, но, как читатель вскоре убедится, это одно и то
же. По сути, из самого существования алгоритма редукции Кодда немедленно следует,
что реляционная алгебра обладает реляционной полнотой.)
Реляционную полноту можно рассматривать как основную меру выразительной силы
языков баз данных в самом общем случае. В частности, так как реляционное исчисление
и реляционная алгебра обладают реляционной полнотой, они могут служить основой для
проектирования не уступающих им по выразительности языков без необходимости вы-
полнять пересортировку для организации циклов. Это замечание особенно важно, если
язык предназначается для конечных пользователей, хотя оно также существенно, если
язык предназначается для использования прикладными программистами.
Далее, поскольку алгебра обладает реляционной полнотой, для доказательства
того, что некоторый язык L также обладает реляционной полнотой, достаточно по-
казать, что в языке L есть аналоги всех восьми алгебраических операций (на самом
деле достаточно показать, что в нем есть аналоги пяти примитивных операций) и
что операндами любой операции языка L могут быть любые выражения этого языка.
Язык SQL — это пример языка, реляционную полноту которого можно доказать ука-
занным способом (упр. 7.9). Язык QUEL — еще один пример подобного языка. В
действительности на практике часто проще показать то, что в языке есть эквивален-
ты операций реляционной алгебры, чем то, что в нем существуют эквиваленты вы-
ражений реляционного исчисления. Именно поэтому реляционная полнота обычно
определяется в терминах алгебраических выражений, а не в терминах выражений
реляционного исчисления.
При этом важно понимать, что реляционная полнота необязательно влечет за собой
полноту какого-либо другого рода. Например, желательно, чтобы язык также обеспечи-
вал “вычислительную полноту”, т.е. позволял вычислять результаты всех вычислимых
функций. Заметим, что согласно нашему определению исчисление не обладает полнотой
такого рода, хотя на практике подобная полнота для языка баз данных весьма желатель-
на. Вычислительная полнота — это один из факторов, побудивших ввести в реляцион-
ную алгебру операции EXTEND и SUMMARIZE (обсуждавшиеся в главе 6). В следующем раз-
деле описано, как можно расширить реляционное исчисление, чтобы обеспечить в нем
наличие аналогов этих операций.
Глава 7. Реляционное исчисление
261
Вернемся к вопросу эквивалентности алгебры и исчисления. Мы на примере по-
казали, что любое выражение исчисления можно преобразовать в его некоторый ал-
гебраический эквивалент, а значит, алгебра по крайней мере не уступает по своей
мощности исчислению. Можно показать обратное: каждое выражение реляционной
алгебры можно преобразовать в эквивалентное выражение реляционного исчисле-
ния, а значит, исчисление по крайней мере не уступает по своей мощности реляци-
онной алгебре. Полное доказательство этих утверждений можно найти, например, в
книге Ульмана (Ullman) [7.13]. Отсюда следует, что реляционная алгебра и реляци-
онное исчисление эквивалентны.
7.5. Вычислительные возможности
Несмотря на то что ранее об этом не упоминалось, в определенном нами реляци-
онном исчислении уже есть аналоги алгебраических операторов EXTEND и SUMMARIZE,
и вот почему.
Одной из допустимых форм прототипа кортежа является параметр «операция
выборки кортежа>, компонентами которого могут быть произвольные подпара-
метры <выражение>.
В параметре Логическое выражение> сравниваемыми элементами могут быть
произвольные подпараметры <выражение>.
Первым или единственным аргументом в параметре <вызов обобщающей функции>
является подпараметр реляционная операция>.
Замечание. Здесь мы ссылаемся на полное определение языка Tutorial D, которое
приводится в [3.3].
Мы считаем, что не стоит приводить здесь все имеющие место синтаксические и се-
мантические подробности; достаточно лишь рассмотреть несколько типичных примеров
(сами примеры также несколько упрощены).
7.5.1. Определить номера и вес в граммах всех типов
деталей, вес которых превышает 10 000 г
( РХ.Р#, РХ.WEIGHT * 454 AS GMWT )
WHERE PX.WEIGHT * 454 > WEIGHT ( 10000 )
Обратите внимание, что спецификация AS GMWT в прототипе кортежа дает имя
соответствующему атрибуту результата. Поэтому такое имя недоступно для ис-
пользования в предложении WHERE и выражение РХ.WEIGHT * 454 должно быть ука-
зано в двух местах.
7.5.2. Выбрать сведения обо всех поставщиках, добавив
для каждого из них литеральное значение
‘Поставщик’
( SX, 'Поставщик' AS TAG )
262
Часть II Реляционная модель
7.5.3. Выбрать сведения о каждой поставке и указать
полные данные о входящих в нее типах деталей
и общий вес поставки
( SPX, PX.WEIGHT * SPX.QTY ) AS SHIPWT WHERE PX.P# = SPX.P#
7.5.4. Для каждой детали выбрать номер и общий объем
поставки в штуках
( PX.P#, SUM ( SPX WHERE SPX.P# = PX.P#, QTY ) AS TOTQTY )
7.5.5. Определить общее количество поставляемых
деталей
SUM (SPX, QTY ) AS GRANDTOTAL )
7.5.6. Для каждого поставщика указать номер и общий
объем поставки в штуках
( SX.S#, COUNT ( SPX WHERE SPX.S# = SX.S# ) AS #_OF_PARTS )
7.5.7. Указать названия городов, в которых находится
более пяти красных деталей
RANGEVAR PY RANGES OVER Р;
PX.CITY
WHERE COUNT ( PY WHERE PY.CITY = PX.CITY
AND PY.COLOR = COLOR ( 'Red' ) ) > 5
7.6. Исчисление доменов
Как указывалось в разделе 7.1, реляционное исчисление, ориентированное на домены
(или исчисление доменов), отличается от исчисления кортежей тем, что в нем вместо пе-
ременных кортежей используются переменные доменов, т.е. переменные, принимающие
свои значения в пределах домена, а не отношения. В этой книге мы лишь кратко рас-
смотрим исчисление доменов. С практической точки зрения большинство очевидных
различий между версиями исчисления доменов и исчисления кортежей основано на том,
что версия для доменов поддерживает дополнительную форму параметра Логическое
выражение^ который мы будем называть условием принадлежности. В общем виде ус-
ловие принадлежности можно записать так.
R ( пара, пара, ... )
Здесь R— имя переменной-отношения, а каждый параметр пара имеет вид A:v, где
А— атрибут переменной-отношения R, a v — имя переменной домена или литерал. Про-
Глава 7. Реляционное исчисление
263
верка условия дает значение истина тогда и только тогда, когда в текущем значении пе-
ременной-отношения R существует кортеж, имеющий указанные значения для указанных
атрибутов. Например, рассмотрим результат вычисления следующего выражения.
SP ( S#:S#('S1'), Р#:Р#('Р1') )
Он будет иметь значение истина тогда и только тогда, когда в переменной-
отношении SP будет существовать кортеж со значением атрибута S#, равным ' S1', и зна-
чением атрибута Р#, равным ' Р1'. Аналогично условие принадлежности
SP ( S#:SX, Р#:РХ )
принимает значение истина тогда и только тогда, когда в переменной-отношении SP су-
ществует кортеж со значением атрибута S#, эквивалентным текущему значению пере-
менной домена SX (какому бы то ни было), и значением атрибута Р#, эквивалентным те-
кущему значению переменной домена РХ (опять же, какому бы то ни было).
Далее будем подразумевать существование следующих переменных доменов.
Домен Переменная домена
S# SX, SY, ...
P# PX, PY, ...
NAME NAMEX, NAMEY, ...
COLOR COLORX, COLORY, ...
WEIGHT WEIGHTX, WEIGHTY, ..
QTY QTYX, QTYY, ...
CHAR CITYX, CITYY, ...
INTEGER STATUSX, STATUSY, ..
Ниже приведено несколько примеров выражений исчисления доменов.
SX
SX WHERE S ( S#:SX )
SX WHERE S ( S#:SX, CITY:'London' )
( SX, CITYX ) WHERE S { S#:SX, CITY:'London' )
AND SP ( S#:SX, P#: P# ( 'P2' ) )
( SX, PX ) WHERE S (S#:SX, CITY:CITYX )
AND P ( P#:PX, CITY:CITYY )
AND CITYX * CITYY
Если говорить нестрого, первое выражение означает множество всех номеров по-
ставщиков, второе — множество всех номеров поставщиков в переменной-
отношении S, третье — подмножество номеров поставщиков из Лондона. Следую-
щее выражение — это выраженный в терминах исчисления доменов запрос
“Определить номера поставщиков и названия городов, в которых находятся постав-
щики детали с номером ' Р2'” (вспомните, что в этом запросе, выраженном в терми-
нах исчисления кортежей, использовался квантор существования). И последнее вы-
264
Часть II. Реляционная модель
ражение — это представленный в терминах исчисления доменов запрос “Найти все
такие пары номеров поставщиков и номеров деталей, для которых поставщик и де-
таль находятся в одном городе”.
Ниже приведено несколько примеров из числа рассмотренных в разделе 7.3, но на
этот раз выраженных в терминах исчисления доменов (часть из них несколько изменена).
7.6.1. Выбрать номера поставщиков из Парижа
со статусом, большим 20
SX WHERE EXISTS STATUSX
(STATUSX > 20 AND
S ( S#:SX, STATUS:STATUSX, CITY:'Paris' ) )
Этот пример несколько неуклюж по сравнению с его аналогом, выраженным в тер-
минах исчисления кортежей. Обратите внимание, что все еще требуется использовать
кванторы. С другой стороны, существуют ситуации, когда верно обратное утверждение,
что видно из более сложных примеров, приведенных ниже.
7.6.2. Найти все такие пары номеров поставщиков,
в которых два поставщика находятся в одном городе
( SX AS SA, SY AS SB ) WHERE EXSIST CITYZ
( S ( S#:SX, CITY:CITYZ) AND
S ( S#:SY, CITY:CITYZ) AND
SX < SY )
7.6.3. Определить имена поставщиков по крайней мере
одной красной детали
NAMEX WHERE EXISTS SX EXISTS РХ
( S ( S#:SX, SNAME:NAMEX )
AND SP ( S#;SX, P#:PX )
AND P ( P#:PX, COLOR:COLOR('Red') ) )
7.6.4. Определить номера поставщиков всех типов деталей,
поставляемых поставщиком с номером ‘S2’
NAMEX WHERE EXISTS SX EXISTS РХ
( S ( S#:SX, SNAME.-NAMEX )
AND SP ( S#:SX, P#:PX )
AND SP ( S#;S#('S2'), P#:PX ) )
7.6.5. Выбрать имена поставщиков всех типов деталей
NAMEX WHERE EXISTS SX ( S ( S#:SX, SNAME:NAMEX )
AND FORALL PX ( IF P ( P#:PX )
THEN SP ( S#:SX, P#:PX )
END IF )
Глава 7. Реляционное исчисление
265
7.6.6. Определить имена поставщиков, которые
не поставляют деталь с номером Т2’
NAMEX WHERE EXISTS SX ( S ( S#:SX, SNAMEtNAMEX )
AND NOT SP (S#:SX, P#:P#('P2') ) )
7.6.7. Определить номера поставщиков всех типов деталей,
поставляемых поставщиком с номером ‘S2’
SX WHERE FORALL PX ( IF SP ( S#:S#('S2'), P#:PX )
THEN SP ( S#:SX, P#:PX )
END IF )
7.6.8. Получить номера деталей, которые либо весят
более 16 фунтов, либо поставляются поставщиком
с номером ‘S2’, либо и то, и другое
PX WHERE EXISTS WEIGHTX
{ Р ( Р#:РХ, WEIGHT-.WEIGHTX )
AND WEIGHTX > WEIGHT ( 16.0 ) )
OR SP ( S#:S#('S2'), P#:PX )
Исчисление доменов, как и исчисление кортежей, формально эквивалентно реляци-
онной алгебре (т.е. оно реляционно полно). Для доказательства можно сослаться, напри-
мер, на статью Ульмана (Ullman) [7.13].
7.7. Средства языка SQL
Как уже говорилось в разделе 7.4, в основу реляционного языка могут быть поло-
жены как реляционная алгебра, так и реляционное исчисление. Что же положено в ос-
нову языка SQL? К сожалению, ответом будет “частично и то, и другое, а частично ни
то, ни другое..”. Когда язык SQL только разрабатывался, предполагалось что он бу-
дет отличаться как от реляционной алгебры, так и от реляционного исчисления [4.8].
Действительно, именно этим мотивировалось введение в язык конструкции IN
<подзапрос> (см. пример 7.7.10, приведенный ниже). Однако со временем выяснилось,
что язык SQL нуждается в определенных средствах как реляционной алгебры, так и
исчисления, поэтому он был расширен для включения этих функций5. На сегодняшний
день ситуация складывается таким образом, что язык SQL в чем-то похож на реляци-
онную алгебру, в чем-то на реляционное исчисление, а в чем-то отличается от них
5 Вследствие этого, как отмечается в аннотации к [4.18], конструкцию IN <подзапрос> можно
полностью удалить из языка без потери его функциональности! В этом есть некоторая ирония, по-
скольку благодаря именно такой конструкции в названии данного языка, в переводе означающего "язык
структурированных запросов" (Structured Query Language), появилось слово "структурированных"
(Structured). В действительности именно эта конструкция способствовала тому, что язык SQL ока-
зался на первом месте, оставив позади и реляционную алгебру, и реляционное исчисление.
266
Часть II. Реляционная модель
обоих. Таким положением дел объясняется, почему в главе 6 мы отложили обсуждение
средств обработки данных языка SQL до настоящей главы. (Мы предоставляем чита-
телю в качестве упражнения определить, какая часть языка SQL основана на алгебре,
какая на исчислении, а какая ни на том, ни на другом.)
Запросы в языке SQL формулируются в виде табличных выражений, которые
потенциально могут иметь очень высокую степень сложности. Здесь мы не будем
углубляться во все эти сложности, а просто рассмотрим несколько примеров, рас-
крывающих наиболее важные моменты. В качестве основы для примеров взяты оп-
ределения SQL-таблиц для базы данных поставщиков и деталей, представленные в
главе 4 (см. рис. 4.1). Напоминаем, что в SQL-версии этой базы данных нет типов
данных, определяемых пользователем, и все столбцы определены в терминах встро-
енных типов языка SQL.
Замечание. Более полная и более формальная интерпретация всех SQL-выражений в
целом и табличных выражений в частности приводится в приложении А.
7.7.1. Указать цвета деталей и названия городов,
в которых находятся детали “не из Парижа”
с весом, превышающим 10 фунтов
SELECT РХ.COLOR, PX.CITY
FROM Р AS РХ
WHERE PX.CITY <> 'Paris'
AND PX.WEIGHT > 10.0;
Необходимо отметить следующее.
1. Прежде всего обратите внимание на использование в этом примере символа “<>”
(не равно). Типичные скалярные операторы сравнения записываются в языке SQL
следующим образом: =, о, <, >, <= и >=.
2. Обратите также внимание на спецификацию Р AS РХ в предложении WHERE. Этой
спецификацией вводится новая переменная кортежа РХ (в стиле исчисления корте-
жей), областью значений которой является текущее значение таблицы Р. Областью
применения такого определения, нестрого говоря, является выражение, в котором
она появляется.
Замечание. В языке SQL обозначение РХ называется относительным именем.
3. В языке SQL также допускается неявное обращение к переменным кортежей, что
позволяет переписать наш запрос в следующем виде.
SELECT Р.COLOR, P.CITY
FROM Р
WHERE P.CITY о 'Paris'
AND P.WEIGHT > 10.0 ;
Основная идея состоит в том, чтобы разрешить использование имени таблицы
для обозначения неявной переменной кортежа, областью значений которой явля-
ется рассматриваемая таблица (разумеется, при условии однозначности результа-
та). Например, предложение FROM Р в нашем примере можно рассматривать как
Глава 7. Реляционное исчисление
267
сокращенную запись предложения FROM Р AS Р. Другими словами, необходимо
четко понимать, что Р в выражении Р.COLOR в предложениях WHERE и SELECT обо-
значает не саму таблицу Р, а переменную кортежа Р, которая принимает свои
значения из одноименной таблицы.
4. Между прочим, в этом примере можно было бы прекрасно обойтись и без специ-
фикаторов (Р.).
SELECT COLOR, CITY
FROM P
WHERE CITY <> 'Paris'
AND WEIGHT > 10.0 ;
Согласно общему правилу языка SQL неуточненные имена допускаются во всех
случаях, когда это не вызывает неоднозначности. Однако в наших примерах спе-
цификаторы будут использоваться и в тех случаях, когда формально они будут из-
лишни. К сожалению, в определенных контекстах явно требуется, чтобы имена
столбцов были не уточнены! Например, это требуется в предложении ORDER BY
(см. следующий пример).
5. В интерактивных SQL-запросах может также использоваться предложение
ORDER BY, уже упоминавшееся в главе 4 в связи с объявлением DECLARE CURSOR.
SELECT Р.COLOR, P.CITY
FROM P
WHERE P.CITY <> 'Paris'
AND P.WEIGHT > 10.0 ;
ORDER BY CITY DESC ;
6. Напоминаем, что допускается использование сокращения SELECT *, о котором
упоминалось в главе 4.
SELECT *
FROM Р
WHERE P.CITY <> 'Paris'
AND P.WEIGHT > 10.0 ;
Символ в выражении SELECT * заменяет список имен всех столбцов таблицы
(или таблиц), указанной в предложении FROM. В этом списке имена столбцов идут в
том порядке, в котором они расположены в соответствующей таблице (или табли-
цах). Следует отметить, что такую сокращенную запись особенно удобно исполь-
зовать в интерактивных запросах, поскольку при этом уменьшается количество на-
жатий клавиш. Однако существует скрытая опасность при использовании этой кон-
струкции во внедренных SQL-операторах (т.е. в операторах языка SQL, внедрен-
ных в программу на другом языке), поскольку в подобных случаях символ мо-
жет иметь совсем другое значение (например, когда столбец добавляется в таблицу
или удаляется из нее с помощью оператора ALTER TABLE).
7. {Более важная информация по сравнению с приведенной в предыдущих пунктах!')
Обратите внимание, что для используемого нами в примерах набора данных этот
запрос будет возвращать четыре строки, а не две, несмотря на то что три из них
268
Часть II. Реляционная модель
будут совершенно идентичны. Язык SQL не предполагает удаления излишних дуб-
лирующихся строк из результата оператора SELECT, пока пользователь явно не по-
требует этого с помощью ключевого слова DISTINCT, как показано ниже.
SELECT DISTINCT Р.COLOR, P.CITY
FROM P
WHERE P.CITY <> 'Paris'
AND P.WEIGHT > 10.0 ;
Данный вариант запроса будет возвращать уже две строки, а не четыре.
Из всего вышесказанного следует, что фундаментальным объектом данных в язы-
ке SQL является не отношение, а, скорее, таблица. SQL-таблицы содержат не
множества, а мультимножества строк (в мультимножествах допускаются повто-
рения элементов). Таким образом, в языке SQL нарушается информационный
принцип (см. раздел 3.2 главы 3). Одно из следствий этого факта состоит в том, что
основные SQL-операторы являются не истинными реляционными операторами, а
их мультимножественными аналогами. Другим следствием является то, что следст-
вия и теоремы, выполняющиеся в реляционной модели (например, о преобразова-
нии выражений [5.6]), необязательно выполняются в языке SQL.
7.7.2. Для всех деталей указать номер и вес в граммах
SELECT Р.Р#, Р.WEIGHT * 454 AS GMWT
FROM P ;
Спецификация AS GMWT вводит соответствующее имя результирующего столбца. Та-
ким образом, два столбца результирующей таблицы будут называться P# и GMWT. Если бы
спецификация AS GMWT была опущена, то соответствующий столбец был бы фактически
безымянным. Отметим, что хотя в подобных случаях правила языка SQL в действитель-
ности не требуют от пользователя указания имени результирующего столбца, в наших
примерах будем их задавать всегда.
7.7.3. Выбрать информацию обо всех парах поставщиков
и деталей, находящихся в одном городе
В языке SQL существует несколько способов формулирования этого запроса. Приве-
дем три самых простых.
1. SELECT S.*, Р.Р#, Р.PNAME, Р.COLOR, Р.WEIGHT
FROM S, Р
WHERE S.CITY = P.CITY ;
2. S JOIN P USING CITY ;
3. S NATURAL JOIN P ;
Результатом в каждом случае будет естественное соединение таблиц S и Р (по атри-
буту города CITY).
Глава 7. Реляционное исчисление
269
Первая формулировка заслуживает более подробного обсуждения. Именно она одна
из трех предложенных вариантов является допустимой в первоначальной версии языка
SQL (явная операция JOIN была добавлена в стандарт SQL/92). Концептуально можно
рассматривать реализацию этой версии запроса следующим образом.
Во-первых, после выполнения предложения FROM мы получаем декартово произ-
ведение S TIMES Р. (Строго говоря, перед вычислением произведения следовало
бы позаботиться о переименовании столбцов. Для простоты мы этого не делаем.
Напоминаем также, что, как следует из упр. 6.12 главы 6, “декартово произведе-
ние” для единственной таблицы Т можно рассматривать как саму таблицу Т.)
Во-вторых, после выполнения предложения WHERE мы получаем выборку из этого
произведения, в которой два значения атрибута CITY в каждой строке равны
(иначе говоря, выполнено соединение таблиц поставщиков и деталей по эквива-
лентности их атрибутов городов).
В-третьих, после выполнения предложения SELECT мы получаем проекцию вы-
борки по столбцам, указанным в предложении SELECT. Конечным результатом бу-
дет естественное соединение указанных таблиц.
Следовательно, нестрого говоря, предложение FROM в языке SQL соответствует декар-
тову произведению, предложение WHERE — операции выборки, а совместное применение
предложений SELECT-FROM-WHERE — проекции выборки произведения. Продолжение об-
суждения можно найти в приложении А.
7.7.4. Найти все пары названий городов, таких,
что поставщик из первого города поставляет
деталь, находящуюся во втором городе
SELECT DISTINCT S.CITY AS SCITY, P.CITY AS PCITY
FROM S JOIN SP USING S# JOIN P USING P# ;
Обратите внимание, что приведенный ниже оператор будет некорректным (поскольку
он включает столбец CITY как присоединяемый столбец во втором соединении).
SELECT DISTINCT S.CITY AS SCITY, P.CITY AS PCITY
FROM S NATURAL JOIN SP NATURAL JOIN P ;
7.7.5. Выбрать все пары номеров поставщиков, таких,
что оба поставщика в каждой паре находятся
в одном городе
SELECT A.S# AS SA, B.S# AS SB
FROM S AS A, S AS В
WHERE A.CITY = B.CITY AND A.S# < B.S# ;
В этом примере требуется явно указывать переменные кортежей. Также следует от-
метить, что вводимые имена столбцов SA и SB относятся к столбцам результирующей
таблицы, и потому не могут использоваться в предложении WHERE.
270
Часть II. Реляционная модель
7.7.6. Определить общее количество поставщиков
SELECT COUNT(*) AS N
FROM S ;
Результатом будет таблица с одним столбцом, которому присвоено имя N, и одной
строкой, содержащей значение 5. Язык SQL поддерживает типичный набор обобщаю-
щих функций: COUNT, SUM, AVG, МАХ и MIN. Однако имеется несколько специфических для
языка SQL особенностей, которые пользователю необходимо знать.
В общем случае аргументу обобщающей функции может предшествовать необяза-
тельное ключевое слово DISTINCT (например, SUM (DISTINCT QTY)), указывающее,
что перед применением этой функции дублирующиеся строки должны быть уда-
лены. Для функций МАХ и MIN ключевое слово DISTINCT является излишним и не
вызывает никакого действия.
Специальная обобщающая функция COUNT(*) не допускает использования ключе-
вого слова DISTINCT и предназначена для подсчета всех строк в таблице без пред-
варительного удаления дублирующихся строк.
Любые NULL-значения в столбце-аргументе (глава 18) удаляются перед примене-
нием обобщающей функции в зависимости от того, указано ли ключевое слово
DISTINCT, кроме случая использования обобщающей функции COUNT(*), когда
NULL-значения обрабатываются так же, как обычные значения.
Если аргумент представляет собой пустое множество, обобщающая функция
COUNT возвращает значение нуль, а все другие операторы возвращают NULL-
значение (неопределенное значение). (В [3.3] показано, что подобное пове-
дение операторов некорректно, однако язык SQL определяет их именно та-
ким образом.)
7.7.7. Определить в поставках максимальное
и минимальное количество деталей с номером Т2’
SELECT МАХ ( SP.QTY ) AS MAXQ, MIN ( SP.QTY ) AS MINQ
FROM SP
WHERE SP.P# = 'P2' ;
Здесь оба предложения, FROM и WHERE, фактически предоставляют часть аргументов
для двух обобщающих функций. Следовательно, по логике вещей они должны были
бы записываться в скобках, заключающих аргументы. Тем не менее данный запрос
действительно должен записываться именно так, как показано выше. Этот неортодок-
сальный подход к синтаксису оказывает существенное отрицательное влияние на
структуру, удобство использования и ортогональность6 языка SQL. Например, одно из
следствий состоит в том, что обобщающие функции не могут быть вложенными, в ре-
6 Ортогональность здесь означает независимость. Язык является ортогональным, если неза-
висимые понятия сохраняют в нем свою независимость и не смешиваются между собой непо-
нятным образом. Ортогональность весьма желательна, поскольку чем менее ортогонален язык,
тем он более сложен и, как это ни парадоксально, менее мощен.
Глава 7. Реляционное исчисление
271
зультате чего такой запрос, как “Получить среднее итоговое количество деталей”,
нельзя сформулировать без громоздких выражений. Если быть точным, то следующий
запрос "'НЕКОРРЕКТЕН***.
SELECT AVG (SUM (SP.QTY) ) — Внимание! Это ошибка!
FROM SP;
Вместо этого данный запрос следовало бы сформулировать, например, так.
SELECT AVG ( X )
FROM ( SELECT SUM ( SP.QTY ) AS X
FROM SP
GROUP BY SP.S# ) AS POINTLESS ;
Назначение предложения GROUP BY разъясняется в следующем примере, а использо-
вание вложенных подзапросов — несколько ниже. Стоит отметить, что возможность
вложения подзапросов в предложение WHERE, как было сделано в этом примере, появи-
лась только в стандарте SQL/92 и еще не используется достаточно широко.
Замечание. Спецификация AS POINTLESS бессмысленна, однако ее наличия требуют
синтаксические правила языка SQL (приложение А).
7.7.8. Для каждой поставляемой детали указать номер
и общий объем поставки в штуках
SELECT SP.P#, SUM ( SP.QTY ) AS TOTQTY
FROM SP
GROUP BY SP.P# ;
В языке SQL это выражение является аналогом такого выражения реляционной алгебры.
SUMMARIZE SP PER SP { P# } ADD SUM ( QTY ) AS TOTQTY
Оно также является аналогом следующего выражения реляционного исчисления
кортежей.
( SPX.P#, SUM ( SPY WHERE SPY.P# = SPX.P#, QTY ) AS TOTQTY )
В частности, стоит отметить, что если в запросе указано предложение GROUP BY, то
выражения в предложении SELECT должны быть однозначными для заданной группы.
Вот альтернативная, а также более предпочтительная формулировка того же запроса.
SELECT Р.Р#, ( SELECT SUM ( SP.QTY )
FROM SP
WHERE SP.P# = P.P# ) AS TOTQTY
FROM P ;
Возможность использования вложенных подзапросов для представления скалярных
элементов (например, в предложении SELECT, как здесь) была добавлена в стандарт
SQL/92 и является важнейшим усовершенствованием по сравнению с первоначальным
вариантом языка SQL. В рассматриваемом примере это предоставляет возможность
генерировать результат, который включает строки для деталей, не поставляемых со-
272
Часть II. Реляционная модель
всем, а предыдущая формулировка (использующая предложение GROUP BY) этого не
позволяла. (Однако значение TOTQTY для таких деталей будет, к сожалению, представ-
лено как NULL-значение, а не нуль.)
7.7.9. Указать номера всех типов деталей, поставляемых
более чем одним поставщиком
SELECT SP.P#
FROM SP
GROUP BY SP.P#
HAVING COUNT ( SP.S# ) > 1 ;
Предложение HAVING в отношении групп является тем же, что и предложение WHERE для
обычных строк. Другими словами, предложение HAVING используется для исключения
групп аналогично тому, как предложение WHERE используется для исключения отдельных
строк. Выражение в предложении HAVING должно быть однозначным для заданной группы.
7.7.10. Определить имена поставщиков детали
с номером ‘Р2’
SELECT DISTINCT S.SNAME
FROM S
WHERE S.S# IN
( SELECT SP.S#
FROM SP
WHERE SP.P# = 'P2' ) ;
Пояснения. В этом примере в предложении WHERE используется так называемый под-
запрос. Проще говоря, подзапрос — это выражение из предложений SELECT-FROM-
WHERE-GROUP BY-HAVING, которое вложено в другое такое же выражение. Подзапрос чаще
всего используется для представления множества значений, поиск которых осуществля-
ется с помощью предложения IN условие, что и представлено в данном в примере. Сис-
тема вычисляет запрос в целом, предварительно вычислив указанный подзапрос (по
крайней мере, концептуально). Подзапрос в данном примере возвращает множество но-
меров поставщиков детали с номером 'Р2': {SI, S2, S3, S4}. Таким образом, первона-
чальное выражение эквивалентно следующему, более простому.
SELECT DISTINCT S.SNAME
FROM S
WHERE S.S# IN ( 'SI', 'S2', 'S3', 'S4' ) ;
Стоит отметить, что первоначальную задачу — “Получить имена поставщиков детали
с номером 'Р2'”— можно равносильно выразить с помощью операции соединения, на-
пример, так.
SELECT DISTINCT S.SNAME
FROM S, SP
WHERE S.S# = SP.S#
AND SP.P# = 'P2' ;
Глава 7. Реляционное исчисление
273
7.7.11. Определить имена поставщиков по крайней мере
одной красной детали
SELECT DISTINCT S.SNAME
FROM S
WHERE S.S# IN
( SELECT SP.S#
FROM SP
WHERE SP.P# = IN
( SELECT P.P#
FROM P
WHERE P.COLOR = 'Red' ) ) ;
Подзапросы могут иметь произвольную глубину вложения.
Упражнение. Приведите эквивалентную формулировку этого запроса с использова-
нием операции соединения.
7.7.12. Указать номера поставщиков, статус которых
меньше текущего максимального статуса
в таблице S
SELECT S.S#
FROM S
WHERE S.STATUS <
( SELECT MAX ( S.STATUS )
FROM S )
В этом примере используются две отдельные неявные переменные кортежей, обозна-
ченные одним и тем же именем S и изменяющиеся на таблице S.
7.7.13. Указать имена поставщиков детали с номером ‘Р2’
Замечание. Этот пример повторяет пример 7.7.10. Ниже приводится другое решение
для того, чтобы представить еще одно средство языка SQL.
SELECT DISTINCT S.SNAME
FROM S
WHERE EXISTS
( SELECT *
FROM SP
WHERE SP.S# = S.S#
AND SP.P# = 'P2'
Пояснение. SQL-выражение EXISTS (SELECT ... FROM ...) будет иметь значение исти-
на тогда и только тогда, когда результат вычисления выражения SELECT ... FROM
будет непустым. Другими словами, в языке SQL функция EXISTS соответствует квантору
существования реляционного исчисления [18.6].
274
Часть II. Реляционная модель
Замечание. В этом SQL-примере ссылка на подзапрос представлена как ссылка на
относительный подзапрос, поскольку в данном подзапросе содержится ссылка на пере-
менную кортежа, а именно — на неявную переменную кортежа S, которая определена во
внешнем запросе. Другим примером относительного подзапроса служит пример 7.7.8.
7.7.14. Выбрать имена поставщиков, которые
не поставляют деталь с номером ‘Р2’
SELECT DISTINCT S.SNAME
FROM S
WHERE NOT EXISTS
( SELECT *
FROM SP
WHERE SP.S# = S.S#
AND SP.P# = 'P2' ) ;
Этот же запрос можно представить в альтернативной формулировке.
SELECT DISTINCT S.SNAME
FROM S
WHERE S.S# NOT IN
( SELECT SP.S#
FROM SP
WHERE SP.P# = 'P2' ) ;
7.7.15. Определить имена поставщиков всех типов деталей
SELECT DISTINCT S.SNAME
FROM S
WHERE NOT EXISTS
( SELECT *
FROM P
WHERE NOT EXISTS
( SELECT *
FROM SP
WHERE SP.S# = S.S#
AND SP.P# = P.P# ) ) ;
Язык SQL не включает какой-либо непосредственной поддержки универсального
квантора FORALL; следовательно, запросы типа “ДЛЯ ВСЕХ” обычно выражаются через
отрицание кванторов существования, как в этом примере.
Стоит отметить, что выражения, подобные показанному выше, хотя, на первый
взгляд, и выглядят несколько устрашающе, легко составляются пользователями, знако-
мыми с реляционным исчислением, как отмечается в [7.4]. В альтернативном случае, ес-
ли подобные примеры все еще кажутся вам слишком сложными, существует несколько
“обходных” путей, позволяющих избежать использования негативных кванторов. В на-
шем случае, например, можно записать запрос следующим образом.
SELECT DISTINCT S.SNAME
FROM S
Глава 7. Реляционное исчисление
275
WHERE ( SELECT COUNT ( SP.P# )
FROM SP
WHERE SP.S# = S.S# ) =
( SELECT COUNT ( P.P# )
FROM P ) ;
(Расшифровка: “Получить имена поставщиков, для которых количество поставляе-
мых деталей равно количеству всех деталей”.) Однако обратите внимание на следующие
обстоятельства.
Во-первых, в отличие от формулировки с выражением NOT EXISTS, в последней
формулировке предполагается, что в отношении SP нет номеров деталей, которые
не содержатся в отношении Р. Другими словами, эти две формулировки эквива-
лентны (а вторая будет верной) только в случае соблюдения определенного огра-
ничения целостности (подробности приводятся в следующей главе).
Во-вторых, метод, примененный во второй формулировке для сравнения двух ко-
личеств (подзапросы, расположенные по обе стороны знака равенства), изначаль-
но не поддерживался в языке SQL и был добавлен только в стандарте SQL/92. Он
все еще не поддерживается во многих продуктах.
В-третьих, на самом деле предпочтительнее было бы сравнивать две таблицы (см.
обсуждение реляционных сравнений в главе 6), и тогда запрос записывался бы так.
SELECT DISTINCT S.SNAME
FROM S
WHERE ( SELECT SP.P# )
FROM SP
WHERE SP.S# = S.S# ) =
( SELECT P.P#
FROM P ) ;
Поскольку язык SQL непосредственно не поддерживает операции сравнения таблиц,
необходимо прибегнуть к приему, использующему сравнение кардинальности таблиц
(опираясь на практический опыт, мы можем гарантировать, что если кардинальности
таблиц равны, то и таблицы одинаковы, по крайней мере в обсуждаемом случае). Допол-
нительный материал по данной теме приведен в упр. 7.11.
7.7.16. Определить номера деталей, которые либо весят
более 16 фунтов, либо поставляются
поставщиком с номером ‘S2’, либо и то, и другое
SELECT P.P#
FROM Р
WHERE Р.WEIGHT >16.0
UNION
SELECT SP.P#
FROM SP
WHERE SP.S# = 'S2' ;
276
Часть II. Реляционная модель
Лишние повторяющиеся строки всегда исключаются из результата выполнения не-
уточненных операторов UNION, INTERSECT и EXCEPT (в языке SQL оператор EXCEPT слу-
жит аналогом операции MINUS реляционной алгебры). Однако язык SQL также поддер-
живает уточненные варианты этих операторов (UNION ALL, INTERSECT ALL и
EXCEPT ALL), при которых повторяющиеся строки (если они есть) сохраняются. Приме-
ры с этими вариантами операторов умышленно опускаются.
В заключение отметим, что, хотя список примеров операций выборки был доста-
точно большим, о многих возможностях языка SQL здесь даже не упоминалось.
Язык SQL в действительности является чрезвычайно избыточным [4.18] в том смыс-
ле, что почти всегда существует множество способов формулирования одного и того
же запроса и нам не хватит места, чтобы описать все возможные формулировки и
все возможные опции даже для сравнительно небольшого числа примеров, которые
приводились в этой главе.
7.8. Резюме
В этой главе кратко рассматривалось реляционное исчисление, альтернативное реля-
ционной алгебре. Внешне два подхода очень отличаются: исчисление имеет описатель-
ный характер, тогда как характер алгебры — предписывающий, но на более низком
уровне они представляют собой одно и то же, поскольку любые выражения исчисления мо-
гут быть преобразованы в семантически эквивалентные выражения алгебры и наоборот.
Реляционное исчисление существует в двух версиях: исчисление кортежей и исчис-
ление доменов. Основное различие между ними состоит в том, что переменные исчис-
ления кортежей изменяются на отношениях, а переменные исчисления доменов изме-
няются на доменах.
Выражение исчисления кортежей состоит из прототипа кортежа и необязательного
предложения WHERE, содержащего логическое выражение или формулу WFF (“правильно
построенную формулу”). Подобная формула WFF может включать кванторы (EXISTS и
FORALL), свободные и связанные ссылки на переменные, логические (булевы) операторы
(AND, OR, NOT и др.) и т.д. Каждая свободная переменная, которая встречается в формуле
WFF, также должна быть упомянута в прототипе кортежа.
Замечание. В настоящей главе явно этот вопрос не затрагивался, но выражения реля-
ционного исчисления предназначены, по существу, для тех же целей, что и выражения
реляционной алгебры (см. раздел 6.6 главы 6).
На примере было показано, как алгоритм редукции Кодда может использоваться
для преобразования произвольного выражения реляционного исчисления в эквивалент-
ное выражение реляционной алгебры, таким образом подготавливая почву для выбора
возможной стратегии реализации исчисления. Вновь обратившись к вопросу реляцион-
ной полноты, мы кратко обсудили, каким образом можно доказать, что некоторый язык
L является полным в этом смысле.
Кроме того, здесь обсуждалось, как можно расширить исчисление кортежей с целью
поддержки определенных вычислительных возможностей (аналогичные возможности
в реляционной алгебре обеспечиваются операциями EXTEND и SUMMARIZE). Затем читате-
лям было представлено краткое введение в исчисление доменов и отмечено (правда, без
попытки доказать это), что оно также является реляционно полным. Таким образом, ис-
числение кортежей, исчисление доменов и реляционная алгебра эквивалентны.
Глава 7. Реляционное исчисление 1Л1
И наконец, вашему вниманию был представлен обзор соответствующих средств язы-
ка SQL. Язык SQL является своеобразной смесью реляционной алгебры и исчисления
(кортежей). Например, в нем есть прямая поддержка таких операций реляционной алгеб-
ры, как соединение и объединение, но одновременно с этим используются переменные
кортежей и квантор существования из реляционного исчисления. SQL-запрос представ-
ляет собой табличное выражение. Обычно такая конструкция содержит единственное
выражение выборки, однако поддерживаются и различные типы явных выражений
операций соединения (JOIN), причем выражения соединения и выборки могут комбини-
роваться произвольным образом с помощью операторов UNION, INTERSECT и EXCEPT.
Также упоминалось о возможности использования предложения ORDER BY для определе-
ния упорядоченности строк в таблице, являющейся результатом вычисления данного
табличного выражения (любого вида).
В частности, были описаны следующие компоненты выражений выборки.
Базовое предложение SELECT, в том числе использование ключевого слова
DISTINCT, скалярных выражений, введение имен результирующих столбцов и ис-
пользование предложения SELECT *
Предложение FROM, включая использование переменных кортежей
Предложение WHERE, включая использование оператора EXISTS
Предложения GROUP BY и HAVING, включая использование обобщающих функ-
ций COUNT, SUM, AVG, МАХ и MIN
Использование подзапросов в предложениях SELECT, FROM и WHERE
Кроме того, здесь был описан концептуальный алгоритм вычисления (т.е. схема
формального определения) для выражений выборки.
Упражнения
7.1. Пусть р (х) и q — произвольные формулы WFF, в которых переменная х соответствен-
но используется и не используется в качестве свободной переменной. Какие из сле-
дующих формулировок верны? (Здесь символ “=>” означает “следует”, а символ “=” оз-
начает “эквивалентно”. Обратите внимание, что если А => В и В => А, то А = В.)
a) EXISTS х ( q ) е q
б) FORALL х ( q ) = q
в) EXISTS x ( p (x) AND q ) EXISTS x ( p (x) ) AND q
r) FORALL x ( p (x) AND q ) = FORALL x ( p (x) ) AND q
д) FORALL x ( p (x) ) => EXISTS x ( p (x) )
7.2. Пусть p(x,y) — это произвольная формула WFF co свободными переменными x и
у. Какие из следующих формулировок верны?
a) EXISTS х EXISTS у ( р(х,у) ) EXISTS у EXISTS х ( р(х,у) )
б) FORALL х FORALL у ( р(х,у) ) s FORALL у FORALL х ( р(х,у) )
в) FORALL х ( р(х,у) ) = NOT EXISTS х ( NOT р(х,у) )
г) EXISTS х ( р(х,у) ) = NOT FORALL х ( NOT р(х,у) )
278
Часть II. Реляционная модель
д) EXISTS х FORALL у ( p(x,y) ) = FORALL у EXISTS x ( p(x,y) )
e) EXISTS у FORALL x ( p(x,y) ) => FORALL x EXISTS у ( p(x,y) )
7.3. Пусть p(x) и q(y) — произвольные формулы WFF co свободными переменными x
и у соответственно. Какие из следующих формулировок верны?
a) EXISTS х ( р(х) ) AND EXISTS у ( q(y) ) =
EXISTS х EXISTS у ( p(x) AND q(y) )
6) EXISTS x ( IF p(x) THEN q(x) END IF ) =
IF FORALL x ( p(x) ) THEN EXISTS x ( q(x) ) END IF
7.4. Еще раз обратимся к запросу из примера 7.3.8: “Определить номера поставщи-
ков по крайней мере всех типов деталей, поставляемых поставщиком с номером
' S2'”. Для этого запроса возможна следующая формулировка в терминах исчис-
ления кортежей.
SX.S# WHERE FORALL SPY ( IF SPY.S# = 'S2' THEN
EXISTS SPZ ( SPZ.S# = SX.S# AND
SPZ.P# = SPY.P# )
END IF )
(Здесь SPZ — это еще одна переменная кортежа, изменяющаяся на отношении по-
ставок.) Что будет возвращено при выполнении этого запроса, если поставщик с
номером ' S2' в данный момент не поставляет никаких деталей? Что будет, если в
приведенном выражении переменную SX всюду заменить переменной SPX?
7.5. Вот пример запроса к базе данных поставщиков, деталей и проектов (используются
обычные упрощения для имен переменных).
( PX.NAME, PX.CITY ) WHERE FORALL SX FORALL JX EXISTS SPJX
( SX.CITY = 'London' AND
JX.CITY = 'Paris' AND
SPJX.S# = SX.S# AND
SPJX.P# = PX.P# AND
SPJX.J# = JX.J# AND
SPJX.QTY < QTY ( 500 ) )
а) Сформулируйте этот запрос в словесной форме.
б) Возьмите на себя роль СУБД и выполните этот запрос по предложенному Код-
дом алгоритму редукции. Можете ли вы указать какие-либо улучшения, кото-
рые целесообразно внести в данный алгоритм?
7.6. Выразите в терминах исчисления кортежей запрос “Получить три самые тяжелые
детали”.
7.7. Рассмотрим отношение спецификации материалов переменной-отношения
PART_STRUCTURE, представленной в главе 4. (Соответствующие SQL-определения
даны в ответе к упр. 4.6, а пример значения приведен на рис. 4.6.) Обратимся к
широкоизвестному запросу разузлования деталей “Получить номера деталей, ко-
торые на любых уровнях вхождения являются компонентами некоторой заданной
детали (скажем, детали с номером 'Р1')”. Результат этого запроса, например от-
Глава 7. Реляционное исчисление
279
ношение PART_LIST (которое, безусловно, является отношением, производным от
исходного отношения PART_STRUCTURE), нельзя сформулировать в виде единствен-
ного выражения начального реляционного исчисления (или реляционной алгебры).
Иначе говоря, производное отношение PART_LIST не может быть получено с по-
мощью единственного выражения начального реляционного исчисления (или ре-
ляционной алгебры). Почему?
7.8. Предположим, что переменную-отношение поставщиков S заменили набором пе-
ременных-отношений LS, PS, AS... по одной переменной-отношению для каждого
города (например, переменная-отношение LS будет содержать кортежи только для
поставщиков из Лондона). Предположим также, что неизвестно, какие именно су-
ществуют города, в которых находятся поставщики, и поэтому неизвестно, сколько
имеется таких переменных-отношений. Рассмотрим запрос “Существует ли в базе
данных поставщик с номером Можно ли такой запрос выразить в терминах
исчисления (или алгебры)? Обоснуйте свой ответ.
7.9. Покажите, что язык SQL является реляционно полным.
7.10. Существуют ли в языке SQL эквиваленты реляционных операторов EXTEND и
SUMMARIZE?
7.11. Существуют ли в языке SQL эквиваленты операторов реляционных сравнений?
7.12. Приведите как можно больше различных формулировок на языке SQL для запроса
“Выбрать имена поставщиков детали с номером 'Р2'”.
Упражнения по запросам
В основу всех остальных упражнений была положена база данных поставщиков,
деталей и проектов (см. рис. 4.5 в главе 4 и ответ к упр. 5.4 в главе 5). В каждом
случае вам будет предложено записать выражение, позволяющее выполнить ука-
занный запрос. (В качестве интересной вариации попытайтесь сформулировать по-
становку той или иной задачи, глядя на ее ответ.)
7.13. Дайте ответы к упр. 6.13-6.50 в терминах исчисления кортежей.
7.14. Дайте ответы к упр. 6.13-6.50 в терминах исчисления доменов.
7.15. Дайте ответы к упр. 6.13-6.50, используя средства языка SQL.
Список литературы
В дополнение к приведенному ниже списку обратитесь также к [4.7], где описыва-
ется несколько расширений языка SQL, предназначенных для работы с транзитив-
ным замыканием и другими подобными операциями. Эти расширения очень напо-
минают соответствующие возможности, предусмотренные стандартом SQL3, ко-
торые кратко описываются в приложении Б. По вопросу внедрения подобных
средств в реляционное исчисление обратитесь к главе 23.
7.1. Codd E.F. A Data Base Sublanguage Founded on the Relational Calculus 11 Proc. 1971
ACM SIGFIDET Workshop on Data Description, Access and Control. — San Diego,
Calif. —November, 1971.
280
Часть II. Реляционная модель
7.2. Date C.J. A Note on the Relation Calculus // ACM SIGMOD Record 18. — 1989. — №
4. Переиздано: An Anomaly in Codd’s Reduction Algorithm // Relational Database
Writings 1989-1991. Reading, Mass.: Addison-Wesley, 1992.
7.3. Date C.J. Why Quantifier Order Is Important // C.J. Date and Hugh Darwen. Relational
Database Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
7.4. Date C.J. Relational Calculus as an Aid to Effective Query Formulation // C.J. Date and
Hugh Darwen. Relational Database Writings 1989-1991.— Reading, Mass.: Addison-
Wesley, 1992.
Почти все представленные на рынке современные реляционные продукты под-
держивают язык SQL, а не реляционное исчисление (или реляционную алгеб-
ру). В этой статье, тем не менее, отстаивается (и иллюстрируется) применение
реляционного исчисления как промежуточного шага в построении “сложных”
SQL-запросов.
7.5. Held G.D., Stonebraker M.R., and Wong E. INGRES — A Relational Data Base System
// Proc. NCC 44. — Anaheim, Calif. Montvale, N.J.: AFIPS Press, May, 1975.
С середины и до конца 70-х годов разрабатывались два главных реляционных про-
тотипа: система System R в фирме IBM и система INGRES в Калифорнийском уни-
верситете в Беркли. Оба эти проекта имели очень большое значение в исследова-
тельском мире и впоследствии лидировали среди коммерческих систем как СУБД
DB2 (в случае системы System R) и как коммерческий продукт INGRES (в случае
системы INGRES).
Замечание. Прототип INGRES иногда называют “университетским INGRES”
[7.11], чтобы отличать его от коммерческой версии этой системы. Учебный обзор
коммерческой версии можно найти в [1.5].
Система INGRES вначале не являлась SQL-системой, поскольку исходно поддер-
живала язык QUEL (Query Language), который во многих отношениях технически
превосходил SQL. В самом деле, язык QUEL по-прежнему составляет основу дос-
таточного числа современных исследований баз данных, а примеры на языке
QUEL до сих пор появляются в исследовательской литературе. Данная статья, в
которой впервые был описан прототип INGRES, включает предварительное опре-
деление языка QUEL. См. также [7.10]-[7.12].
7.6. Kuhns J.L. Answering Questions by Computer: A Logical Study // Report RM-5428-PR,
Rand Corp. — Santa Monica, Calif., 1967.
7.7. Lacrorix M., Pirotte A. Domain-Oriented Relational Languages // Proc. 3rd Int. Conf, on
Very Large Data Bases. — Tokyo, Japan., October, 1977.
7.8. Merrett Т.Н. The Extended Relational Algebra, A Basis for Query Languages П
Shneiderman B. (ed.). Databases: Improving Usability and Responsiveness. New York,
N.Y.: Academic Press., 1978.
Назначением этой статьи является введение кванторов в алгебру — не просто кван-
торов существования и кванторов всеобщности реляционного исчисления, а более
общих кванторов “количество” и “соотношение”. С их помощью можно выразить та-
кие условия, как “по крайней мере три”, “не более половины”, “нечетное число” и т.д.
7.9. Negri М., Pelagatti G., Sbattella L. Formal Semantics of SQL Queries // ACM TODS. —
September, 1991. — 16, № 3.
Глава 7. Реляционное исчисление
281
Цитата из резюме: “Семантика SQL-запросов формально определена с помо-
щью набора правил, определяющих преобразование на основе синтаксиса
SQL-запроса в формальную модель, называемую расширенным исчислением
трехзначных предикатов (Extended Three Valued Predicate Calculus— E3VPC),
которая большей частью основана на хорошо известных математических поня-
тиях. Приведены также правила преобразования общего выражения E3VPC в
каноническую форму; [дополнительно] полностью решены проблемы, подоб-
ные анализу эквивалентности SQL-запросов”. Однако отметим, что рассматри-
ваемый здесь диалект языка SQL— это только первая версия стандарта
(SQL/86), а не стандарт SQL/92.
7.10. Stonebraker М. The INGRES Papers: The Anatomy of a Relational Database
Management System // Reading, Mass.: Addison-Wesley, 1986.
Собрание некоторых наиболее важных документов университетского проекта
INGRES под редакцией одного из первых создателей этого проекта. (В собрание
включены статьи [7.11], [7.12].) Насколько известно автору настоящей книги, это
единственное доступное издание, в котором подробно описываются проект и реа-
лизация полномасштабной реляционной СУБД. Весьма ценный материал для серь-
езных студентов.
7.11. Stonebraker М., Wong Е., Kreps Р., Held G. The Design Implementation of INGRES //
ACM TODS. — September, 1976. — 1, № 3. (Переиздано [7.10].)
Подробное описание университетского прототипа INGRES.
7.12. Stonebraker М. Retrospection on a Data Base System // ACM TODS.— 1980.— 5,
№ 2. (Переиздано [7.10].)
Доклад по истории проекта прототипа INGRES (до января 1979 года). Акцент сде-
лан скорее на ошибках и полученных уроках, чем на успехах.
7.13. Ullman J. D. Principles of Database and Knowledge-Base Systems: Volume I. Rockville,
Md.: Computer Science Press, 1988.
Книга Ульмана, в отличие от данной книги, содержит более формальное изложе-
ние реляционного исчисления и связанных с ним вопросов. В частности, в ней
обсуждается понятие безопасности выражений исчисления. Это имеет значение
при адаптации немного измененной версии исчисления, в которой переменные
кортежей не определяются отдельными операторами RANGE, а связываются с об-
ластью значений посредством явных условий в предложении WHERE. В такой вер-
сии исчисления запрос “Получить имена всех поставщиков из Лондона”, напри-
мер, может выглядеть так.
SX WHERE SX е S AND SX.CITY = 'London'
Одна из проблем, возникающих при использовании этой версии исчисления, за-
ключается в том, что в ней недопустимы запросы, подобные следующему.
SX WHERE NOT ( SX е S )
Такие выражения называются небезопасными, так как они не возвращают конеч-
ный результат (множество всего, что не входит в отношение S, бесконечно). По-
этому необходимо ввести некоторые правила, обеспечивающие безопасность в
282
Часть II. Реляционная модель
этом смысле. В книге Ульмана описаны такие правила (для исчисления как корте-
жей, так и доменов). Следует отметить, что в оригинальном исчислении Кодда та-
кие правила были.
7.14. Zloof М. М. Query By Example // Proc. NCC 44.— Anaheim, Calif., 1975.—
Montvale, N.J.: AFIPS Press, 1977.
Описанный в этой работе реляционный язык Query-By-Example (QBE) включает
элементы исчисления кортежей и в еще большей степени — элементы исчисле-
ния доменов. Привлекательный и интуитивно понятный синтаксис языка осно-
вывается на идее формирования элементов в “шаблонные таблицы” на экране
дисплея вместо записи линейных операторов. Например, формулировка языка
QBE для запроса “Получить имена поставщиков по крайней мере одной детали,
поставляемой поставщиком с номером 'S2'” (довольно сложный запрос) может
выглядеть следующим образом.
S S# SNAME SP s# p# SP s# P#
SX Р. NX SX PX S2 PX
Пояснение. Пользователь обращается к системе с запросом отобразить на экране
три шаблонные таблицы (одну — для отношения S и две — для отношения SP), по-
сле чего формирует в них элементы, как показано выше. Элементы, начинающиеся
символом подчеркивания, представляют “образцы” (т.е. переменные доменов); ос-
тальные элементы представляют собой литералы. В этом случае пользователь об-
ращается к системе с запросом “предоставить” (“Р”) значения имен поставщиков
(_NX), таких, что если это поставщик _SX, то _SX поставляет некоторую деталь _РХ,
а деталь _РХ, в свою очередь, также поставляется поставщиком с номером 'S2'.
Заметьте, что под кванторами существования подразумевается (как, кстати, и под
кванторами существования в языке QUEL) совсем другой смысл, поэтому данный
синтаксис прост для понимания.
Вот другой пример: “Определить все пары номеров поставщиков, которые нахо-
дятся в одном городе”.
s s# CITY
SX SY CZ CZ P. _sx _SY
К сожалению, язык QBE не является реляционно полным, а конкретнее — не под-
держивает (в полной мере) негативный квантор существования (NOT EXISTS).
Вследствие этого определенные запросы (например, “Получить имена поставщи-
ков всех типов деталей”) не могут быть выражены в языке QBE.
(На самом деле язык QBE вначале “поддерживал” квантор NOT EXISTS, по крайней
мере неявно, но построение всегда было сопряжено с некоторыми трудностями.
Основная проблема заключалась в том, что не было способа указать порядок, в ко-
тором различные неявные кванторы могли бы быть применены, а этот порядок, к
сожалению, очень важен; см. [7.3] или ответ к упр. 7.2. Поэтому определенные за-
просы получались неоднозначными [7.3].)
Злуф (автор этой работы) первым изобрел и разработал язык QBE. Данная статья
была первой из многих статей, написанных Злуфом по этой тематике.
Глава 7. Реляционное исчисление
283
Ответы к некоторым упражнениям
7.1. а) верно; б) верно; в) верно; г) верно; д) не верно.
Замечание. Причина, по которой утверждение д не верно, состоит в том, что при-
менение квантора FORALL к пустому множеству всегда дает значение истина. И на-
оборот, применение квантора EXISTS к пустому множеству всегда дает значение
ложь. Поэтому, например, если утверждение “Все фиолетовые детали весят более
100 фунтов” истинно, то это необязательно означает, что действительно существу-
ют фиолетовые детали.
Заметим, что тождества (верные!) могут использоваться в качестве основы для
множества правил преобразования выражений исчисления аналогично алгебраиче-
ским правилам преобразования, упоминавшимся в главе 6 и подробно обсуждаю-
щимися в главе 17. Аналогичные замечания также применимы к упр. 7.2 и 7.3.
7.2. а) верно; б) верно; в) верно (этот пример рассматривался в основном тексте
главы); г) верно (следовательно, один квантор может быть определен через
другой); б) не верно; е) верно. Обратите внимание, что последовательность
одинаковых кванторов — как в тождествах а и б — может быть записана в лю-
бом порядке без изменения смысла выражения, тогда как для разных кванто-
ров — как показано в тождестве д — такой порядок имеет существенное зна-
чение. Чтобы проиллюстрировать последнее, предположим, что переменные х
и у изменяются на множестве целых чисел и р является формулой WFF у > х.
Очевидно, что формула
FORALL х EXISTS у ( у > х )
(“для всех целых х существует целое у, большее х”) дает значение истина, тогда
как формула
EXISTS у FORALL х (у > х )
(“существует целое у, большее любого целого х”) дает значение ложь. Таким обра-
зом, перестановка неодинаковых кванторов изменяет значение выражения. Поэто-
му в языке запросов, основанном на реляционном исчислении, перестановка не-
одинаковых кванторов в предложении WHERE изменяет значение запроса [7.3].
7.3. а) верно; б) верно.
7.4. Если поставщик с номером 'S2' в данный момент не поставляет никаких дета-
лей, исходный запрос будет возвращать все номера поставщиков из отношения S
(включая, в частности, самого поставщика с номером 'S2', сведения о котором
согласно нашему предположению содержатся в отношении S, но отсутствуют в
SP). Если везде заменить переменную SX переменной SPX, то запрос будет воз-
вращать все номера поставщиков, содержащихся в отношении SP. Различие ме-
жду двумя формулировками следующее: первая означает “Получить номера по-
ставщиков всех типов деталей, поставляемых поставщиком с номером 'S2'” (что
и требуется), а вторая — “Получить номера поставщиков по крайней мере одной
детапи и по крайней мере всех типов деталей, которые поставляются поставщи-
ком с номером ' S2
284
Часть II. Реляционная модель
7.5. а) Получить наименование детали и название города для деталей, поставляемых
для каждого проекта в Париже каждым поставщиком в Лондоне в количестве ме-
нее 500 штук, б) Результат выполнения этого запроса — пустое множество.
7.6. Это упражнение очень трудное! Особенно если мы будем учитывать, что вес
деталей неуникален. (Если бы их вес был уникален, можно было бы перефор-
мулировать запрос так: “Получить все детали, такие, что количество более тя-
желых деталей меньше трех”.) Упражнение настолько трудное, что мы даже не
пытаемся дать здесь полное решение на языке реляционного исчисления. Оно
очень хорошо иллюстрирует тот факт, что реляционная полнота является лишь
основным критерием выразительной силы языка, но необязательно достаточ-
ным. (Следующие два примера также иллюстрируют этот момент.) Подобные
запросы обсуждаются в [6.4].
7.7. Пусть PSA, PSB, PSC, ..., PSn— переменные кортежей, изменяющиеся на перемен-
ной-отношении PART_STRUCTURE. Предположим также, что заданная деталь — это
деталь с номером 'Р1'. Тогда имеем следующее.
а) Выражение реляционного исчисления для запроса “Получить номера деталей
для всех типов деталей, которые являются компонентами детали с номером
' Р1' на первом уровне входимости” будет таким.
PSA.MINOR_P# WHERE PSA.MAJOR_P# = Р ( 'Pl' )
б) Выражение реляционного исчисления для запроса “Получить номера деталей
для всех деталей, которые являются компонентами детали с номером 'Р1' на
втором уровне входимости” будет таким.
PSB.MINOR_P# WHERE EXISTS PSA
( PSA.MAJOR_P# = P ( 'Pl' ) AND
PSB.MAJOR_P# = PSA.MINOR_P# )
в) Выражение реляционного исчисления для запроса “Получить номера деталей
для всех деталей, которые являются компонентами детали с номером 'Р1' на
третьем уровне входимости” будет таким.
PSC.MINOR_P# WHERE EXISTS PSA EXISTS PSB
( PSA.MAJOR_P# = P ( 'Pl' ) AND
PSB.MAJOR_P# = PSA.MINOR_P# AND
PSC.MAJOR_P# = PSB.MINOR_P# )
И т.д. Выражение реляционного исчисления для запроса “Получить номера де-
талей для всех деталей, которые являются компонентами детали с номером
'Р1' на и-м уровне входимости” будет таким.
PSn.MINOR_P# WHERE EXISTS PSA EXISTS PSB ... EXISTS PS(n-l)
( PSA.MAJOR_P# = P ( 'Pl' ) AND
PSB.MAJOR_P# = PSA.MINOR_P# AND
PSC.MAJOR_P# = PSB.MINOR_P# AND
........................... AND
PSn.MAJOR_P# = PS(n-l).MINOR_P# )
Глава 7. Реляционное исчисление
285
Для построения отношения PART_LIST все результирующие отношения из пп. а,
б, в, ..., п необходимо объединить.
Проблема заключается в том, что невозможно записать п таких выражений, если
значение п неизвестно. Следовательно, запрос разузлования детали является клас-
сической иллюстрацией задачи, которая не может быть сформулирована с помо-
щью отдельных выражений на языке, обладающем лишь свойством реляционной
полноты, т.е. на языке, который не является более мощным, чем реляционное ис-
числение (или алгебра). Частично эту проблему можно решить с помощью опера-
тора TCLOSE, кратко рассмотренного в главе 6 (но только частично). Дальнейшие
подробности выходят за рамки этой книги.
Замечание. Хотя данную задачу обычно называют составлением спецификации
материалов или разузлованием деталей, применяется она на самом деле значи-
тельно шире, чем можно судить по этим названиям. В действительности класс
отношений вида “детали содержат детали” очень широко распространен в самых
разных приложениях. Кроме всего прочего, подобный вид отношений присутст-
вует в процессах управления иерархическими структурами, в родословных де-
ревьях, графах аутентификации, сетевых взаимодействиях, структурах вызова
программных модулей, транспортных сетях и т.д.
7.8. Этот запрос нельзя выразить ни в терминах исчисления, ни в терминах алгебры.
Например, чтобы выразить его в терминах исчисления, по существу, потребова-
лось бы уметь выражать нечто подобное следующему.
“Существует ли отношение г, такое, что в этом отношении г имеется кортеж t, та-
кой, что t.S# = S# ( 'S1' )?”
Другими словами, мы должны были бы уметь квалифицировать отношения, а не
кортежи и, следовательно, потребовалась бы иная переменная с новой областью
значений, т.е. такая переменная, значениями которой являлись бы некоторые от-
ношения, а не кортежи. Поэтому подобный запрос не может быть выражен в тер-
минах реляционного исчисления, как оно определено на настоящий момент.
Кстати, обратите внимание, что рассматриваемый запрос — это запрос типа
“Да — нет” (причем, желаемый ответ — чаще всего значение истина}. Поэто-
му читателю может показаться, что запрос нельзя выразить в терминах исчис-
ления или с помощью алгебры, потому что выражения реляционного исчисле-
ния и алгебры принимают значения отношений, а не логические. Однако за-
просы типа “Да — нет” могут быть выражены в терминах исчисления и алгеб-
ры, если они правильно реализованы! Главная трудность заключается в том,
чтобы понять, что результаты “да” и “нет” (эквивалентные значениям истина
и ложь) .могут быть представлены как отношения. Рассматриваемые отно-
шения — это TABLE_DEE и TABLE_DUM соответственно. Более подробное обсуж-
дение этих отношений приводится в [5.5].
7.9. Для подтверждения реляционной полноты языка SQL необходимо сначала пока-
зать, что существуют SQL-выражения для каждой из пяти примитивных операций
реляционной алгебры (выборки, проекции, произведения, объединения и вычита-
ния), а затем доказать, что операнды таких SQL-выражений могут, в свою очередь,
быть произвольными выражениями языка SQL.
286
Часть II. Реляционная модель
Начнем с предварительного замечания о том, что язык SQL фактически поддержи-
вает оператор переименования реляционной алгебры RENAME после введения в
стандарт SQL/92 необязательной спецификации AS <имя столбца> в предложении
SELECT. Следовательно, можно быть уверенным, что все имена столбцов в табли-
цах правильны и, в частности, что операнды операций произведения, объединения
и вычитания удовлетворяют требованиям реляционной алгебры (в нашей версии) в
отношении именования столбцов. Более того, указанные требования к именованию
столбцов операндов действительно удовлетворяются: правила вывода имен столб-
цов в языке SQL фактически совпадают с аналогичными правилами реляционной
алгебры (в нашей версии), что было показано в главе 6.
Вот выражения языка SQL, соответствующие пяти примитивным операциям алгебры.
Алгебра Язык SQL
A WHERE р А {X, у,..., 2} SELECT * FROM A WHERE р SELECT DISTINCT X, у,...,2 FROM A
A TIMES В A UNION В A CROSS JOIN В SELECT * FROM A UNION SELECT * FROM В
A MINUS В SELECT * FROM A EXCEPT SELECT * FROM В
Обратившись к грамматике табличных выражений языка SQL, которая описывается в
приложении А, можно увидеть, что переменные А и В в приведенных выше SQL-
выражениях по сути являются значениями параметра <ссылка на таблицу>. Можно
убедиться еще и в том, что если заключить каждое из пяти показанных SQL-
выражений в скобки, то оно также станет допустимым значением этого же парамет-
ра7. Отсюда следует, что язык SQL на самом деле является реляционно полным.
Замечание. В действительности во всем вышесказанном есть один недостаток:
язык SQL не поддерживает проекций по нулевому количеству столбцов (поскольку
он не поддерживает пустых предложений SELECT). Как следствие язык SQL не под-
держивает таблиц TABLE_DEE и TABLE_DUM [5.5].
7.10. Язык SQL поддерживает операцию EXTEND, но не SUMMARIZE (по крайней мере, не не-
посредственно). Что касается операции EXTEND, то выражение реляционной алгебры
EXTEND A ADD ехр AS Z
в языке SQL может быть представлено так.
SELECT А.*, ехр' AS Z
FROM ( А ) AS А
Выражение ехр' в предложении SELECT является SQL-аналогом операнда ехр в
выражении EXTEND. Заключенная в скобки ссылка на переменную А представляет
собой значение параметра <ссылка на таблнцу> произвольной сложности
7 Здесь мы игнорируем mom факт, что в языке SQL параметр <ССЫЛКа на таблицу> в дей-
ствительности требует включения в свое значение определения переменной кортежа с пустой
областью значений (см. приложение А).
Глава 7. Реляционное исчисление
287
(соответствующую операнду А оператора EXTEND). Вторая ссылка А в предложе-
нии FROM — имя переменной кортежа.
Что касается операции SUMMARIZE, основная проблема состоит в том, что выраже-
ние реляционной алгебры
SUMMARIZE A PER В ...
возвращает результат, кардинальность которого равна кардинальности операнда В,
в то время как “эквивалентное” этой функции SQL-выражение
SELECT ...
FROM А
GROUP BY С ;
возвращает результат с кардинальностью, равной кардинальности проекции табли-
цы А по атрибуту С.
7.11. Язык SQL не поддерживает реляционных сравнений непосредственно. Однако по-
добные операции можно смоделировать, хотя и в виде очень громоздких выраже-
ний. Например, реляционное сравнение А = В (где А и В — отношения) можно ус-
пешно смоделировать с помощью следующего SQL-выражения.
NOT EXISTS ( SELECT * FROM A
WHERE NOT EXISTS ( SELECT * FROM В
WHERE к-строка = В-строка ) )
Здесь операнды k-строка и В-строка— это значения параметра <конструктор
строки> (приложение А), представляющие соответственно всю строку таблицы А и
всю строку таблицы В.
7.12. Вот несколько таких формулировок. Заметьте, что этот список далеко не исчерпы-
вающий [4.18]. Обратите внимание также на простоту каждого запроса!
SELECT DISTINCT S.SNAME
FROM S
WHERE S.S# IN
( SELECT SP.S#
FROM SP
WHERE SP.P# = 'P2' ) ;
SELECT DISTINCT T.SNAME
FROM ( S NATURAL JOIN SP ) AS T
WHERE T.P# = 'P2' ;
SELECT DISTINCT T.SNAME
FROM ( S JOIN SP ON S.S# = SP.P# AND SP.P# = 'P2' ) AS T ;
SELECT DISTINCT T.SNAME
FROM ( S JOIN SP USING S# ) AS T
WHERE T.P# = 'P2' ;
288
Часть IL Реляционная модель
SELECT DISTINCT S.SNAME
FROM S
WHERE EXISTS
( SELECT *
FROM SP
WHERE SP.S# = S.S#
AND SP.P# = 'P2' ) ;
SELECT DISTINCT S.SNAME
FROM S, SP
WHERE S.S# = SP.S#
AND SP.P# = 'P2' ;
SELECT DISTINCT S.SNAME
FROM S
WHERE 0 <
( SELECT COUNT(*)
FROM SP
WHERE SP.S# = S.S#
AND SP.P# = 'P2' ) ;
SELECT DISTINCT S.SNAME
FROM S
WHERE 'P2' IN
( SELECT SP.P#
FROM SP
WHERE SP.S# = S.S# ) ;
SELECT S.SNAME
FROM S, SP
WHERE S.S# = SP.S#
AND SP.P# = 'P2'
GROUP BY S.SNAME ;
Дополнительный вопрос. Каков смысл всех приведенных выше запросов?
7.13. Мы перенумеровали решения для этого пункта как 7.13./?, где п — номер исходно-
го упражнения в главе 6, т.е. упр. б.п. Подразумевается, что переменные SX, SY, РХ,
PY, JX, JY, SPJX, SPJY и т.д. — это переменные кортежей, изменяющихся на отно-
шениях S, Р, J и SPJ соответственно. Определение этих переменных кортежей в от-
ветах не показано.
7.13.13. JX
7.13.14.JX WHERE JX.CITY = 'London'
7.13.15.SPJX.S# WHERE SPJX.J# = J# ( 'Jl' )
7.13.16.SPJX WHERE SPJX.QTY > QTY ( 300 ) AND
SPJX.QTY < QTY ( 750 )
7.13.17. ( PX.COLOR, PX.CITY )
Глава 7. Реляционное исчисление
289
7.13.18. ( SX.S#, PX.P#, jx.j# : ) WHERE SX.CITY = PX.CITY = JX.CITY = SX.CITY
AND AND PX.CITY JX.CITY
7.13.19. ( SX.S#, PX.P#, jx.j# : ) WHERE SX.CITY * PX.CITY
OR PX.CITY * JX.CITY
OR JX.CITY * SX.CITY
7.13.20. ( SX.S#, PX.P#, JX.J# ) WHERE SX.CITY * PX.CITY
AND PX.CITY * JX.CITY
AND JX.CITY * SX.CITY
7.13.21. SPJX.P# WHERE EXISTS SX ( SX.S# = SPJX.S# AND
SX.CITY = 'London' )
7.13.22.SPJX.P# WHERE EXISTS SX EXISTS JX
( SX.S# = SPJX.S# AND SX.CITY = 'London' AND
JX.J# = SPJX.J# AND JX.CITY = 'London' )
7.13.23. ( SX.CITY AS SCITY, JX.CITY AS JCITY )
WHERE EXISTS SPJX ( SPJX.S# = SX.S# AND SPJX.J# = JX.J# )
7.13.24.SPJX.P# WHERE EXISTS SX EXISTS JX
( SX.CITY = JX.CITY AND
SPJX.S# = SX.S# AND
SPJX.J# = JX.J# )
7.13.25.SPJX.J# WHERE EXISTS SX EXISTS JX
( SX.CITY * JX.CITY AND
SPJX.S# = SX.S# AND
SPJX.J# = JX.J# )
7.13.26. ( SPJX.P# AS XP#, SPJY.P# AS YP# )
WHERE SPJX.S# = SPJY.S# AND SPJX.P# < SPJY.P#
7.13.27.COUNT ( SPJX.J# WHERE SPJX.S# = S# ( 'SI' ) ) AS N
7.13.28.SUM ( SPJX WHERE SPJX.S# = S# ( 'SI' )
AND SPJX.P# = P# ( 'Pl' ), QTY ) AS Q
Замечание. Следующее “решение” не верно (почему?).
SUM ( SPJX.QTY WHERE SPJX.S# = S# ( 'SI' )
AND SPJX.P# = P# ( 'Pl' ), QTY ) AS Q
Ответ. При вычислении суммы повторяющиеся значения в столбце QTY буду]
игнорироваться.
7.13.29. ( SPJX.P#, SPJX.J#,
SUM ( SPJY WHERE SPJY.P# = SPJX.P#
AND SPJY.J# = SPJX.J#, QTY ) AS Q )
7.13.30.SPJX.P# WHERE
AVG ( SPJY WHERE SPJY.P# = SPJX.P#
AND SPJY.J# = SPJX.J#, QTY ) > QTY ( 350 )
290
Часть II. Реляционная моделг
7.13.31. JX.JNAME WHERE EXISTS SPJX ( SPJX.J# = JX.J# AND
SPJX.S# = S ( 'SI' ) )
7.13.32.PX.COLOR WHERE EXISTS SPJX ( SPJX.P# = PX.P# AND
SPJX.S# = S# ( 'SI' ) )
7.13.33.SPJX.P# WHERE EXISTS JX ( JX.CITY = 'London' AND
JX.J# = SPJX.J# )
7.13.34.SPJX.J# WHERE EXISTS SPJY ( SPJX.P# = SPJY.P# AND
SPJY.S# = S# ( 'SI' ) )
7.13.35.SPJX.S# WHERE EXISTS SPJY EXISTS SPJZ EXISTS PX
, ( SPJX.P# = SPJY.P# AND
SPJY.S# = SPJZ.S# AND
SPJZ.P# = PX.P# AND
PX.COLOR = COLOR ( 'Red' ) )
7.13.36.SX.S# WHERE EXISTS SY ( SY.S# = S# ( 'SI' ) AND
SX.STATUS < SY.STATUS )
7.13.37.JX.J# WHERE FORALL JY ( JY.CITY > JX.CITY ) или
JX.J# WHERE JX.CITY = MIN ( JY.CITY )
7.13.38.SPJX.J# WHERE SPJX.P# = P# ( 'Pl' ) AND
AVG ( SPJY WHERE SPJY.P# = P# ( 'Pl' )
AND SPJY.J# = SPJX.J#, QTY ) >
MAX ( SPJZ.QTY WHERE SPJZ.J# = J# ( 'JI' ) )
7.13.39.SPJX.S# WHERE SPJX.P# = P# ( 'Pl' )
AND SPJX.QTY >
AVG ( SPJY
WHERE SPJY.P# = P# ( 'Pl' )
AND SPJY.J# = SPJX.J#, QTY )
7.13.40.JX.J# WHERE NOT EXISTS SPJX EXISTS SX EXISTS PX
( SX.CITY = 'London' AND
PX.COLOR = COLOR ( 'Red' ) AND
SPJX.S# = SX.S# AND
SPJX.P# = PX.P# AND
SPJX.J# = JX.J# )
7.13.41.JX.J# WHERE FORALL SPJY ( IF SPJY.J# = JX.J#
THEN SPJY.S# = S# ( 'SI' )
END IF )
7.13.42.PX.P# WHERE FORALL JX
( IF JX.CITY = 'London' THEN
EXISTS SPJY ( SPJY.P# = PX.P# AND
SPJY.J# = JX.J# )
END IF )
7.13.43.SX.S# WHERE EXISTS PX FORALL JX EXISTS SPJY
( SPJY.S# = SX.S# AND
Глава 7. Реляционное исчисление
291
SPJY.P# = PX.P# AND
SPJY.J# = JX.J# )
7.13.44.JX.J# WHERE FORALL SPJY ( IF SPJY.S# = S# ( 'SI' ) THEN
EXISTS SPJZ
( SPJZ.J# = JX.J# AND
SPJZ.P# = SPJY.P# )
END IF )
7.13.45. RANGEVAR VX RANGES OVER
( SX.CITY ), ( PX.CITY ), ( JX.CITY ) ;
VX.CITY
7.13.46.SPJX.P# WHERE EXISTS SX ( SX.S# = SPJX.S# AND
SX.CITY = 'London' )
OR EXISTS JX ( JX.J# = SPJX.J# AND
JX.CITY = 'London' )
7.13.47 . ( SX.S#, PX.P# )
WHERE NOT EXISTS SPJX ( SPJX.S# = SX.S# AND
SPJX.P# = PX.P# )
7.13.48 . ( SX.S# AS XS#, SY.S# AS YS# )
WHERE FORALL PZ
( ( IF EXISTS SPJX ( SPJX.S# = SX.S# AND
SPJX.P# = PZ.P# )
THEN EXISTS SPJY ( SPJY.S# = SY.S# AND
SPJY.P# = PZ.P# )
END IF )
AND
( IF EXISTS SPJY ( SPJY.S# = SY.S# AND
SPJY.P# = PZ.P# )
THEN EXISTS SPJX ( SPJX.S# = SX.S# AND
SPJX.P# = PZ.P# )
END IF ) )
7.13.49 . ( SPJX.S#, SPJX.P#, ( SPJY.J#, SPJY.QTY WHERE
SPJY.S# = SPJX.S# AND
SPJY.P# = SPJX.P# ) AS JQ )
7.13.50 . Пусть R — это результат вычисления выражения из ответа к предыдущему уп
ражнению. Тогда имеем следующее.
RANGEVAR RX RANGES OVER R ,
RANGEVAR RY RANGES OVER RX.JQ ;
(RX.S#, RX.P#, RY.J#, RY.QTY )
Мы несколько расширили синтаксис и семантику параметра <определени
переменной кортежа>. Идея состоит в том, что определение переменной RY зави
сит от переменной RX (обратите внимание на то, что оба определения разделен!
запятыми, а не точками с запятыми, и поэтому связаны в одну операцию). Даль
нейшее обсуждение этого вопроса приводится в [3.3].
292
Часть II. Реляционная модели
7.14. Мы перенумеровали решения для этого пункта в виде 7.14./?, где п— номер ис-
ходного упражнения в главе 6, т.е. упр. б.п. Относительно определения и именова-
ния переменных доменов будем следовать соглашениям, принятым в разделе 7.6.
7.14.13. ( JX, NAMEX, CITYX )
WHERE J ( J#:JX, JNAME:NAMEX, CITY:CITYX )
7.14.14. ( JX, NAMEX, 'London' AS CITY )
WHERE J ( J#:JX, JNAME-.NAMEX, CITY:'London' )
7.14.15.SX WHERE SPJ ( S#:SX, J#:J# ( 'JI' ) )
7.14.16. ( SX, PX, JX, QTYX )
WHERE SPJ ( S#:SX, P#:PX, J#:JX, QTY:QTYX )
AND QTYX > QTY ( 300 ) AND QTYX < QTY ( 750 )
7.14.17. ( COLORX, CITYX WHERE P ( COLOR:COLORX, CITY:CITYX ) )
7.14.18. ( SX, PX, JX ) WHERE EXISTS CITYX
( S ( S#:SX, CITY:CITYX ) AND
P ( P#:PX, CITY:CITYX ) AND
J ( J#:JX, CITY:CITYX ) )
7.14.19. ( SX, PX, JX )
WHERE EXISTS CITYX EXISTS CITYY EXISTS CITYZ
( S ( S#:SX, CITY:CITYX ) AND
P ( P#:PX, CITY:CITYY ) AND
J ( J#:JX, CITY:CITYZ )
AND ( CITYX * CITYY OR
CITYY * CITYZ OR
CITYZ Ф CITYX ) )
7.14.20. ( SX, PX, JX )
WHERE EXISTS CITYX EXISTS CITYY EXISTS CITYZ
( S ( S#:SX, CITY:CITYX ) AND
P ( P#:PX, CITY:CITYY ) AND
J ( J#:JX, CITY:CITYZ )
AND ( CITYX Ф CITYY AND
CITYY Ф CITYZ AND
CITYZ * CITYX ) )
7.14.21. PX WHERE EXISTS SX ( SPJ ( P#:PX, S#:SX ) AND
S ( S#:SX, CITY:'London' ) )
7.14.22. PX WHERE EXISTS SX EXISTS JX
( SPJ ( S#:SX, P#:PX, J#:JX )
AND S ( S#:SX, CITY:'London' )
AND J ( J#:JX, CITY:'London' )
7.14.23. ( CITYX AS SCITY, CITYY AS JCITY )
WHERE EXISTS SX EXISTS JY
( S ( S#:SX, CITY:CITYX )
Глава 7. Реляционное исчисление
293
AND J ( J#:JY, CITY:CITYY )
AND SPJ ( S#:SX, J#:JY ) )
7.14.24. PX WHERE EXISTS SX EXISTS JX EXISTS CITYX
( S ( S#:SX, CITY:CITYX )
AND J ( J#:JY, CITY:CITYX )
AND SPJ ( S#:SX, P#:PX, J#:JX ) )
7.14.25. JY WHERE EXISTS SX EXISTS CITYX EXISTS CITYY
( SPJ ( S#:SX, J#:JY )
AND S ( S#:SX, CITY:CITYX )
AND J ( J#:JY, CITY:CITYY )
AND CITYX * CITYY )
7.14.26. ( PX AS XP#, PY AS YP# ) WHERE EXISTS SX
( SPJ ( S#:SX, P#:PX )
AND SPJ ( S#:SX, P#:PY )
AND PX < PY )
7.14.27- 7.14.30. Решения опущены.
7.14.31. NAMEX WHERE EXISTS JX
( J ( J#:JX, JNAME:NAMEX )
AND SPJ ( S#:S# ( 'SI' ), J#:JX ) )
7.14.32. COLORX WHERE EXISTS PX
( P ( P#:PX, COLOR:COLORX ) AND
SPJ ( S#:S# ( 'SI' ), P#:PX ) )
7.14.33. PX WHERE EXISTS JX
( SPJ ( P#:PX, J#:JX ) AND
J ( J#:JX, CITY:'London' ) )
7.14.34. JX WHERE EXISTS PX
( SPJ ( P#:PX, J#:JX ) AND
SPJ ( P#:PX, S#:S#( 'SI' ) ) )
7.14.35. SX WHERE EXISTS PX EXISTS SY EXISTS PY
( SPJ ( S#:SX, P#:PX ) AND
SPJ ( P#:PX, S#:SY ) AND
SPJ ( S#:SY, P#:PY ) AND
P ( P#:PY, COLOR:COLOR ( 'Red' ) ) )
7.14.36. SX WHERE EXISTS STATUSX EXISTS STATUSY
( S ( S#:SX, STATUS:STATUSX ) AND
S ( S#:S# ( 'SI' ), STATUS:STATUSY ) AND
STATUSX < STATUSY )
7.14.37. JX WHERE EXISTS CITYX
( J ( J#:JX, CITY:CITYX ) AND
FORALL CITYY ( IF J ( CITY:CITYY )
THEN CITYY > CITYX
END IF) )
7.14.38- 7.14.39. Решения опущены.
294
Часть II. Реляционная модель
7.14.40. JX WHERE J ( J#:JX ) AND
NOT EXISTS SX EXISTS PX
( SPJ ( S#:SX, P#:PX, J#:JX ) AND
S ( S#:SX, CITY:'London' ) AND
P ( P#:PX, COLOR:COLOR ( 'Red' ) ) )
7.14.41. JX WHERE J ( J#:JX )
AND FORALL SX ( IF SPJ ( S#:SX, J#:JX )
THEN SX = S# ( 'SI' )
END IF )
7.14.42. PX WHERE P ( P#:PX )
AND FORALL JX ( IF J ( J#:JX, CITY:'London' )
THEN SPJ ( P#:PX, J#:JX )
END IF )
7.14.43. SX WHERE S ( S#:SX )
AND EXISTS PX FORALL JX
( SPJ ( S#:SX, P#:PX, J#:JX ) )
7.14.44. JX WHERE J ( J#:JX )
AND FORALL PX ( IF SPJ ( S#:S# ( 'Si' ), P#:PX )
THEN SPJ ( P#:PX, J#:JX )
END IF )
7.14.45. CITYX WHERE EXISTS S ( CITY:CITYX )
OR P ( CITY:CITYX )
OR J ( CITY:CITYX )
7.14.46. PX WHERE EXISTS SX ( SPJ ( S#:SX, P#:PX ) AND
S ( S#:SX, CITY:'London' ) )
OR EXISTS JX ( SPJ ( J#:JX, P#:PX ) AND
J ( J#:JX, CITY:'London' ) )
7.14.47. ( SX, PX ) WHERE S ( S#:SX ) AND P ( P#:PX )
AND NOT SPJ ( S#:SX, P#:PX )
7.14.48. ( SX AS XS#, SY AS YS# )
WHERE S ( S#:SX ) AND S ( S#:SY ) AND FORALL PZ
( ( IF SPJ ( S#:SX, P#:PZ ) THEN SPJ ( S#:SY, P#:PZ )
END IF )
AND
( IF SPJ ( S#:SY, P#:PZ ) THEN SPJ ( S#:SX, P#:PZ )
END IF ) )
7.14.49- 7.14.50. Решения опущены.
7.15. Мы перенумеровали решения этого пункта в виде 7.15.п, что соответствует номе-
рам б.п в исходных упражнениях главы 6.
7.15.13. SELECT *
FROM J ;
или просто
TABLE J ;
Глава 7. Реляционное исчисление
295
7.15.14.SELECT J.*
FROM J
WHERE J.CITY = 'London' ;
7.15.15.SELECT DISTINCT SPJ.S#
FROM WHERE SPJ SPJ.J# = 'JI' ;
7.15.16. SELECT FROM WHERE AND SPJ.* SPJ SPJ.QTY >= 300 SPJ.QTY <= 750 ;
7.15.17. SELECT FROM DISTINCT P.COLOR, P.CITY p ;
7.15.18. SELECT FROM WHERE AND S.S#, P.P#, J.J# S, P, J S.CITY = P. CITY P.CITY = J. CITY ;
7.15.19. SELECT FROM WHERE S.S#, P.P#, J.J# S, P, J NOT ( S.CITY = P.CITY AND P.CITY = J.CITY ) ;
7.15.20. SELECT FROM WHERE AND AND S.S#, P.P#, J.J# S, P, J S.CITY <> P.CITY P.CITY <> J.CITY J.CITY <> P.CITY ;
7.15.21. SELECT DISTINCT SPJ.P#
FROM SPJ
WHERE ( SELECT S.CITY
FROM S
WHERE S.S# = SPJ.S# ) = 'London' ;
7.15.22. SELECT DISTINCT SPJ.P#
FROM SPJ
WHERE ( SELECT S.CITY
FROM S
WHERE S.S# = SPJ.S# ) = 'London'
AND ( SELECT J.CITY
FROM J
WHERE J.J# = SPJ.J# ) = 'London' ;
7.15.23. SELECT DISTINCT S.CITY AS SCITY, , J.CITY AS JCITY
FROM S, J
WHERE EXISTS
( SELECT *
FROM SPJ
296
Часть II. Реляционная модель
WHERE SPJ.S# = S.S# AND SPJ.J# = J.J# ) ;
7.15.24. SELECT FROM WHERE DISTINCT SPJ.P# SPJ ( SELECT S.CITY FROM S WHERE S.S# = SPJ.S# ) = ( SELECT J.CITY FROM J WHERE J.J# = SPJ.J# ) ;
7.15.25. SELECT FROM WHERE DISTINCT SPJ.J# SPJ ( SELECT S.CITY FROM S WHERE S.S# = SPJ.S# ) <> ( SELECT J.CITY FROM J WHERE J.J# = SPJ.J# ) ;
7.15.26. SELECT FROM WHERE AND DISTINCT SPJX.P# AS PA, SPJY.P# AS PB SPJ AS SPJX, SPJ AS SPJY SPJX.S# = SPJY.S# SPJX.P# < SPJY.P# ;
7.15.27. SELECT FROM WHERE COUNT ( DISTINCT SPJ.J# ) AS N SPJ SPJ.S# = 'SI' ;
7.15.28. SELECT FROM WHERE AND SUM ( SPJ.QTY ) AS X SPJ SPJ.S# = 'SI' SPJ.P# = 'Pl' ;
7.15.29. SELECT FROM SPJ.P#, SPJ.J#, SUM ( SPJ.QTY ) AS Y SPJ
GROUP BY SPJ.P#, SPJ.J# ;
7.15.30. SELECT FROM GROUP HAVING DISTINCT SPJ.P# SPJ BY SPJ.P#, SPJ.J# AVG ( SPJ.QTY ) > 350 ;
7.15.31. SELECT FROM WHERE AND DISTINCT J.JNAME J, SPJ J.J# = SPJ.J# SPJ.S# = 'Si' ;
7.15.32. SELECT FROM WHERE AND DISTINCT P.COLOR P, SPJ P.P# = SPJ.P# SPJ.S# = 'Si' ;
Глава 7. Реляционное исчисление
297
7.15.33.SELECT DISTINCT SPJ.P#
FROM SPJ, J
WHERE SPJ.J# = J.J#
AND J.CITY = 'London' ;
7.15.34.SELECT DISTINCT SPJX.J#
FROM SPJ AS SPJX, SPJ AS SPJY
WHERE SPJX.P# = SPJY.P#
AND SPJY.S# = 'SI' ;
7.15.35.SELECT DISTINCT SPJX.S#
FROM SPJ AS SPJX, SPJ AS SPJY, SPJ AS SPJZ
WHERE SPJX.P# = SPJY.P#
AND SPJY.S# = SPJZ.S#
AND ( SELECT P.COLOR
FROM P
WHERE P.P# = SPJZ.P# ) = 'Red' ;
7.15.36.SELECT S.S#
FROM S
WHERE S.STATUS < ( SELECT S.STATUS
FROM S
WHERE S.S# = 'SI' ) ;
7.15.37.SELECT J.J#
FROM J
WHERE J.CITY = ( SELECT MIN ( J.CITY )
FROM J ) ;
7.15.38.SELECT DISTINCT SPJX.J#
FROM SPJ AS SPJX
WHERE SPJX.P# = 'Pl'
AND ( SELECT AVG ( SPJY.QTY )
FROM SPJ AS SPJY
WHERE SPJY.J# = SPJX.J#
AND SPJY.P# = 'Pl' ) >
( SELECT MAX ( SPJZ.QTY )
FROM SPJ AS SPJZ
WHERE SPJZ.J# = 'JI' ) ;
7.15.39.SELECT DISTINCT SPJX.S#
FROM SPJ AS SPJX
WHERE SPJX.P# = 'Pl'
AND SPJX.QTY > ( SELECT AVG ( SPJY.QTY )
FROM SPJ AS SPJY
WHERE SPJY.P# = 'Pl'
AND SPJY.J# = SPJX.J# ) ;
7.15.40.SELECT J.J#
FROM J
WHERE NOT EXISTS
298
Часть IL Реляционная модель
( SELECT *
FROM SPJ, P, S
WHERE SPJ.J# = J.J#
AND SPJ.P# = P.P#
AND SPJ.S# = S.S#
AND P.COLOR = 'Red'
AND S.CITY = 'London' ) ;
7.15.41.SELECT J.J#
FROM J
WHERE NOT EXISTS
( SELECT *
FROM SPJ
WHERE SPJ.J# = J.J#
AND NOT ( SPJ.S# = 'SI' ) ) ;
7.15.42.SELECT P.P#
FROM P
WHERE NOT EXISTS
( SELECT *
FROM J
WHERE J.CITY = 'London'
AND NOT EXISTS
( SELECT *
FROM SPJ
WHERE SPJ.P# = P.P#
AND SPJ.J# = J.J# ) ) ;
7.15.43.SELECT S.S#
FROM S
WHERE EXISTS
( SELECT *
FROM P
WHERE NOT EXISTS
( SELECT *
FROM J
WHERE NOT EXISTS
( SELECT *
FROM SPJ
WHERE SPJ.S# = S.S#
AND SPJ.P# = P.P#
AND SPJ.J# = J.J# ) ) ) ;
7.15.44.SELECT J.J#
FROM J
WHERE NOT EXISTS
( SELECT *
FROM SPJ AS SPJX
WHERE SPJX.S# = 'SI'
AND NOT EXISTS
Глава 7. Реляционное исчисление
299
( SELECT *
FROM SPJ AS SPJY
WHERE SPJY.P# = SPJX.P#
AND SPJY.J# = J.J# ) ) ;
7.15.45.SELECT S.CITY FROM S
UNION
SELECT P.CITY FROM P
UNION
SELECT J.CITY FROM J ;
7.15.46.SELECT DISTINCT SPJ.P#
FROM SPJ
WHERE ( SELECT S.CITY
FROM S
WHERE S.S# = SPJ.S# ) = 'London'
OR ( SELECT J.CITY
FROM J
WHERE J.J# = SPJ.J# ) = 'London' ;
7.15.47.SELECT S.S#, P.P#
FROM S CROSS JOIN P
EXCEPT
SELECT SPJ.S#, SPJ.P#
FROM SPJ ;
7.15.48. Решение опущено.
7.15.49-7.15.50. Решений не существует.
300
Часть II. Реляционная модель
Глава
Целостность данных
8.1. Введение
Термин целостность данных используется для описания точности и корректности
хранящейся в базе информации. Как отмечалось в главе 3, в базе данных может сущест-
вовать любое количество ограничений целостности и в общем случае они могут быть
произвольной сложности. Например, для базы данных поставщиков и деталей можно
предположить, что номера поставщиков должны представляться в виде 'Злллл' (где
лллл — десятичное число, не превышающее 9999) и иметь уникальные значения; значе-
ния статуса поставщика должны находиться в диапазоне от 1 до 100, причем поставщики
из Лондона должны иметь статус 20; количество поставляемых деталей должно быть
кратно 50, причем красные детали должны храниться только в Лондоне; и т.д. В общем
случае можно сделать заключение, что СУБД должно быть известно о подобных ограни-
чениях и, безусловно, необходимо, чтобы СУБД тем или иным образом обеспечивала их
выполнение (в основном, посредством отмены любых обновлений, нарушающих эти
требования). Рассмотрим следующий пример (снова воспользуемся языком Tutorial D).
CONSTRAINT SC3
IS_EMPTY ( S WHERE STATUS < 1 OR STATUS > 100 ) ;
Смысл этого выражения таков: “Значения статуса поставщика должны находиться в
диапазоне от 1 до 100”. Обратите внимание на имя ограничения— SC3 (т.е.
“Ограничение № 3 для поставщиков”). Под этим именем данное ограничение будет заре-
гистрировано в системном каталоге и именно это имя будет указываться в диагностиче-
ских сообщениях системы при обнаружении попыток нарушения данного ограничения.
Само ограничение задается в виде логического выражения, результат вычисления кото-
рого не должен иметь значение ложь (false).
Замечание. Для определенности здесь мы используем алгебраическую версию языка
Tutorial D, поэтому логическое выражение часто будет принимать форму IS_EMPTY(...),
которая означает, что в базе данных нет данных, нарушающих указанное ограничение
(см. раздел 6.9 главы 6). Аналог приведенного выше примера в виде выражения реляци-
онного исчисления может выглядеть следующим образом1.
CONSTRAINT SC3
FORALL SX ( SX.STATUS > 1 AND SX.STATUS < 100 ) ;
1 На практике бытует мнение, что ограничения (особенно сложные) легче формулировать в
терминах реляционного исчисления, а не посредством выражений реляционной алгебры. В этой гла-
ве мы остановимся на алгебраических выражениях в соответствии с принципами изложения мате-
риала в остальной части книги, но читателю, несомненно, будет полезно поупражняться в преоб-
разовании некоторых из приводимых ниже примеров в выражения реляционного исчисления.
Глава 8. Целостность данных
301
Здесь SX — переменная кортежа, которая изменяется на отношении поставщиков S.
По ходу отметим, что логическое выражение в ограничениях, представленных в виде
выражений реляционного исчисления, должно быть закрытой формулой WFF (см. раз-
дел 7.2 главы 7) и чаще всего будет иметь форму FORALL х(...). Следовательно, выраже-
ние в данном примере означает, что все значения статуса поставщиков должны нахо-
диться в указанном диапазоне. На практике, конечно, достаточно, чтобы система просто
проверяла лишь вновь вводимые или обновляемые значения статуса поставщиков, а не
все те значения, которые уже хранятся в базе данных.
После того как новое ограничение будет объявлено, необходимо, чтобы оно было
проверено системой, т.е. нужно убедиться, что база данных в текущий момент удовле-
творяет вновь установленному ограничению. Если это не так, новое ограничение отвер-
гается; в противном случае оно принимается (т.е. сохраняется в каталоге) и с этого мо-
мента вступает в силу. Объявление в системе приведенного выше ограничения приведет
к тому, что СУБД будет контролировать все операции, которые подразумевают вставку
кортежа для нового поставщика или изменение статуса существующего поставщика.
Конечно, дополнительно требуется, чтобы существовала возможность отмены уста-
новленного ранее ограничения.
DROP CONSTRAINT <имя ограничениям ;
Например:
DROP CONSTRAINT SC3 ;
Замечание. Как вы, наверное, уже заметили, наше обсуждение сосредоточено на
декларативной поддержке ограничений целостности. К сожалению, на сегодняшний
день лишь немногие продукты предоставляют что-либо существенное в плане реали-
зации такой поддержки, хотя ситуация в этом направлении пусть медленно, но все же
улучшается. В некоторых продуктах (особенно в нереляционных) практикуется совсем
другой подход, т.е. применяется процедурная поддержка ограничений целостности,
построенная на использовании хранимых, или триггерных, процедур2. Однако мож-
но предположить, что если бы существующие СУБД действительно предоставляли не-
обходимую декларативную поддержку, то по крайней мере 90% текста определений
типичной базы данных составляли бы объявления ограничений целостности данных.
Таким образом, предоставляющая подобную поддержку система значительно облегчи-
ла бы труд прикладных программистов и позволила бы существенно повысить произ-
водительность их труда. Декларативная поддержка ограничений целостности является
очень важным аспектом СУБД.
Прежде чем перейти к следующему вопросу, отметим, что в реляционной мо-
дели на протяжении последних лет точка зрения на проблему поддержки целост-
ности данных претерпевает изменения в большей степени, чем другие (пожалуй,
2 Хранимые, или триггерные, процедуры — это заранее скомпилированные процедуры, кото-
рые могут вызываться из прикладных программ. В качестве примера можно упомянуть опреде-
ленные пользователем операторы ABS, DIST, REFLECT и т.д., которые рассматривались в разде-
ле 5.2 (подраздел “Объявление оператора"). Такие процедуры логически можно рассматривать
как расширение СУБД (в системах клиент/сервер они чаще всего хранятся и выполняются на
сервере). Мы еще поговорим об этих процедурах в разделе 8.8, в аннотациях к некоторым публи-
кациям в конце данной главы, а также в главе 20.
302
Часть II. Реляционная модель
точнее будет сказать, эволюционирует). Как отмечалось в главе 3, изначально ак-
цент делался на первичных и внешних ключах (для краткости — просто на
“ключах”). Однако со временем особое — даже ключевое! — значение ограниче-
ний целостности в общей картине осознавалось во все большей степени и оцени-
валось все выше. Одновременно начали возникать некоторые щекотливые вопро-
сы, в частности относительно ключей. Структура этой главы отражает такое сме-
щение акцентов, поскольку в начале (и еще в нескольких разделах) рассматрива-
ется общая проблема ограничений целостности, а затем — ключи, которые по-
прежнему имеют большое практическое значение.
Схема классификации ограничений
В [3.3] ограничения целостности классифицируются по четырем основным категори-
ям: ограничения типа (домена), атрибута, переменной-отношения и базы данных.
В ограничениях типа задаются допустимые значения для данного типа.
Замечание. В этой главе под типом подразумевается скалярный тип. Типы отно-
шений, конечно, также являются объектами ограничений типов, но они представ-
ляют собой, по существу, просто логическое следствие ограничений типа, которые
применяются к скалярным типам и в терминах которых эти типы отношений в ко-
нечном счете определены.
В ограничениях целостности атрибута задаются допустимые значения для дан-
ного атрибута.
В ограничениях целостности переменной-отношения задаются допустимые значе-
ния для данной переменной-отношения.
В ограничениях целостности базы данных задаются допустимые значения для
этой базы данных.
Подробнее указанные виды ограничений рассматриваются в разделах 8.2-8.5 соот-
ветственно.
8.2. Ограничения типа
По существу, ограничение типа является перечнем (или логическим эквивалентом
перечня) допустимых значений типа. Вот простой пример ограничения типа для типа
WEIGHT (Вес).
TYPE WEIGHT POSSREP ( RATIONAL )
CONSTRAINT THE_WEIGHT ( WEIGHT ) > 0.0 ;
Мы принимаем очевидное соглашение, по которому в ограничении типа можно ис-
пользовать подходящее имя типа, призванное обозначить произвольное значение рас-
сматриваемого типа. В данном случае допустимы только такие значения веса детали,
которые могут быть представлены рациональным числом, большим нуля. Любое вы-
ражение, в котором предполагается определение веса, но в результате вычисления ко-
торого получается значение, не удовлетворяющее приведенному выше ограничению,
будет отвергнуто.
Глава 8. Целостность данных
303
Замечание. Если вам необходимо восстановить в памяти назначение операторов
POSSREP и ТНЕ_, возвратитесь к главе 5.
Напомним, что ограничение типа является, в общем, просто перечнем значений, ко-
торые составляют данный тип. Следовательно, в языке Tutorial D мы связываем такие
ограничения с определениями соответствующих типов и идентифицируем их посредст-
вом соответствующего имени типа. (Поэтому ограничение типа может быть упразднено
лишь в том случае, если будет исключен сам тип.)
Таким образом, совершенно ясно, что единственный способ, с помощью которого в
результате вычисления произвольного выражения может быть получено значение типа
WEIGHT, состоит в обращении к некоторому оператору выбора значений типа WEIGHT. По-
этому любое выражение лишь в том случае не сможет нарушить ограничения для типа
WEIGHT, если нарушение этих ограничений будет проверяться используемым в выраже-
нии оператором выбора. Следовательно, можно считать (по крайней мере, концепту-
ально), что в любом случае соблюдение ограничений типа контролируется именно во
время выполнения некоторым оператором выбора. Дополнительно можно сказать, что
ограничения типа всегда проверяются немедленно, а значит, ни одна переменная-
отношение не может получить значение какого-либо атрибута в каком-либо кортеже, ко-
торый не соответствовал бы требуемому типу (конечно, в такой системе, где имеется
поддержка ограничений типов).
Вот еще один пример ограничения типа.
TYPE POINT POSSREP CARTESIAN ( X RATIONAL, Y RATIONAL )
CONSTRAINT ABS ( THE_X (POINT) ) < 100.0 AND
ABS ( THE_Y (POINT) ) < 100.0 ;
Здесь контроль типа осуществляется (концептуально) в результате обращения к опе-
ратору выбора CARTESIAN. Обратите внимание на применение определенного пользова-
телем оператора ABS (см. раздел 5.2 главы 5).
Приведем более сложный пример — определение типа компонентов эллипса.
TYPE ELLIPSE POSSREP ( A LENGTH, В LENGTH, CTR POINT )
CONSTRAINT THE_A ( ELLIPSE ) > THE_B ( ELLIPSE ) ;
Здесь представлены возможные компоненты, а именно — А, В и CTR, которые соот-
ветствуют длине большой полуоси а, длине малой полуоси b и точке центра ctr рассмат-
риваемого эллипса. Предположим, что скалярная переменная Е объявлена с типом
ELLIPSE, ее текущее значение длины большой полуоси равно 5, а значение длины малой
полуоси равно 4. Теперь рассмотрим следующее присвоение.
ТНЕ_В ( Е ) := LENGTH ( 6.0 ) ;
Замечание. В этом примере скалярная переменная и операция скалярного присвоения
используются исключительно из соображений упрощения, поэтому вместо них с тем же
успехом можно было использовать, скажем, переменную-отношение и операцию реля-
ционного присвоения.
Это присвоение, как и следует ожидать, будет отвергнуто, однако ошибочным явля-
ется не само присвоение как таковое. Ошибка будет зафиксирована, опять же, при вы-
полнении оператора выбора (хотя никакого прямого вызова подобного оператора в при-
304
Часть II Реляционная модель
своении не видно), поскольку в действительности данное присвоение является сокраще-
нием следующего выражения3.
Е := ELLIPSE ( ТНЕ_А ( Е ), LENGTH ( 6.0 ), THE_CTR ( Е ) ) ;
Здесь в правой части операции присвоения явно показано обращение к оператору вы-
бора, при выполнении которого и будет зафиксирована ошибка.
8.3. Ограничения атрибута
Ограничение атрибута по своей сути является простым объявлением о том, что опре-
деленный атрибут имеет определенный тип. В качестве примера еще раз обратимся к оп-
ределению переменной-отношения поставщиков.
VAR S BASE RELATION
{ S# S#,
SNAME NAME,
STATUS INTEGER,
CITY CHAR } ... ;
В этой переменной-отношении значения атрибутов S#, SNAME, STATUS и CITY ог-
раничены типами S#, NAME, INTEGER и CHAR соответственно. Другими словами, огра-
ничения атрибутов являются частью определения этих атрибутов и могут быть иден-
тифицированы по соответствующим именам атрибутов. Отсюда следует, что огра-
ничение атрибута может быть устранено только путем удаления самого атрибута
(что на практике чаще всего означает удаление переменной-отношения, включаю-
щей данный атрибут).
Замечание. В принципе, любая попытка ввести в базу данных значение атрибута,
имеющее тип, отличный от того, который был установлен для данного атрибута, будет
отвергнута. Однако на практике такие ситуации никогда не должны возникать, если
только в системе применяются ограничения типа, описанные в предыдущем разделе.
8.4. Ограничения переменной-отношения
Ограничение переменной-отношения — это ограничение для некоторой отдельной
переменной-отношения (оно выражается лишь через рассматриваемую переменную-
отношение, хотя, с другой стороны, может быть сколь угодно сложным). Вот несколь-
ко примеров.
CONSTRAINT SC5
IS_EMPTY ( S WHERE CITY = 'London' AND STATUS * 20 ) ;
Смысл: “Поставщики в Лондоне должны обладать статусом, равным 20”.
3 Иначе говоря (и несмотря на то, что мы явно не ссылались на главу 5), псевдопеременные
THE не являются логически необходимыми! Любое присвоение значения псевдопеременной THE
всегда логически эквивалентно (и фактически было определено просто как сокращенная запись)
присвоению обычной переменной результата вызова определенного оператора выбора.
Глава 8. Целостность данных
305
CONSTRAINT PC4
IS_EMPTY ( P WHERE COLOR = COLOR ( 'Red' ) )
AND CITY * 'London' ) ;
Смысл: “Красные детали должны храниться в Лондоне”.
CONSTRAINT SCK
COUNT ( S ) = COUNT ( S { S# } ) ;
Смысл: “Номера поставщиков должны быть уникальны” или, более формально,
“Ключ {S#} —это потенциальный ключ отношения поставщиков” (раздел 8.8).
CONSTRAINT РС7
IF NOT ( IS_EMPTY ( P ) ) THEN
COUNT ( P WHERE COLOR = COLOR ( 'Red' ) ) > 0
END IF ;
Смысл: “Если детали вообще имеются, то одна из них должна быть красной”. Отме-
тим, кстати, что этот пример отличается от всех рассмотренных ранее, поскольку данное
ограничение может быть нарушено и при выполнении операции DELETE.
Ограничения переменных-отношений всегда проверяются немедленно (фактически
как часть процедуры выполнения любого оператора, способного нарушить данное огра-
ничение). Таким образом, любой оператор, в котором предпринимается попытка присво-
ить данной переменной-отношению значение, нарушающее одно из установленных для
нее ограничений, будет просто отвергнут.
8.5. Ограничения баз данных
Ограничение базы данных — это ограничение, устанавливающее взаимосвязь между
различными переменными-отношениями. Приведем несколько примеров.
CONSTRAINT DBC1
IS_EMPTY ( ( S JOIN SP )
WHERE STATUS < 20 AND QTY > QTY ( 500 ) ) ;
Смысл: “Поставщики co статусом, меньшим 20, не могут поставлять детали в количе-
стве свыше 500 штук”.
Упражнение. Какие операции должны отслеживаться СУБД для приведения ограни-
чения DBC1 в действие?
CONSTRAINT DBC2 SP { S# } < S { S# } ;
Смысл: “Каждый номер поставщика в переменной-отношении поставок должен при-
сутствовать и в переменной-отношении поставщиков”. (Напомним, что, как указывалось
в главе 6, знак здесь означает “подмножество”.) Поскольку атрибут S# в переменной-
отношении S составляет потенциальный ключ, по сути, это ограничение является ссы-
лочным ограничением для поставок в отношении поставщиков (т.е. ключ {S#} в пере-
менной-отношении SP является внешним ключом, посредством которого сведения о по-
ставках связываются с соответствующими поставщиками). Обсуждение этого вопроса
будет продолжено в разделе 8.8.
CONSTRAINT DBC3 SP { P# } = Р { P# } ;
306
Часть II. Реляционная модель
Смысл: “Каждая деталь должна быть поставлена хотя бы один раз”.
Замечание. Конечно, возможен случай, когда каждая поставка включает точно одну
деталь, как следствие того факта, что ключ {P#} в переменной-отношении Р является по-
тенциальным ключом для деталей и существует ссылочное ограничение в отношении по-
ставок и деталей. Однако мы не будем приводить это ограничение здесь, а обсуждение
данного вопроса продолжим, опять же, в разделе 8.8.
Последние два примера показывают, что (в общем случае) проверка ограничений ба-
зы данных не может быть выполнена немедленно, а должна быть отложена до конца
транзакции, т.е. до момента выполнения оператора COMMIT (при необходимости уточнить
какие-либо сведения относительно оператора COMMIT; см. главу 3). Для доказательства
этого утверждения допустим противное и предположим, что проверка должна выпол-
няться немедленно. Пусть в данный момент вообще отсутствуют сведения о каких-либо
поставках и деталях. Тогда добавление сведений о любой детали будет ошибочным, по-
скольку при этом будет нарушено ограничение DBC3. Аналогично любая попытка ввести
сведения о поставке также приведет к ошибке, поскольку в этом случае будет нарушено
ограничение DBC24.
Если во время выполнения оператора COMMIT будет обнаружено нарушение ограниче-
ния базы данных, это вызовет откат данной транзакции.
8.6. “Золотое правило”
Замечание. Материал этого раздела имеет фундаментальное значение. Однако во-
просы, которые здесь рассматриваются, на практике, к сожалению, не нашли ни ши-
рокой поддержки, ни даже достаточного понимания, хотя, в принципе, они довольно
простые. Предупреждение для читателя.
В разделе 3.4 главы 3 мы установили, что любое отношение имеет связанный с
ним предикат, а кортежи этого отношения выражают истинные высказывания, по-
рождаемые данным предикатом. В разделе 5.3 главы 5 упоминалось допущение
замкнутости мира, согласно которому, если в определенном отношении не сущест-
вует определенного кортежа, мы имеем право предположить, что соответствующее
ему высказывание ложно.
Мы не подчеркивали этот факт прежде, но читателю должно быть понятно, что пере-
менная-отношение тоже имеет предикат, а именно — предикат, который будет общим
для всех возможных отношений, представляющих допустимые значения для данной пе-
ременной-отношения. Например, рассмотрим переменную-отношение поставщиков S.
Предикат для этой переменной-отношения можно сформулировать примерно так.
Поставщик с данным номером поставщика (Si) имеет данное имя (SNAME), дан-
ное значение статуса (STATUS) и размещается в данном городе (CITY), кроме
того, в любой заданный момент никакие два поставщика не имеют одинаковых
номеров поставщика.
4 В действительности в [3.3] предлагается множественная форма присвоения, которая по-
зволила бы вставлять детали и поставки в пределах одной операции. Если бы такие операции
присвоения поддерживались системой, то ограничения базы данных могли бы контролироваться
немедленно
Глава 8. Целостность данных
307
Это утверждение и не точное, и не полное, но вполне приемлемое для наших целей.
Также должно быть понятно, что предикат данной переменной-отношения по свой
сути является критерием приемлемости изменений для рассматриваемой переменной-
отношения, т.е. он предписывает, будет ли допустима определенная операция INSERT,
UPDATE или DELETE для данной переменной-отношения. Например, попытка вставить све-
дения о новом поставщике с тем же номером поставщика, что и номер уже существую-
щего поставщика, несомненно, должна быть отвергнута.
Следовательно, в идеальном случае СУБД должен быть известен и понятен предикат
каждой переменной-отношения в базе данных, что позволит системе корректно обраба-
тывать всевозможные попытки внесения изменений. Но такая цель, конечно, недости-
жима. Например, не существует способа сформулировать для СУБД понятие о том, что
определенный поставщик должен быть “в” определенном городе. Также неясно, каким
образом СУБД может быть заранее известно, что предикат для переменной-отношения
поставщиков является таким, что, например, первый из приведенных ниже кортежей бу-
дет допустимым, а второй — нет.
{ S# : S# ( 'S1' ) ,
SNAME : NAME ( 'Smith' ) ,
STATUS : 20
CITY : 'London' }
{ S# : S# ( 'S6' )
SNAME : NAME ( 'Smith' ) ,
STATUS : 50 ,
CITY : 'Rome' }
Конечно, если пользователь предоставит последний кортеж для ввода в базу дан-
ных, то все, что система сможет сделать, — это убедиться, что никаких нарушений из-
вестных ей ограничений целостности нет. И, несомненно, система затем примет кор-
теж для добавления в базу данных и в дальнейшем будет воспринимать его как ис-
тинное высказывание.
Итак, можем сделать вывод, что система “не знает и не понимает” (и “не может знать
и понимать”) предикат переменной-отношения поставщиков на все 100%. Однако ей из-
вестно достаточно хорошее приближение к этому предикату, а конкретнее — ей из-
вестны ограничения целостности, которые применимы к записям о поставщиках. Следо-
вательно, мы определяем предикат переменной-отношения для переменной-
отношения поставщиков (или в общем случае для любой переменной-отношения) как ло-
гическое умножение (логическая операция И) всех ограничений переменной-отношения,
которые установлены для данной переменной-отношения. Например, предикат перемен-
ной-отношения для переменной-отношения S выглядит примерно так.
( IS_EMPTY ( S WHERE STATUS < 1 OR STATUS > 100 ) ) AND
( IS_EMPTY ( S WHERE CITY = 'London' AND STATUS * 20 ) ) AND
( COUNT ( S ) = COUNT ( S { S# } ) )
(Кроме того, системе, конечно, известно, что атрибуты S#, SNAME, STATUS и CITY
должны иметь типы S#, NAME, INTEGER и CHAR соответственно.)
308
Часть II. Реляционная модель
Отметим, что реально существуют два предиката, связанных с любой данной пере-
менной-отношением: неформальный, или внешний, предикат, который понятен поль-
зователям, но непонятен системе, и формальный, или внутренний, который понятен и
пользователям, и системе. Конечно, внутренним предикатом является именно тот пре-
дикат, который мы подразумеваем под “предикатом переменной-отношения”, и имен-
но внутренний предикат система проверяет всякий раз, когда предпринимаются по-
пытки изменить данную переменную-отношение. В дальнейшем под термином преди-
кат (когда он используется в связи с переменной-отношением) мы будем подразуме-
вать именно внутренний предикат, кроме случаев, когда явно будет указано противо-
положное.
Исходя из предшествующих определений теперь можно сформулировать золотое
правило (по крайней мере его первую версию).
Ни одна из операций изменения не имеет права переводить переменную-
отношение в состояние, нарушающее ее собственный предикат.
Необходимо также подчеркнуть, что в этом случае под переменной-отношением не-
обязательно подразумевается непременно базовая переменная-отношение. Золотое пра-
вило применимо ко всем переменным-отношениям, как к базовым, так и к производным.
В следующей главе мы возвратимся к этому вопросу.
В завершение раздела отметим, что точно так, как для каждой переменной-отно-
шения имеется некоторый связанный с ней предикат, так и для всей базы данных имеет-
ся связанный с ней предикат базы данных, который определяется как логическое ум-
ножение (логическая операция И) всех ограничений базы данных и всех ограничений пе-
ременных-отношений, которые были установлены в этой базе данных. Поэтому мы мо-
жем расширить формулировку золотого правила следующим образом5.
Ни одна из операций изменения не имеет права переводить переменную-
отношение в состояние, нарушающее ее собственный предикат. Аналогично ни
одна из транзакций изменения не имеет права переводить базу данных в со-
стояние, нарушающее ее собственный предикат.
8.7. Ограничения состояния и ограничения
перехода
Во всех описанных до сих пор примерах были представлены ограничения состоя-
ния, поскольку они касались тех или иных состояний базы данных. Однако иногда
необходимо также учитывать ограничения перехода, т.е. ограничения для допустимых
вариантов перехода от одного корректного состояния к другому. Например, в базе
данных персонала может быть установлено множество ограничений перехода, связан-
ных с внесением изменений в сведения о семейном положении. Примерами допусти-
мых типов переходов в этом случае могут служить следующие:
5 Если бы система поддерживала операцию множественного присвоения (на эту возмож-
ность указывалось в предыдущей сноске), то можно было бы сохранить формулировку золотого
правила в его первоначальной и более простой форме.
Глава 8. Целостность данных
309
никогда не состоял в браке — состоит в браке;
состоит в браке — овдовел;
состоит в браке — разведен;
разведен — состоит в браке.
Среди недопустимых типов переходов можно назвать такие:
никогда не состоял в браке — овдовел;
никогда не состоял в браке — разведен;
овдовел — разведен;
разведен — овдовел.
Возвращаясь к примеру базы данных поставщиков и деталей, можно привести при-
мер ограничения перехода, утверждающего, что “статус поставщика никогда не должен
уменьшаться”.
CONSTRAINT TRC1 IS_EMPTY
( ( ( S' { S#, STATUS } RENAME STATUS AS STATUS' )
JOIN S { S#, STATUS } )
WHERE STATUS' > STATUS ) ;
Пояснение. Здесь мы ввели соглашение о том, что имя исходной переменной-
отношения, подобное S' в данном примере, понимается как имя соответствующей пе-
ременной-отношения, которая существовала до выполнения рассматриваемой опера-
ции обновления. С учетом этого замечания представленное выше ограничение можно
интерпретировать так. Если мы соединим (по номеру поставщика) отношение, которое
являлось значением переменной-отношения S до выполнения обновления с отношени-
ем, которое является значением этой переменной-отношения после выполнения об-
новления, а затем выберем из результата этого соединения все кортежи, в которых
старое значение статуса поставщика больше, чем новое, то конечный результат дол-
жен быть пустым отношением. (Поскольку соединение выполняется по номерам по-
ставщиков, любой полученный в результате выполнения соединения кортеж, для кото-
рого значение старого статуса больше, чем новое, должен представлять поставщика,
статус которого понизился.)
Замечание. Поскольку ограничение перехода TRC1 задано для переменной-
отношения (применяется к единственной переменной-отношению, в данном слу-
чае — к переменной-отношению поставщиков), оно должно проверяться немед-
ленно. Ниже для сравнения приводится пример ограничения перехода для базы
данных (“Общее количество любых заданных деталей для всех поставщиков мо-
жет только возрастать”).
CONSTRAINT TRC2 IS_EMPTY
( ( ( SUMMARIZE SP' PER S' { S# } ADD SUM ( QTY ) AS SQ' )
JOIN
( SUMMARIZE SP PER S { S# } ADD SUM ( QTY ) AS SQ ) )
WHERE SQ' > SQ ) ;
310
Часть II. Реляционная модель
Поскольку ограничение перехода TRC2 задано для базы данных (оно включ< > две
различные переменные-отношения — поставщиков и поставок), его проверка бу. т от-
ложена до момента выполнения оператора COMMIT. Здесь имена исходных переме ных-
отношений S' и SP' используются для обозначения соответственно переменных-
отношений S и SP в момент до начала выполнения транзакции
Для ограничений типов и атрибутов противопоставление ограничений состоя! 1я и
перехода лишено смысла.
8.8. Ключи
В реляционной модели всегда делался акцент на понятии ключей, хотя, как мы уже
видели, на самом деле они являются лишь частным случаем (хотя и очень важным) неко-
торого более общего явления. В этом разделе мы вновь обратимся к понятию ключа и
рассмотрим его более подробно.
Замечание Основная идея понятия ключа достаточно проста, но, к сожалению, имеет
место одно существенное затруднение — NULL-значения. Возможность того, что, на-
пример, для данного внешнего ключа разрешены NULL-значения, существенно услож-
няет дело. Однако проблема NULL-значений представляет собой отдельную обширную
тему для обсуждения и было бы нецелесообразно рассматривать ее в настоящий момент.
Поэтому по методическим соображениям в настоящем разделе мы практически не будем
обращать внимания на ее существование. Мы вернемся к ней в главе 18 и рассмотрим
проблему NULL-значений в общем случае, в частности рассмотрим, как эти значения
влияют на понятие ключа. (На самом деле, по нашему твердому убеждению, понятие
NULL-значения является ошибочным и совсем не должно использоваться, но было бы
неправильным полностью игнорировать его в подобной книге.)
Потенциальные ключи
Пусть R — некоторая переменная-отношение. По определению множество всех атри-
бутов переменной-отношения R обладает свойством уникальности, т е. в любой момент
в значении переменной-отношении R никакие два кортежа не дублируют друг друга. На
практике же часто некоторое допустимое подмножество множества всех атрибутов пе-
ременной-отношения R также обладает подобным свойством уникальности. Например, в
переменной-отношении поставщиков S этим свойством обладает подмножество из одно-
го атрибута S#. Подобные случаи служат основой интуитивного понимания смысла фор-
мального определения потенциального ключа.
Пусть К — множество атрибутов переменной-отношения R. В этом случае множе-
ство К будет потенциальным ключом переменной-отношения R тогда и только
тогда, когда оно обладает следующими свойствами6.
а) Уникальность. Никакие допустимые значения переменной-отношения R не
содержат двух различных кортежей с одинаковыми значениями атрибутов
множества К.
6 Обратите внимание, что определение применяется именно к переменным-отношениям
Аналогичное понятие можно определить и для значений отношения (см [3 3J), но переменные-
отношения представляют более важный случай
Глава 8. Целостность данных
311
б) Неизбыточность. Никакое из собственных подмножеств множества К не обла-
дает свойством уникальности.
Обратите внимание, что каждая переменная-отношение имеет по крайней мере
один потенциальный ключ. Свойство уникальности подобных ключей не требует до-
полнительных разъяснений. Относительно свойства неизбыточности следует предос-
тавить некоторые пояснения. Суть в том, что если определить “потенциальный ключ”,
который не будет обладать свойством неизбыточности, системе об этом ничего не бу-
дет известно и она не сможет должным образом обеспечить выполнение соответст-
вующего ограничения целостности. Пусть, например, мы определили потенциальный
ключ отношения поставщиков не как атрибут S#, а как комбинацию атрибутов
{S#,CITY}. Тогда система не сможет соблюдать ограничение, требующее “глобальной”
уникальности номера поставщика; вместо этого в ней будет поддерживаться более
слабое ограничение, согласно которому номер поставщика должен быть уникальным в
масштабе одного города. По этой причине среди прочих условий требуется, чтобы по-
тенциальные ключи не содержали какие-либо атрибуты, которые не имеют отношения
к обеспечению его уникальной идентификации7.
Довольно часто в литературе (включая предыдущие издания этой книги) понятие не-
избыточности в указанном выше смысле иначе называется минимальностью. Однако
“минимальность” — это не совсем точное выражение, поскольку, когда мы говорим, что
потенциальный ключ К1 “минимален”, это не означает, что не существует другого по-
тенциального ключа К2 с меньшим количеством атрибутов. Вполне возможно, например,
что ключ К1 состоит из четырех атрибутов, а ключ К2 — только из двух. Поэтому здесь
будет использоваться термин “неизбыточность”.
Для описания потенциального ключа в определении переменной-отношения будем
использовать следующий синтаксис языка Tutorial D.
KEY { <список имен атрибутов> }
Ниже приведено несколько примеров.
VAR S BASE RELATION
{ S# Sfl,
SNAME NAME,
STATUS INTEGER,
CITY CHAR }
KEY { S# } ;
Замечание. В предыдущей главе мы уже приводили это определение с ис-
пользованием фразы PRIMARY KEY вместо KEY. Подробности можно найти в
подразделе “Первичные и альтернативные ключи”, приведенном ниже в
этом разделе.
7 Другой веской причиной, по которой от потенциальных ключей требуется отсутствие
избыточности, является требование их соответствия внешним ключам. Любой внешний ключ,
который ссылается на “избыточный” потенциальный ключ (если бы такое было возможно), был
бы также “избыточным ”, и содержащая его переменная отношения почти наверняка нарушала
бы принципы дополнительной нормализации (глава 11).
312
Часть II. Реляционная модель
VAR SP BASE RELATION
{ S# S#,
P# P#,
QTY QTY }
KEY { S#, P# } ... ;
В этом примере показана переменная-отношение с составным потенциальным
ключом (т.е. с потенциальным ключом, содержащим более одного атрибута).
Потенциальный ключ, состоящий из одного атрибута, называется простым.
VAR ELEMENT BASE RELATION {NAME NAME,
SYMBOL CHAR,
ATOMIC# INTEGER }
KEY { NAME }
KEY { SYMBOL }
KEY { ATOMIC# } ;
В этом примере показана переменная-отношение с несколькими различными
(простыми) потенциальными ключами.
VAR MARRIAGE BASE RELATION {HUSBEND /* Муж */ NAME,
WIFE /* Жена */ NAME,
DATE /* Дата бракосочетания */ DATE }
/* Подразумевается, что муж может иметь лишь одну жену, а жена */
/* лишь одного мужа, а также, что каждый из супругов состоит в */
/* браке первый раз */
• KEY { HUSBEND, DATE }
KEY { DATE, WIFE }
KEY { WIFE, HUSBEND } ;
В этом примере показана переменная-отношение с несколькими различными
составными (и перекрывающимися) потенциальными ключами.
Конечно, как указывалось в разделе 8.4, определение потенциального ключа, по
существу, представляет собой просто сокращенную запись определенного ограниче-
ния переменной-отношения. Эта сокращенная запись весьма удобна, поскольку по-
нятие потенциального ключа очень важно с практической точки зрения. Говоря кон-
кретнее, в реляционной модели потенциальные ключи обеспечивают основной ме-
ханизм адресации на уровне кортежей. Это утверждение означает, что единствен-
ный гарантируемый системой способ точно указать на какой-то конкретный кортеж
состоит в указании значения одного из его потенциальных ключей. Например, с по-
мощью приведенного ниже выражения гарантированно будет получено не более од-
ного кортежа (точнее, будет получено отношение, состоящее не более чем из одно-
го кортежа).
S WHERE S# = S# ( 'S3' )
В противоположность этому при задании следующего выражения в общем случае бу-
дет получено количество кортежей, которое нельзя предсказать заранее.
S WHERE CITY = 'Paris'
Глава 8. Целостность данных
313
Таким образом, потенциальные ключи имеют такое же фундаментальное значение
для успешной работы реляционной системы, как адресация основной памяти для ус-
пешной работы машины, на которой эта система установлена. В качестве выводов из
этого утверждения можно привести следующее.
1 . “Переменные-отношения”, которые не имеют потенциальных ключей (т.е.
“переменные-отношения”, допускающие дублирование кортежей), при опреде-
ленных обстоятельствах способны вызвать нетипичное или аномальное поведе-
ние системы.
2 . Система, которая не имеет сведений о потенциальных ключах, в некоторых случаях
будет демонстрировать поведение, отличное от “действительно реляционного”, да-
же если используемые в ней переменные-отношения являются истинными пере-
менными-отношениями и не допускают дублирования кортежей.
Упомянутое выше “нетипичное или аномальное” либо “отличное от типично реляци-
онного” поведение чаще всего будет связано с такими процессами, как обновление пред-
ставлений и оптимизация (подробности приводятся в главах 9 и 17 соответственно).
Прежде чем завершить этот подраздел, укажем на некоторые особенности потенци-
альных ключей.
Надмножество потенциального ключа является суперключом. Например, мно-
жество атрибутов {S#,CITY}— это суперключ переменной-отношения S. Су-
перключ обладает свойством уникальности, но необязательно — свойством не-
избыточности (поэтому потенциальный ключ, естественно, является частным
случаем суперключа).
Если множество SK является суперключом переменной-отношения R и А — это ат-
рибут переменной-отношения R, то функциональная зависимость SK —> А в пере-
менной-отношении R является истинной (эта важная концепция подробно будет
обсуждаться в главе 10). Фактически суперключ можно определить как подмно-
жество SK, состоящее из таких атрибутов переменной-отношения R, что функцио-
нальная зависимость SK —> А является истинной для всех атрибутов А перемен-
ной-отношения R.
И наконец, обратите внимание на то, что логическое понятие потенциального
ключа не следует путать с физическим понятием “уникального индекса”, хотя по-
следний часто используется для реализации потенциальных ключей. Другими сло-
вами, для потенциального ключа вовсе не обязательно должен существовать ин-
декс (или другой специальный физический путь доступа, ведущий к отдельным
значениям этого ключа). Конечно, на практике такой специальный путь доступа,
возможно, будет существовать, но вопрос о том, существует ли он, выходит за
рамки реляционной модели как таковой.
Первичные и альтернативные ключи
Как мы уже убедились, некоторые переменные-отношения вполне могут иметь не-
сколько потенциальных ключей. В таком случае в реляционной модели по традиции (по
крайней мере, в случае базовой переменной-отношения) один из потенциальных ключей
должен быть выбран в качестве первичного ключа, а все остальные потенциальные
314
Часть II. Реляционная модель
ключи будут называться альтернативными. В приведенном выше в этой главе примере
с переменной-отношением ELEMENT в качестве первичного ключа можно выбрать атрибут
обозначения элемента {SYMBOL}; тогда атрибут названия элемента {NAME} и атрибут
атомного числа элемента {ATOMIC#} будут альтернативными ключами. В том случае, ко-
гда в базовой переменной-отношении существует только один потенциальный ключ, со-
гласно реляционной модели (опять же, традиционно) именно он должен быть выбран в
качестве ее первичного ключа. Следовательно, каждая базовая переменная-отношение
всегда должна иметь первичный ключ.
Выбор одного потенциального ключа (если есть из чего выбирать) в качестве первич-
ного, определенно, желателен во многих случаях (даже в большинстве случаев), но это
не означает, что во всех случаях. Аргументы в пользу этой точки зрения приведены в
[8.13]. Здесь же мы просто отметим, что если есть несколько потенциальных ключей, то
не имеет существенного значения, какой из них будет выбран в качестве первичного.
Приведем цитату из работы Кодда [8.8]: “Обычно обоснования [выбора ключа] доста-
точно просты, однако этот вопрос выходит за рамки реляционной модели”. Что касается
наших собственных примеров, иногда мы первичный ключ определяем, а иногда не оп-
ределяем (но мы всегда будем, конечно, определять хотя бы один потенциальный ключ).
Внешние ключи
Если не придерживаться формальностей, то внешний ключ можно определить как мно-
жество атрибутов одной переменной-отношения R2, значения которых должны совпадать
со значениями некоторого потенциального ключа некоторой другой переменной-
отношения R1. Например, рассмотрим множество атрибутов {S#} (состоящее из одного ат-
рибута) переменной-отношения SP. Ясно, что каждое значение множества {S#} должно
быть допустимым для переменной-отношения SP лишь в том случае, если такое же значе-
ние присутствует в качестве значения единственного потенциального ключа {S#} для пе-
ременной-отношения S (не имеет смысла описывать поставку несуществующего поставщи-
ка). Аналогично заданное значение множества атрибутов {Р#} переменной-отношения SP
будет допустимым лишь в том случае, если существует такое же значение единственного
потенциального ключа {Р#} переменной-отношения Р (невозможно поставить несущест-
вующую деталь). Эти примеры послужат нам обоснованием следующего определения.
Пусть R2 — некоторая переменная-отношение. Тогда внешний ключ (скажем,
FK) в переменной-отношении R2 представляет собой множество атрибутов этой
переменной-отношения, такое, что:
а) существует переменная-отношение R1 (причем переменные-отношения R1 и R2
необязательно различны) с потенциальным ключом СК;
б) каждое значение внешнего ключа FK в текущем значении переменной-
отношения R2 обязательно совпадает со значением ключа СК некоторого корте-
жа в текущем значении переменной-отношения R1.
Данное определение нуждается в дополнительных пояснениях.
1. По определению каждое значение данного внешнего ключа должно присутствовать
в качестве значения соответствующего ему потенциального ключа (который обыч-
но, но не всегда, является первичным ключом). Однако заметьте, что обратное ус-
Глава 8. Целостность данных
315
ловие не требуется, т.е. потенциальный ключ, соответствующий данному внешнему
ключу, может содержать значение, которое в данный момент не является значени-
ем этого внешнего ключа. Например, в случае базы данных поставщиков и деталей
(пример возможных значений показан на рис. 3.8) поставщик с номером 'S5' есть
в переменной-отношении S, но его нет в переменной-отношении SP, поскольку этот
поставщик в данный момент не поставляет никаких деталей.
2. Некоторый внешний ключ будет составным или простым в зависимости от того,
является ли простым или составным соответствующий потенциальный ключ.
3. Каждый входящий в некоторый внешний ключ атрибут должен иметь то же
имя и тип, что и эквивалентный ему компонент соответствующего потенциаль-
ного ключа.
4. Терминология. Значение внешнего ключа представляет ссылку на кортеж, содер-
жащий соответствующее значение потенциального ключа (ссылочный кортеж).
Поэтому проблема контроля того, чтобы база данных не включала никаких невер-
ных значений внешних ключей, известна как проблема поддержания ссылочной
целостности. Ограничение, в соответствии с которым значения данного внешнего
ключа должны отвечать значениям соответствующих потенциальных ключей, на-
зывают ссылочным ограничением. Переменная-отношение, которая содержит
внешний ключ, называется ссылающейся переменной отношения, а переменная-
отношение, которая содержит соответствующий потенциальный ключ, — ссылоч-
ной переменной-отношением.
5. Ссылочные диаграммы. Еще раз обратимся к базе данных поставщиков и деталей.
Существующие в этой базе данных ссылочные ограничения можно представить по-
средством следующей ссылочной диаграммы.
S <--- SP ---> Р
Здесь каждая стрелка обозначает внешний ключ в той переменной-отношении, из
которой стрелка выходит. Этот внешний ключ ссылается на некоторый потенци-
альный ключ той переменной-отношения, на который данная стрелка указывает.
Замечание. Чтобы диаграмма была более понятной, иногда желательно поме-
чать каждую стрелку на ссылочной диаграмме именами атрибутов (или един-
ственного атрибута), составляющих соответствующий внешний ключ8, как, на-
пример, показано ниже.
S# P#
S <--- SP ---> Р
Однако в этой книге подобные пометки будут использоваться лишь в тех случаях,
когда их отсутствие может привести к путанице или двусмысленности.
6. Конечно, любая заданная переменная-отношение может быть одновременно и ссы-
лочной, и ссылающейся, как в случае отношения R2 на следующей диаграмме.
R3 ---> R2 --» R1
5 В качестве альтернативы (и, возможно, предпочтительной) можно было бы присвоить
внешним ключам имена, а затем использовать эти имена для обозначения стрелок.
316
Часть II. Реляционная модель
Удобно будет ввести термин ссылочный путь. Пусть имеются переменные-
отношения Rn, R(n-l), R2, R1, такие, что существует ссылочное ограничение из
переменной-отношения Rn в переменную-отношение R(n-l), ссылочное ограниче-
ние из переменной-отношения R(n-l) в переменную-отношение R(n-2), ... и ссы-
лочное ограничение из переменной-отношения R2 в переменную-отношение R1.
Rn ---> R(n-l) ---> R(n-2) ---> ... ---> R2 ---> R1
Тогда цепочка стрелок из Rn в R1 будет представлять ссылочный путь из пере-
менной-отношения Rn в переменную-отношение R1.
7. Обратите внимание, что переменные-отношения R1 и R2 в определении внешнего
ключа необязательно различны, т.е. некоторая переменная-отношение может иметь
внешний ключ, значения которого должны совпадать со значениями некоторого
потенциального ключа в этой же переменной-отношении. В качестве примера рас-
смотрим следующее определение переменной-отношения (синтаксис мы поясним
по ходу рассмотрения, хотя он должен быть понятен и сам по себе).
VAR ЕМР BASE RELATION
{ EMP# ЕМР#,..., MGR_EMP# ЕМР#, ... }
PRIMARY KEY { EMP# }
FOREIGN KEY { RENAME MGR_EMP# AS EMP# } REFERENCES EMP ;
Здесь атрибут MGR_EMP# представляет номер того служащего, который является ме-
неджером для служащего, определяемого значением атрибута ЕМР#. Например,
кортеж для служащего с номером 'Е4' в качестве значения атрибута MGR_EMP# мо-
жет включать значение ' ЕЗ', которое, по сути, представляет собой ссылку на кор-
теж переменной-отношения ЕМР для служащего с номером 'ЕЗ'. (Обратите внима-
ние, что в этом примере необходимо переименовать атрибут внешнего ключа, что-
бы обеспечить приведенное выше требование из п. 3.) Подобные переменные-
отношения иногда называют самоссылающимися.
Упражнение. Придумайте какие-нибудь данные для этого примера.
8. Самоссылающиеся переменные-отношения, подобные переменной-отношению ЕМР
в предыдущем примере, на самом деле представляют собой специальный случай
более общей ситуации, при которой могут возникать ссылочные циклы. Перемен-
ные-отношения Rn, R(n-l), ..., R2, R1 образуют ссылочный цикл, если перемен-
ная-отношение Rn содержит внешний ключ, ссылающийся на переменную-
отношение R(n-l), переменная-отношение R(n-l) содержит внешний ключ, ссы-
лающийся на переменную-отношение R(n-2), ..., и наконец, переменная-
отношение R1 содержит внешний ключ, ссылающийся вновь на переменную-
отношение Rn. Или более кратко: ссылочный цикл существует, если есть ссылоч-
ный путь из некоторой переменной-отношения Rn к самой себе.
Rn ---> R(n-l) ---» R(n-2) ---> ... ---> R2 ---> R1---» Rn
9. Соответствие между внешними и потенциальными ключами иногда называют
клеем, который объединяет базу данных в единое целое. То же самое можно
сказать иначе: такое соответствие представляет собой определенную связь ме-
Глава 8. Целостность данных
317
жду кортежами. Однако обратите особое внимание на то, что не все подобные
связи представлены ключами таким способом. Например, существует связь
(“совместное размещение”) между находящимися в одном городе поставщика-
ми и деталями, представленная атрибутами CITY переменных-отношений S и Р.
В этом случае данный поставщик и данная деталь “размещены совместно”, ес-
ли они находятся в одном и том же городе. Как видите, эта связь представлена
без помощи ключей.
10. Исторически понятие внешнего ключа было определено лишь для базовых пере-
менных-отношений — факт, который сам по себе поднимает некоторые вопросы
(подробности приводятся при обсуждении принципа взаимозаменяемости в разде-
ле 9.2 главы 9). Мы не навязываем здесь подобных ограничений, однако для про-
стоты изложения ограничим наше обсуждение лишь базовыми переменными-
отношениями (где это не связано с какими-либо различиями).
11. В реляционной модели первоначально требовалось, чтобы внешние ключи ссылались
конкретно на первичные ключи, а не просто на потенциальные ключи (например,
[8.8]). В общем случае мы отвергаем такое ограничение как излишнее и нежелатель-
ное, хотя на практике оно позволяет поддерживать в системе определенный порядок
[8.13]. Обычно мы будем следовать такому порядку в наших примерах.
12. Вместе с понятием потенциального ключа реляционная модель содержит следую-
щее правило поддержки ссылочной целостности.
Ссылочная целостность. База данных не должна содержать значений внешних
ключей, не имеющих соответствия9.
Здесь выражение “значение внешнего ключа, не имеющее соответствия” относится к
значению внешнего ключа в некоторой переменной-отношении, для которого не сущест-
вует отвечающего ему значения соответствующего потенциального ключа в соответст-
вующей ссылочной переменной-отношении. Проще говоря, правило утверждает, что ес-
ли В ссылается на А, то А должно существовать.
Ниже приведен синтаксис для определения внешнего ключа.
FOREIGN KEY { <список элементов> } REFERENCES <имя переменной-отношения>
Это предложение должно присутствовать в определении ссылающейся переменной-
отношения. Дополнительно отметим следующее.
Каждое значение в параметре <список элементов> представляет собой или пара-
метр <имя атрибута>, определяющий атрибут ссылочной переменной-отношения,
или выражение следующего вида.
RENAME <имя атрибута> AS <имя атрибута>
9 Правило ссылочной целостности можно рассматривать как метаограничение. Оно означает,
что любая база данных должна быть объектом определенных ограничений целостности, специфи-
ческих именно для нее. В совокупности эти ограничения гарантируют, что правило ссылочной цело-
стности не будет нарушено в конкретной базе данных. По ходу дела отметим, что в отношении
реляционной модели обычно считается, что она включает другое “метаограничение”— правило
целостности сущностей. Однако это правило тесно связано с концепцией NULL-значений, поэтому
мы отложим его обсуждение до главы 18.
318
Часть II. Реляционная модель
(В качестве примера построения предложения RENAME может служить приведенное
выше определение самоссылающейся переменной-отношения ЕМР.)
Параметр <имя переменной-отношения> идентифицирует ссылочную переменную-
отношение.
Примеры определения внешних ключей неоднократно были представлены в данной
книге (например, см. рис. 3.9 в главе 3).
Замечание. Как указывалось в разделе 8.5, определение внешнего ключа фактически
является сокращенной записью некоторого ограничения базы данных (или определенно-
го ограничения переменной-отношения в случае самоссылающейся переменной-
отношения), но только если это определение не содержит конкретных “ссылочных опе-
раций”. В последнем случае определение внешнего ключа становится чем-то большим,
чем просто ограничение целостности как таковое. Подробнее этот вопрос рассматрива-
ется в следующих подразделах.
Ссылочные операции
Рассмотрим следующий оператор.
DELETE S WHERE S# = S# ( 'SI' ) ;
Предположим, что оператор DELETE выполняет именно те действия, которые и
должен выполнять, т.е. удаляет кортеж описания поставщика с номером ' S1', и не
более того. Также предположим, что база данных включает некоторые поставки для
поставщика с номером ' S1' (как показано на рис. 3.8) и выполняемое приложение
не намеревается удалять сведения об этих поставках. Если впоследствии система
проверит выполнение ограничений ссылочной целостности между переменными-
отношениями поставщиков и поставок, то будет обнаружено их нарушение и выдано
сообщение об ошибке.
Замечание. Поскольку в этом случае ссылочное ограничение является ограниче-
нием базы данных, его проверка будет осуществляться во время выполнения опера-
тора COMMIT, по крайней мере концептуально. (На самом деле система вполне может
проверить соблюдение ограничений и сразу же после выполнения оператора DELETE,
однако нарушение ограничения в этот момент необязательно означает ошибку, т.е.
системе необходимо будет осуществить эту проверку еще раз, во время выполнения
оператора COMMIT.)
Однако существует и альтернативный подход, который в определенных случаях
может оказаться предпочтительнее. При этом подходе предполагается, что системой
выполняются соответствующие компенсирующие операции, гарантирующие, что ко-
нечный результат будет удовлетворять существующим ограничениям. В нашем приме-
ре очевидной компенсирующей операцией могло бы быть “автоматическое” удаление
сведений обо всех поставках поставщика с номером ' S1'. Достичь этого можно, рас-
ширив определение внешнего ключа.
VAR SP BASE RELATION { ... } ...
FOREIGN KEY { S# } REFERENCES S
ON DELETE CASCADE ;
Глава 8. Целостность данных
319
Спецификация ON DELETE CASCADE определяет правило удаления для данного кон-
кретного ключа, которое будет применяться при обработке операторов DELETE. Здесь
спецификация CASCADE определяет тип ссылочной операции для этого правила удаления.
Смысл определений состоит в том, что обработка операторов DELETE для переменной-
отношения поставщиков должна сопровождаться “каскадным” удалением всех соответ-
ствующих кортежей из переменной-отношения поставок.
Другая общепринятая ссылочная операция задается спецификатором RESTRICT (она
не имеет ничего общего с операцией выборки (restrict) реляционной алгебры). В данном
случае спецификатор RESTRICT указывает, что выполнение операции DELETE допускается,
если в переменной-отношении поставок нет ни одного кортежа с соответствующим
внешним ключом. В противном случае операция удаления отвергается. Опускание кон-
кретного спецификатора ссылочной операции при определении некоторого внешнего
ключа равносильно заданию спецификатора NO ACTION (никаких действий), означающе-
го, что операция DELETE будет выполняться в точности так, как она описана, и не более
того. (Если спецификатор NO ACTION применить к нашему примеру, то при удалении по-
ставщика, для которого имеются сведения о выполняемых им поставках, установленное
ограничение ссылочной целостности, безусловно, будет нарушено.) Рассмотрим некото-
рые случаи применения ссылочных операций.
1. Операция DELETE — это не единственная операция, для которой имеет смысл опре-
деление ссылочных операций. Например, что должно произойти при попытке из-
менить номер поставщика, для которого уже имеются сведения хотя бы об одной
поставке? Очевидно, что необходимо использовать правило обновления, подобное
обсуждавшемуся выше правилу удаления. В общем случае для операции обновле-
ния существует тот же набор ссылочных действий, что и для операции удаления.
CASCADE— “каскадно” распространить операцию обновления посредством об-
новления значений всех соответствующих внешних ключей в переменной-
отношении поставок.
RESTRICT — ограничить выполнение операции обновления только теми случая-
ми, когда не существует никаких соответствующих поставок. Иначе выполнение
операции запрещается.
NO ACTION — операция обновления выполняется в точности так, как она записана.
2. Безусловно, спецификаторы CASCADE, RESTRICT и NO ACTION не следует считать
единственно возможными вариантами ссылочных операций. Это минимальный на-
бор спецификаторов, отражающий только те варианты действий, которые чаще
всего применяются на практике. Однако, в принципе, может существовать произ-
вольное количество возможных решений при попытке, например, удалить опреде-
ленного поставщика. Укажем некоторые из возможных действий.
Информация записывается в некоторую архивную базу данных.
Поставки для одного поставщика передаются другому поставщику.
И т.д. Однако невозможно предоставить декларативный синтаксис для всех мыс-
лимых решений. Поэтому в общем случае просто должна существовать возмож-
ность указать ссылочные действия в виде выражения CALL ргос{...), где proc —
имя процедуры, определяемой пользователем.
320
Часть II. Реляционная модель
Замечание. Выполнение этой процедуры должно рассматриваться как часть тран-
закции, для успешного завершения которой необходимо обязательно выполнить
проверку целостности. Кроме того, сохранение целостности базы данных должно
быть проверено повторно, после выполнения самой этой процедуры (поскольку
понятно, что данная процедура не должна переводить базу данных в состояние,
противоречащее требованиям ограничений целостности).
3. Пусть R1 и R2 — ссылающаяся и ссылочная переменные-отношения соответственно.
R2 ---> R1
I
И пусть для этого ссылочного ограничения установлено правило удаления CASCADE.
Тогда удаление некоторого кортежа из переменной-отношения R1 в общем случае
повлечет за собой удаление определенных кортежей переменной-отношения R2.
Теперь предположим, что на переменную-отношение R2, в свою очередь, ссылается
некоторая переменная-отношение R3.
R3 ---» R2 ---» R1
Тогда результат неявного удаления кортежей из переменной-отношения R2 по сути
ничем не будет отличаться от попытки непосредственного удаления этих кортежей
явно заданной операцией удаления. Иначе говоря, выполнение неявного удаления
требует соблюдения правила удаления, установленного как ограничение ссылочной
целостности между переменными-отношениями R3 и R2. Если в результате требуе-
мое удаление выполнено не будет (согласно установленному правилу удаления для
ссылочной зависимости между переменными-отношениями R3 и R2 или же по ка-
кой-либо другой причине), то должно быть отменено и выполнение всей операции
в целом, а база данных сохранена в неизменном состоянии. И так далее рекурсивно
для любого количества уровней.
Аналогичные замечания можно сделать в отношении правил каскадного обновле-
ния, потребовав распространения необходимых изменений, если внешний ключ в
переменной-отношении R2 имеет какие-либо общие атрибуты с потенциальным
ключом той переменной-отношения, на которую ссылается внешний ключ в пере-
менной-отношении R3.
4. Из сказанного выше следует, что с логической точки зрения операции обновления
базы данных всегда атомарны (все или ничего), даже в том случае, когда из-за ус-
тановленного правила каскадного распространения изменений они неявно выпол-
няют несколько обновлений в нескольких переменных-отношениях.
Триггерные процедуры
В предыдущем подразделе в качестве одного из возможных решений проблемы под-
держки ссылочной целостности предлагалось применять пользовательские процедуры. У
читателя, по-видимому, нет никаких сомнений в том, что в общем концепция ссылочных
действий относится, скорее всего, не к ограничениям целостности как таковым, а к об-
ласти триггерных процедур. Триггерные процедуры, которые в литературе часто назы-
вают просто триггерами, автоматически вызываются, как только происходит некоторое
событие (или условие запуска). Обычно условием запуска является выполнение некото-
рой операции обновления базы данных, но это может быть и определенная исключи-
Глава 8. Целостность данных
321
тельная ситуация (в частности, нарушение некоторого установленного ограничения це-
лостности) или истечение заданного времени. Простейшим примером триггерной проце-
дуры могут служить ссылочные действия, выполняемые при указании спецификатора
CASCADE (заметьте, при декларативном указании!).
В общем случае триггерные процедуры могут применяться и для решения более ши-
рокого круга проблем, а не только для рассматриваемых в этом разделе вопросов обес-
печения ссылочной целостности. (С перечнем таких применений можно ознакомиться в
[8.1].) Однако это большая самостоятельная тема, которая выходит далеко за рамки дан-
ной книги. (Заинтересованный читатель может обратиться к [8.22], где эти вопросы изла-
гаются подробно.) Хотелось бы отметить, что, несмотря на то что использование триг-
герных процедур может быть чрезвычайно полезным для достижения самых различных
целей, его не следует считать хорошим подходом для обеспечения целостности базы
данных по очевидным причинам: декларативный подход, если он только возможен, все-
гда предпочтительнее.
Замечание. Последнее высказывание не означает, что использование ссылочных опе-
раций — это плохая идея. По крайней мере (как уже отмечалось выше), когда для реали-
зации ссылочных действий потребуется использовать некоторые процедуры, это должно
указываться декларативно.
8.9. Средства языка SQL
Классификация ограничений целостности в языке SQL довольно сильно отличается от
схемы, описанной в разделах 8.1-8.5. В языке SQL все ограничения делятся на три категории:
ограничения домена;
ограничения базовой таблицы;
общие ограничения (иначе называемые утверждениями).
Однако ограничения домена— это не то же самое, что обсуждавшиеся выше огра-
ничения типа, а ограничения базовой таблицы отличаются от обсуждавшихся здесь ог-
раничений переменной-отношения. Аналогично утверждения отличаются от понятия
ограничений базы данных. Укажем некоторые особенности, касающиеся упомянутых
понятий языка SQL.
В действительности в языке SQL вовсе нет ограничений типа (поскольку язык
SQL не поддерживает никаких типов, за исключением небольшого количества
встроенных типов).
Понятие ограничения домена в языке SQL представляет некоторую сомнительную
обобщенную форму нашего ограничения атрибута (напомним, что домены в стиле
языка SQL в реляционном смысле доменами не являются).
Ограничения базовой таблицы и утверждения языка SQL (которые фактически
взаимозаменяемы) упрощенно можно считать равносильными нашим ограничени-
ям переменной-отношения и базы данных, вместе взятым.
Также отметим, что в языке SQL совершенно отсутствует поддержка ограничений
перехода. В настоящее время не поддерживаются и триггерные процедуры, хотя их под-
держка уже включена в новый стандарт SQL3 (см. приложение Б).
322
Часть II Реляционная модель
Ограничения домена
В языке SQL ограничения домена представляют собой ограничения, применяемые к
каждому столбцу, объявленному принадлежащим к данному домену. Приведем пример
определения домена.
CREATE DOMAIN COLOR CHAR(6) DEFAULT '???'
CONSTRAINT VALID_COLORS
CHECK ( VALUE IN
( 'Red', 'Yellow', 'Blue', 'Green', '???' ) ) ;
Предположим, что оператор CREATE TABLE для базовой таблицы Р (таблицы деталей)
выглядит следующим образом.
CREATE TABLE Р ( ... , COLOR COLOR, ... ) ;
Если пользователь вставляет в таблицу Р только часть новой строки, не содержащую
значение для столбца COLOR, то по умолчанию в этот столбец будет помещено значение
'???'. Если же пользователь укажет значение для столбца COLOR, но это значение не
будет принадлежать диапазону допустимых для него значений, то операция не будет вы-
полнена и система выдаст сообщение, в котором будет указано о нарушении пользовате-
лем ограничения VALID_COLORS.
Как было показано в разделе 8.2, концептуально ограничения домена являются (или, ско-
рее, должны являться) ничем иным, как перечнем значений, которые составляют этот домен,
и приведенный выше пример ограничения VALID_COLORS, конечно, следует этому определе-
нию. Однако в общем случае язык SQL позволяет включать в определение ограничений до-
менов логические выражения произвольной сложности. Это предоставляет возможность ука-
зывать, например, что допустимые значения некоторого домена D могут зависеть от значений
указанного атрибута, присутствующих в настоящий момент в некоторой таблице Т. Читатель
может поразмышлять о возможных последствиях такой неоправданной вседозволенности.
Ограничения базовой таблицы
В языке SQL существуют следующие виды ограничений базовой таблицы:
определение потенциального ключа;
определение внешнего ключа;
определение “проверочного условия”.
Ниже каждое из них обсуждается подробнее.
Замечание. В языке SQL каждому определению ограничений может предшествовать
предложение вида CONSTRAINT <имя ограничений. задающее имя нового ограничения (это
замечание верно и для ограничений доменов, как мы уже убедились на примере ограничения
VALID_COLORS). В приводимых ниже примерах мы будем игнорировать эту возможность.
Потенциальные ключи
Определение потенциального ключа записывается в следующем виде.
UNIQUE ( <список имен столбцов> )
Глава 8. Целостность данных
323
Возможна и другая форма записи.
PRIMARY KEY ( <список имен столбцов> )
В обоих случаях параметр <список имен столбцов> не должен быть пустым. Для за-
данной базовой таблицы может существовать не более одной спецификации PRIMARY KEY
(первичный ключ) и любое количество спецификаций UNIQUE (альтернативные ключи). В
случае первичного ключа для каждого из указанных столбцов дополнительно подразуме-
вается наличие в определении спецификации NOT NULL, даже если эта спецификация не
была указана явно. Проверка выполнения ограничений будет обсуждаться ниже.
Внешние ключи
Определение внешнего ключа записывается следующим образом.
FOREIGN KEY ( <список имен столбцов> )
REFERENCES <имя базовой таблицы> [ ( <список имен столбцов> ) ]
[ ON DELETE <ссылочная операция? ]
[ ON UPDATE <ссылочная операция? ]
Здесь параметр <ссылочная операция? может принимать значения NO ACTION (по
умолчанию), CASCADE, SET DEFAULT и SET NULL. Опции SET DEFAULT и SET NULL будут
рассматриваться в главе 18. Второй параметр <список имен столбцов> необходим в том
случае, если внешний ключ ссылается на потенциальный ключ, который не является пер-
вичным ключом.
Замечание. Соответствие “внешний ключ — потенциальный ключ” устанавлива-
ется не на основе имен столбцов, а на основе позиции (слева направо) в списках
имен атрибутов.
Проверочные условия
Определение проверочного условия (проверочного ограничения) имеет следующий вид.
CHECK ( <условное выражение> )
Попытка создания строки г в базовой таблице Т рассматривается как нарушение про-
верочного ограничения для таблицы Т, если в результате вычисления указанного в этом
ограничении условного выражения для строки г будет получено значение ложь.
Замечание. Условное выражение в языке SQL является аналогом того, что ранее мы
называли логическим (или булевым) выражением. Эти выражения подробно рассматри-
ваются в приложении А. В частности, отметим, что в данном контексте условное выра-
жение может быть сколь угодно сложным. Не требуется, чтобы условие ограничения
включало ссылки только на таблицу Т; оно может иметь ссылки на что угодно в базе
данных. Читателю, опять-таки, будет полезно поразмышлять над тем, какими могут быть
последствия такой неоправданной вседозволенности.
Вот пример создания таблицы с помощью оператора CREATE TABLE, в котором ис-
пользуются ограничения базовой таблицы всех трех типов.
CREATE TABLE SP
( S# S# NOT NULL, P# P# NOT NULL, QTY QTY NOT NULL,
PRIMARY KEY ( S#, P# ),
FOREIGN KEY ( S# ) REFERENCES S
324
Часть II. Реляционная модель
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY ( P# ) REFERENCES P
ON DELETE CASCADE
ON UPDATE CASCADE,
CHECK ( QTY > 0 AND QTY < 5001 ) ) ;
Здесь подразумевается, что домены S#, P# и QTY уже определены, а атрибуты S# и P#
явно определены как первичные ключи для таблиц S и Р соответственно. Также здесь
умышленно применяется соглашение по сокращению, благодаря которому проверочное
условие вида
CHECK ( <имя столбца> IS NOT NULL )
в определении рассматриваемого столбца можно заменить простой спецификацией
NOT NULL. В соответствии с данным правилом в этом примере три достаточно громозд-
ких проверочных условия заменены тремя простейшими спецификациями NOT NULL.
Завершая подраздел, обратим внимание на некоторую “странность”: считается, что
ограничение базовой таблицы SQL всегда удовлетворено, если базовая таблица пуста,
причем даже в случае ограничения вида “эта таблица не должна быть пустой”!
Утверждения
Рассмотрим третий случай: общие ограничения, иначе называемые утверждениями.
Общие ограничения создаются с помощью оператора CREATE ASSERTION, имеющего
следующий синтаксис.
CREATE ASSERTION <имя ограничения?
CHECK ( <условное выражение> ) ;
Здесь параметр <имя ограничения? задает имя создаваемого ограничения, а параметр
<условное выражение> определяет проверяемое условное выражение. Для отмены обще-
го ограничения используется оператор DROP ASSERTION.
DROP ASSERTION <имя ограничения? ;
Отметим, что в отличие от всех других форм SQL-оператора отмены DROP, приведен-
ных в этой книге (DROP DOMAIN, DROP TABLE, DROP VIEW), оператор DROP ASSERTION не
содержит опций RESTRICT и CASCADE.
Вот несколько примеров утверждений, создаваемых с помощью оператора CREATE
ASSERTION.
1. Каждый поставщик должен иметь статус не менее 5.
CREATE ASSERTION IC13 CHECK
( ( SELECT MIN ( S.STATUS ) FROM S ) > 4 ) ;
2. Значение веса любой детали должно быть положительным.
CREATE ASSERTION IC18 CHECK
( NOT EXISTS ( SELECT * FROM P
WHERE NOT ( P.WEIGHT > 0 ) ) ) ;
Глава 8. Целостность данных
325
3. Все красные детали должны храниться в Лондоне.
CREATE ASSERTION IC99 CHECK
( NOT EXISTS ( SELECT * FROM P
WHERE P.COLOR = 'Red'
AND P.CITY <> 'London' ) ) ;
4. He допускаются поставки с общим весом (произведение количества деталей и их
веса), превышающим 20 000 фунтов.
CREATE ASSERTION IC46 CHECK
( NOT EXISTS ( SELECT * FROM P, SP
WHERE P.P# = SP.P#
AND ( P.WEIGHT * SP.QTY ) > 20000.0 ) ) ;
5. Поставщики co статусом, меньшим 20, не имеют права поставлять любую деталь в
количестве более 500 штук.
CREATE ASSERTION IC95 CHECK
( NOT EXISTS ( SELECT * FROM S, SP
WHERE S.STATUS < 20
AND S.S# = SP.S#
AND SP.QTY > 500 ) ) ;
Откладываемая проверка
Классификация ограничений целостности в языке SQL отличается от нашей также в
отношении вопроса, когда должна выполняться проверка. В нашей схеме ограничения
базы данных проверяются во время выполнения оператора COMMIT, а остальные ограни-
чения проверяются немедленно. В языке SQL подход иной и ограничения могут быть
определены как откладываемые и неоткладываемые (опции DEFERRABLE и NOT
DEFERRABLE соответственно). Если ограничение откладываемое, оно дополнительно мо-
жет быть определено как исходно откладываемое (INITIALLY DEFERRED) или исходно
выполняемое (INITIALLY IMMEDIATE), что определяет состояние ограничения в начале
выполнения каждой транзакции. Неоткладываемые ограничения всегда проверяются не-
медленно, а откладываемые могут динамически включаться и отключаться с помощью
оператора, синтаксис которого приведен ниже.
SET CONSTRAINTS <список имен ограничений <параметр> ;
Здесь параметр <параметр>— это или ключевое слово IMMEDIATE (немедленно), или
ключевое слово DEFERRED (отложено). Примером может служить следующее утверждение.
SET CONSTRAINTS IC46, IC95 DEFERRED ;
Откладываемые ограничения проверяются только тогда, когда они находятся в со-
стоянии IMMEDIATE (немедленно). Установка откладываемого ограничения в состояние
IMMEDIATE, естественно, приводит к тому, что оно проверяется немедленно. Если про-
верка завершается ошибкой, то завершается ошибкой и оператор SET IMMEDIATE. При
выполнении операции завершения транзакции (COMMIT) все откладываемые ограничения
целостности переходят в выполняемое состояние IMMEDIATE и если какая-либо проверка
завершается ошибкой, выполняется откат транзакции.
326
Часть II. Реляционная модель
8.10. Резюме
В этой главе обсуждалось ключевое понятие целостность. Проблема целостности —
это проблема обеспечения точности и корректности данных, хранящихся в базе дан-
ных (безусловно, нас интересовали декларативные-решения этой проблемы). Как мы
уже выяснили, понятие “целостность” в данном контексте означает семантику: это ог-
раничения целостности (в частности, предикаты переменных-отношений и базы данных;
см. ниже), которые отражают смысл данных. Поэтому, как утверждалось в разделе 8.6,
целостность данных имеет решающее значение.
Ограничения целостности можно распределить по четырем категориям.
Ограничения типа задают допустимые значения для данного типа (или домена) и
проверяются при вызове соответствующего оператора выбора значения.
Ограничения атрибута задают допустимые значения для данного атрибута и ни-
когда не должны нарушаться (подразумевается, что ограничения типа проверены).
Ограничения переменной-отношения задают допустимые значения для данной
переменной-отношения и проверяются перед тем, как рассматриваемая перемен-
ная-отношение будет обновлена.
Ограничения базы данных устанавливают допустимые значения для данной ба-
зы данных и проверяются при выполнении операторов COMMIT.
Логическое произведение (или операция И) всех установленных ограничений перемен-
ных-отношений для данной переменной-отношения представляет внутренний предикат пе-
ременной-отношения. Предикат переменной-отношения отражает смысл этой переменной в
том виде, в котором он может быть воспринят системой, и является критерием приемлемо-
сти обновлений для этой переменной-отношения. Золотое правило утверждает, что любым
операциям изменения запрещается каким-либо образом переводить переменную-отношение
в состояние, противоречащее ее собственному предикату. В свою очередь, вся база данных
является объектом предиката базы данных и любой транзакции также запрещено перево-
дить базу данных в состояние, которое противоречит этому предикату.
Затем в общих чертах были описаны основная идея ограничений перехода
(остальные ограничения относятся к ограничениям состояния) и практически важные
специальные случаи ограничений, представляющие потенциальные, первичные, аль-
тернативные и внешние ключи. Потенциальные ключи должны обладать свойством
уникальности и неизбыточности, и каждая переменная-отношение должна иметь по
крайней мере один потенциальный ключ (исключений нет!). Ограничение, согласно ко-
торому значения данного внешнего ключа должны совпадать со значениями соответст-
вующего потенциального ключа, называется ссылочным ограничением. Мы познако-
мились с несколькими следствиями из идеи ссылочной целостности, включая понятие
ссылочных действий (в том числе каскадирование). Последнее обсуждение подвело нас
к понятию триггерных процедур.
В завершение этой главы были рассмотрены соответствующие аспекты языка SQL. В
языке SQL присутствует поддержка ограничений домена, ограничений базовых таблиц и
утверждений (общих ограничений). Кроме того, поддержка ограничений базовых таблиц
в языке SQL включает специальный случай поддержки ключей.
Глава 8. Целостность данных
327
Упражнения
8.1. На основе представленного в разделах 8.2-8.5 синтаксиса запишите следующие
ограничения целостности для базы данных поставщиков деталей и проектов.
а) Допустимыми городами являются Лондон ('London'), Париж ('Paris'), Рим
('Rome'), Афины ('Athens'), Осло ('Oslo'), Стокгольм ('Stockholm'), Мадрид
('Madrid') и Амстердам ('Amsterdam').
б) Допустимы только такие номера поставщиков, которые представлены символь-
ной строкой, содержащей не менее двух символов, первым из которых является
буква ' S', а оставшиеся образуют целое число в диапазоне от 0 до 9 999.
в) Все красные детали должны весить меньше 50 фунтов.
г) Никакие два проекта не могут находиться в одном и том же городе.
д) В любой момент в Афинах может находиться не более одного поставщика.
е) Ни одна поставка по количеству деталей не может превышать удвоенное сред-
нее значение количества для всех поставок.
ж) Поставщик с наибольшим статусом не может находиться в одном городе с по-
ставщиком с наименьшим статусом.
з) Каждый проект должен находиться в городе, в котором есть хотя бы один по-
ставщик.
и) Каждый проект должен находиться в городе, в котором есть хотя бы один по-
ставщик деталей данного проекта.
к) Должна существовать по крайней мере одна деталь красного цвета.
л) Среднее значение статуса поставщика должно быть больше 18.
м) Каждый поставщик в Лондоне должен поставлять деталь с номером 'Р2'.
н) Хотя бы одна красная деталь должна весить меньше 50 фунтов.
о) Поставщики в Лондоне должны поставлять больше видов деталей, чем постав-
щики в Париже.
п) Поставщики в Лондоне должны в сумме поставлять больше деталей, чем по-
ставщики в Париже.
р) Ни одна поставка не может быть сокращена (за одно обновление) более чем
вдвое по сравнению с текущим значением.
с) Поставщики из Афин могут переехать только в Лондон или Париж, а постав-
щики из Лондона — только в Париж.
8.2. Для каждого из ответов к упр. 8.1 укажите, являются ли они ограничениями пере-
менной-отношения или ограничениями базы данных.
8.3. Для каждого из ответов к упр. 8.1 приведите пример операции, которая может при-
вести к нарушению данного ограничения.
8.4. Предположим, что выражения CHAR(5) и CHAR(3) обозначают символьные строки
длиной 5 и 3 символа соответственно. Сколько типов здесь присутствует — один
или два?
8.5. Пусть А и В — это две переменные-отношения. Определите потенциальные ключи
для результата выполнения каждого из приведенных ниже выражений.
328
Часть II. Реляционная модель
a) A WHERE ...
6) A {...}
в) A TIMES В
r) A UNION В
д) A INTERSECT В
e) A MINUS В
ж) A JOIN В
з) EXTEND В ADD <выражение> AS Z
и) SUMMARIZE A PER В ADD <выражение> AS Z
к) A SEMIJOIN В
л) A SEMIMINUS В
Для каждого случая предполагается, что переменные-отношения А и В удовлетво-
ряют требованиям для соответствующей операции (т.е. имеют тот же тип, что и в
случае операции UNION).
8.6. Пусть R — переменная-отношение степени п. Какое максимальное количество по-
тенциальных ключей может иметь переменная-отношение R?
8.7. Пусть R — переменная-отношение, имеющая единственными допустимыми значе-
ниями особые (и очень важные) отношения степени 0 с названиями DEE и DUM. Ка-
кой потенциальный ключ (или ключи) имеет эта переменная-отношение R?
8.8. В данной главе для внешних ключей обсуждались правила удаления и обновления
(DELETE и UPDATE), но не упоминались правила вставки (операция INSERT). Почему?
8.9. Используя значения из базы данных поставщиков, деталей и проектов (см. рис. 4.5),
укажите, каким будет результат выполнения каждой из приведенных ниже операций.
а) Обновить кортеж проекта с номером ' J7', присвоив атрибуту CITY значение
'New York'.
б) Обновить кортеж детали с номером ' Р5', присвоив атрибуту P# значение ' Р4'.
в) Обновить кортеж поставщика с номером 'S5', присвоив атрибуту S# значение
'S8'. Предполагается, что для этой операции установлено правило обновления
RESTRICT.
г) Удалить кортеж поставщика с номером 'S3'. Предполагается, что для этой
операции установлено правило удаления CASCADE.
д) Удалить кортеж детали с номером 'Р2'. Предполагается, что для этой операции
установлено правило удаления RESTRICT.
е) Удалить кортеж проекта с номером 'J4'. Предполагается, что для этой опера-
ции установлено правило удаления CASCADE.
ж) Обновить кортеж поставки с ключом 'Sl'-'Pl'-'Jl', присвоив атрибуту S#
значение 'S2'.
з) Обновить кортеж поставки с ключом 'S5'-'P5'-'J5', присвоив атрибуту J#
значение ' J7
Глава 8. Целостность данных
329
и) Обновить кортеж поставки с ключом ' S5' Р5' J5', присвоив атрибуту J#
значение 'J8'.
к) Вставить кортеж для поставки с ключом ' S5' -' Рб' -' J7'.
л) Вставить кортеж для поставки с ключом 'S4'-'P7'-'J6'.
м) Вставить кортеж для поставки с ключом 'Sl'-'P2'-'jjj' (где ' j j j' —значе-
ние номера проекта по умолчанию).
8.10. В учебной базе данных содержится информация о схеме процесса обучения внутри
компании. Для каждого курса обучения в базе данных имеются подробные сведе-
ния обо всех необходимых курсах, которые должны быть прослушаны перед дан-
ным, и обо всех потоках его прослушивания. Для каждого потока в базе данных
содержатся сведения обо всех его преподавателях и студентах, зарегистрирован-
ных для прохождения курса в данном потоке. База данных также содержит инфор-
мацию о сотрудниках. Соответствующие переменные-отношения описаны ниже.
COURSE { COURSE#, TITLE } /* Курс */
PREREQ { SUP_COURSE#, SUB_COURSE# } /* Условия */
OFFERING { COURSE#, OFF#, OFFDATE, LOCATION } /* Поток */
TEACHER { COURSE#, OFF#, EMP# } /* Преподаватель */
ENROLLMENT { COURSE#, OFF#, EMP#, GRADE } /* Списки */
EMPLOYEE { EMP#, ENAME, JOB } /* Работник */
Смысл переменной-отношения PREREQ (Предварительные условия) заключается в том,
что определенный старший курс (SUP_COURSE#) требует в качестве обязательного усло-
вия предварительного прослушивания некоторого подчиненного курса (SUB_COURSE#).
Назначение остальных переменных-отношений должно быть понятно без каких-либо
дополнительных пояснений. Начертите для этой базы данных соответствующую ссы-
лочную диаграмму. Дайте также соответствующие определения базы данных (т.е. за-
пишите соответствующий набор определений типов и переменных-отношений).
8.11. Две следующие переменные-отношения представляют базу данных, содержащую
информацию об отделах и служащих.
DEPT { DEPT#, ... , MGR_EMP#, ... }
ЕМР { ЕМР#, ... , DEPT#, ... }
В каждом отделе есть менеджер (MGR_EMP#), и каждый из служащих работает в од-
ном из отделов (DEPT#). Начертите ссылочную диаграмму и необходимые опреде-
ления данных для этой базы данных.
8.12. Две следующие переменные-отношения представляют базу данных, содержащую
информацию о служащих и программистах.
ЕМР { ЕМР#, ... , JOB, ... }
PGMR { ЕМР#, ... , LANG, ... }
Каждый программист является служащим, но не наоборот. Начертите ссылочную
диаграмму и необходимые определения данных для этой базы данных.
8.13. Один из вопросов, который еще не обсуждался в этой главе, связан с ситуацией,
когда пользователь пытается удалить некоторую переменную-отношение или тип,
а существующее ограничение целостности ссылается на эту переменную-
отношение или тип. Что должно произойти в такой ситуации?
330
Часть II. Реляционная модель
8.14. Запишите ответ к упр. 8.1 на языке SQL.
8.15. Сравните средства поддержки целостности в языке SQL и тот механизм поддержки
целостности, который был описан в основной части этой главы, и укажите разли-
чия между ними.
Список литературы
8.1. Aileen A., Hellerstein J.M., and Widom J. Static Analysis Techniques for Predicting the
Behavior of Active Database Rules ACM TODS. — March, 1995. — 20, № 1.
В этой статье продолжена работа, начатая в [8.2], [8.5]; см. “экспертная система
баз данных” (здесь она называется активной системой баз данных). В частности, в
статье описана система правил прототипа Starburst компании IBM (см. [17.50],
[25.14], [25.17], [25.21], [2522], а также [8.22]).
8.2. Balaris Е.А. and Widom J. An Algebraic Approach to Rule Analysis in Expert Database
Systems П Proc. 20th Int. Conf, on Very Large Data Bases. — Santiago, Chile,
September, 1994.
В соответствии с этой статьей “экспертная система баз данных” представляет
собой систему баз данных, которая поддерживает “правила условий/действий” (в
нашей терминологии условиям соответствуют триггерные условия, а действи-
ям — триггерные процедуры). Одной из проблем для таких систем является то,
что их поведение сложно по своему существу как для понимания, так и для про-
гнозирования. В статье предлагаются методы для предварительного определения
перед выполнением, обладает ли заданный набор правил свойствами завершен-
ности и слияния. Свойство завершенности означает, что выполнение правила
гарантированно не будет продолжаться бесконечно. Свойство слияния означает,
что окончательное состояние базы данных не зависит от порядка, в котором эти
правила выполнялись.
8.3. Bernstein Р.А., Blaustein В.Т., Clarke Е.М. Fast Maintenance of Semantic Integrity
Assertions Using Redundant Aggregate Data // Proc. 6th Intern. Conf, on Very Large
Data Bases. — Montreal, Canada, October, 1980.
Здесь представлен эффективный метод приведения в действие ограничений целост-
ности особого рода на примере, в котором “любое значение множества А должно
быть меньше любого значения множества В”. Этот метод основан, например, на том
наблюдении, что данное ограничение, по сути, логически эквивалентно ограничению
“максимальное значение множества А должно быть меньше минимального значения
множества В”. Приводя ограничения к подобному типу и используя автоматическое
сохранение максимальных и минимальных значений в виде скрытых системных пе-
ременных, можно снизить число операций сравнения, используемых для приведения
в действие заданного ограничения. В подобном случае это число сравнений не будет
зависеть от размера множества А или множества В (в зависимости от того, к какому
из множеств применяется операция обновления). Однако это будет возможно только
при организации хранения максимального и минимального значений.
8.4. Buneman О.Р., Clemons Е.К. Efficiently Monitoring Relational Databases П ACM
TODS. — September, 1979. — 4, № 3.
Глава 8. Целостность данных
331
В статье описываются методы эффективной реализации триггерных процедур (которые
здесь называются аварийными), в частности, обсуждается проблема возможности опре-
деления, когда условие удовлетворяется, без необходимости вычислять это условие. В
ней приводится метод обнаружения обновлений, которые, вероятно, не смогут удовле-
творить заданному триггерному условию (здесь этот метод называется алгоритмом ук-
лонения (algorithm avoidance)). В статье также обсуждается метод снижения избыточной
нагрузки на систему в случае безуспешного применения алгоритма уклонения, постро-
енный на основе вычисления триггерного условия для некоторого небольшого под-
множества (фильтра) всего множества соответствующих кортежей.
8.5. Ceri S., Widom J. Deriving Production Rules for Constraint Maintenance // Proc. 16th
Intern. Conf, on Very Large Data Bases. — Brisbane, Australia, August, 1990.
В статье описывается SQL-подобный язык для определения ограничений целост-
ности и задания алгоритма идентификации всех операций, которые способны на-
рушить данное ограничение. (Предварительный обзор подобного алгоритма был
дан автором этой книги в [8.11]. Существование такого алгоритма подразумевает,
что нет необходимости явно указывать для СУБД, когда данное ограничение необ-
ходимо проверить, и, конечно, схема, которая была описана в настоящей главе, не
предоставляет пользователю никаких способов выполнить это.) В статье также
рассматриваются некоторые вопросы оптимизации и корректности.
8.6. Ceri S., Fratemali Р., Paraboschi S., and Tanca L. Automatic Generation of Production
Rules for Integrity Maintenance H ACM TODS. — September, 1994. — 19, № 3.
В статье, основанной на работе [8.5], представлены возможности автоматическо-
го исправления повреждений, внесенных в результате нарушения ограничения. Ог-
раничения транслируются в правила вывода с помощью следующих компонентов.
1. Список операций, которые могут нарушать ограничение.
2. Булево выражение, в результате вычисления которого будет получено значение
истина, если ограничение нарушено (в основном, это просто отрицание перво-
начального ограничения).
3. Восстановительная процедура на языке SQL.
В статье также приведен широкий обзор работ, связанных с этой темой.
8.7. Cochrane R., Pirahesh Н., and Mattos N. Integrating Triggers and Declarative
Constraints in SQL Database System И Proc. 22 Int. Conf, on Very Large Data Bases. —
Mumbai (Bombay), India, September, 1996.
Цитата: “Семантика взаимодействия триггеров и декларативных ограничений
должна быть точно определена, что позволит избежать противоречий при выпол-
нении и обеспечить пользователей подробной моделью для упрощения понимания
подобных взаимодействий. Эта [статья] определяет такую модель”. Рассматривае-
мая модель была применена в среде СУБД DB2 и “принята как модель для ожи-
даемой новой версии стандарта языка SQL (SQL3)” (см. приложение Б).
8.8. Codd E.F. Domains, Keys, and Referential Integrity in Relational Databases И
InfoDB3. — 1988. — 3, № 1.
Здесь обсуждаются понятия домена, первичного ключа и внешнего ключа. Эта
статья, очевидно, должна быть авторитетной, поскольку Кодд является автором
всех трех понятий. Однако, по мнению автора данной книги, статья, к сожале-
332
Часть II. Реляционная модель
нию, оставила слишком много вопросов неразрешенными и невыясненными.
Между прочим, в ней приводятся следующие аргументы в пользу соблюдения
требования, чтобы один потенциальный ключ обязательно выбирался в качестве
первичного ключа: “Отказаться от этого правила — это то же самое, что попы-
таться использовать компьютер со схемой адресации основной памяти..., в ко-
торой основание системы исчисления изменяется всякий раз при возникновении
определенных условий (например, если встретился адрес, являющийся простым
числом)”. Однако, рассуждая подобным образом, можно прийти к выводу, что
одну и ту же схему адресации следует использовать для всех видов объектов. Но
разве не удобнее “адресовать” поставщиков с помощью номера поставщика, а
детали — с помощью номеров деталей (не говоря уже о поставках, для которых
используется составной “адрес”)? (На самом деле эта идея глобальной универ-
сальной схемы адресации заслуживает дальнейшего обсуждения. См. обсужде-
ние заменителей в аннотации к [13.16] в главе 13.)
8.9. Date C.J. Referential Integrity // Proc. 7th Intern. Conf, on Very Large Data Bases. — Cannes,
France, September, 1981. Позднее была издана пересмотренная версия этой статьи (Date
C.J. Relational Database: Selected Writings. — Reading, Mass.: Addison-Wesley, 1986).
В статье предложены правила ссылочных действий (преимущественно RESTRICT и
CASCADE), которые обсуждались в разделе 8.8 этой главы.
Замечание. Основное различие между первой версией статьи (VLDB 1981) и пере-
смотренной версией состоит в том, что в первой версии, следовавшей [13.6], для
внешнего ключа допускались ссылки на любое количество переменных-отношений,
тогда как в пересмотренной версии (соображения по этому поводу рассматриваются
в [8.10]) автор уже не придерживается такой чрезмерно общей позиции.
8.10. Date C.J. Referential Integrity and Foreign Keys, (в двух частях) И Relational Database
Writings 1985-1989. — Reading, Mass.: Addison-Wesley, 1990.
В первой части этой обширной статьи обсуждается история понятия ссылочной
целостности, а также предлагается ряд основных определений (с пояснениями). Во
второй части рассматриваются расширенные аргументы в пользу приведенных оп-
ределений и даются некоторые практические рекомендации. В частности, обсуж-
даются проблемы, вызванные перекрывающимися внешними ключами, значения-
ми составных внешних ключей, частично представленными NULL-значениями, и
смежные ссылочные пути (т.е. различные ссылочные пути, начальная и конечная
точки которых совпадают).
Замечание. Определенные позиции этой статьи несколько (не очень существенно)
опровергаются аргументами статьи [8.13].
8.11. Date C.J. A Contribution to the Study of Database Integrity // Relational Database
Writings 1985-1989. — Reading, Mass.: Addison-Wesley, 1990.
Цитата из резюме: “В этой статье предпринята попытка наложить некоторую
структуру на проблему [целостности] с помощью предлагаемой схемы классифи-
кации для ограничений целостности, использования этой схемы для объяснения
основополагающих понятий целостности данных, краткого описания подхода к
созданию конкретного языка формулирования ограничений целостности и опреде-
ления некоторых областей для дальнейшего исследования”. Эта глава частично ос-
Глава 8. Целостность данных
333
новывается на материале данной статьи, но саму предлагаемую схему классифика-
ции следует рассматривать как устаревшую и подлежащую замене пересмотренной
версией, описанной в разделах 8.2-8.5 настоящей главы.
8.12. Date C.J. Integrity // Chapter 11 of C.J. Date and Colin J. White. A Guide to DB2 (4th
ed.). —Reading, Mass.: Addison-Wesley, 1993.
Во время написания этой книги СУБД DB2 корпорации IBM обеспечивала дек-
ларативную поддержку первичных и внешних ключей (одна из первых, если не
первая, СУБД среди всех коммерческих СУБД). Следует отметить, что в СУБД
DB2 упомянутая поддержка пострадала от введения в реализации нескольких ог-
раничений, общее назначение которых состояло в обеспечении предсказуемого
поведения системы. Приведем простой пример. Пусть переменная-отношение R
содержит только 2 кортежа со значениями первичного ключа, равными 1 и 2 со-
ответственно. Рассмотрим следующий запрос на обновление: “Удвоить каждое
значение первичного ключа в переменной-отношении R”. При правильном вы-
полнении запроса новые значения первичных ключей в кортежах будут равны 2
и 4 соответственно. Если в СУБД DB2 вначале будет обновляться значение 2
(оно заменяется значением 4), а затем — значение 1 (оно заменяется значением
2), то запрос будет выполнен успешно. Но если вначале попытаться обновить
значение 1 (заменяя его значением 2), то будет утрачена уникальность значений
первичного ключа и запрос не будет выполнен (база данных останется неизмен-
ной). Итак, мы видим, что результат выполнения запроса непредсказуем. Чтобы
избежать подобной непредсказуемости, в СУБД DB2 просто запрещены ситуа-
ции, в которых она может возникнуть. Однако, к сожалению, некоторые из этих
ограничений довольно жесткие [8.17].
Обратите внимание, что в предыдущем примере система выполняет “немедленную
проверку”, т.е. правила целостности применяются для каждого кортежа непосред-
ственно в момент его обновления. Такой способ проверки логически неоправдан
(операции обновления обсуждались в разделе 5.4 главы 5) и осуществляется лишь
в целях повышения производительности.
8.13. Date C.J. The Primacy of Primary Keys: An Investigation // Relational Database
Writings 1991-1994. — Reading, Mass.: Addison-Wesley, 1995.
Здесь представлены аргументы в поддержку позиции, которая в некоторых случаях
не совсем правильна: сделать один из потенциальных ключей таким, чтобы он был
“больше остальных либо равным остальным”.
8.14. Hammer М.М., Sarin S.K. Efficient Monitoring of Database Assertions // Proc.
1978 ACM SIGMOD Intern. Conf, on Management of Data.— Austin, Texas,
May/June, 1978.
В статье схематически представлен алгоритм генерации процедур проверки цело-
стности (для соответствующих ограничений целостности), которые будут более
эффективны, чем очевидный метод “грубой силы” с простой оценкой установлен-
ных ограничений после полного выполнения операции обновления. Данные про-
верки вставляются в объектный код транзакции на этапе компиляции. В некоторых
случаях удается обнаружить, что во время выполнения проверки не нужны. И даже
если в них возникнет необходимость, часто можно различными способами значи-
тельно сократить количество операций доступа к базе данных.
334
Часть II. Реляционная модель
8.15. Horowitz В. M. A Run-Time Execution Model for Referential Integrity Maintenance //
Proc. 8th Intern. Data Engineering Conf. — Phoenix, Ariz., February, 1992.
Хорошо известно, что определенные комбинации
1. ссылочных структур (т.е. наборов переменных-отношений, связанных между
собой с помощью ссылочных ограничений);
2. правил удаления и обновления внешних ключей;
3. реальных значений данных в базе данных
могут привести к возникновению некоторых конфликтных ситуаций и потенциаль-
но стать причиной непредсказуемого поведения в части реализации (см. [8.10], где
можно найти подробные объяснения). Существует три общих подхода к решению
подобных проблем.
а) Оставить все это пользователю.
б) Заставить систему выявлять и запрещать попытки определения структур, по-
тенциально способных привести к конфликтам во время выполнения.
в) Заставить систему выявлять и отклонять конфликты, действительно возни-
кающие во время выполнения.
Первый подход не стоит рассматривать, а второй часто приводит к чрезмерным
ограничениям [8.12], [8.17]. Поэтому автор предлагает остановиться на третьем
подходе. В статье приведен набор правил осуществления подобных действий во
время выполнения и доказана их корректность. Однако отметим, что вопрос о про-
изводительности таких динамических проверок не рассматривается.
Автор статьи г-н Хорвиц (Horowitz) был активным членом комитета, задачей кото-
рого было определение стандарта SQL/92. Высказанные в этой статье предложения
действительно были учтены в соответствующих разделах стандарта, связанных со
ссылочной целостностью.
8.16. Markowitz V. М. Referential Integrity Revisited: An Object-Oriented Perspective // Proc.
16th Intern. Conf, on Very Large Data Bases. — Brisbane, Australia, August, 1990.
Название статьи, “Объектно-ориентированная перспектива”, действительно отра-
жает открытую позицию автора, состоящую в том, что “ссылочная целостность
лежит в основе реляционного представления объектно-ориентированных струк-
тур”. Однако сама статья посвящена вовсе не обсуждению объектно-ориентирован-
ных систем. На самом деле в ней представлен алгоритм, генерирующий на основе
диаграммы “сущность-связь” (глава 13) определение реляционной базы данных, в
которой не возникает некоторых проблем, указанных в [8.10] (перекрывающиеся
внешние ключи).
В статье также обсуждаются три коммерческих продукта (СУБД DB2, SYBASE и
INGRES по состоянию на 1990 год) с точки зрения обеспечения ссылочной цело-
стности. СУБД DB2, предоставляющая декларативную поддержку, показана чрез-
мерно ограниченной; системы SYBASE и INGRES, предоставляющие процедурную
поддержку (с помощью “триггеров” и “правил” соответственно), показаны менее
ограниченными, чем СУБД DB2, однако громоздкими и сложными в использова-
нии (хотя и сказано, что процедурная поддержка СУБД INGRES “технически пре-
восходит” поддержку ссылочной целостности в системе SYBASE).
Глава 8. Целостность данных
335
8.17. Markowitz V. M. Safe Referential Integrity Structures in Relational Databases // Proc.
17th Intern. Conf, on Very Large Data Bases. — Barselona, Spain, September, 1991.
В статье предлагаются два формальных “условия безопасности”, гарантирующих, что
определенные проблемные ситуации, описанные, например, в [8.10], [8.15], не воз-
никнут. В ней также обсуждается, что именно предоставляется в целях удовлетворе-
ния этих условий в коммерческих СУБД DB2, SYBASE и INGRES (опять же, на 1990
год). Применительно к СУБД DB2 показано, что одни реализованные ограничения,
налагаемые в целях безопасности [8.12], логически излишни, хотя другие в то же
время явно недостаточны (т.е. в системах с СУБД DB2 возможно возникновение не-
которых небезопасных ситуаций). Относительно систем SYBASE и INGRES отмече-
но, что реализованная в них процедурная поддержка не предоставляет возможности
обнаружения опасных (и даже некорректных!) ссылочных спецификаций.
8.18. Ross R. G. The Business Rule Book: Classifying, Defining, and Modeling Rules
(Version 3.0). — Boston, Mass.: Database Research Group, 1994.
См. аннотацию к [8.19].
8.19. Ross R. G. Business Rule Concepts. — Houston, Tx.: Business Rule Solutions, Inc., 1998.
На протяжении нескольких последних лет в коммерческих продуктах получила
широкое распространение поддержка бизнес-правил. Некоторые ведущие специа-
листы компьютерной индустрии стали склоняться к тому, что они могут представ-
лять собой лучшую основу для разработки и построения баз данных и их приложе-
ний (т.е. лучшую, чем ранее признанные методы, подобные созданию моделей
“сущность-связь”, объектному моделированию, семантическому моделированию и
т.д.). И мы с этим согласны, поскольку бизнес-правила, по существу, представляют
собой ни что иное, как более дружественный пользователю (т.е. менее академиче-
ский и менее формальный) способ описания предикатов, утверждений и прочих
аспектов целостности данных, обсуждавшихся в настоящей главе. Автор этой ра-
боты является одним из основных защитников подхода, основанного на использо-
вании бизнес-правил, и его книги рекомендуются всем серьезным практикам. В
[8.18] дано исчерпывающее освещение рассматриваемой темы, а [8.19] представ-
ляет собой краткое учебное пособие.
8.20. Stonebraker M.R., Wong Е. Access Control in a Relational Data Base Management
System by Query Modification // Proc. ACM National Conf. — 1974.
Университетский прототип СУБД INGRES [7.11] был пионером в интересном под-
ходе к реализации ограничений целостности (и ограничений безопасности также; см.
главу 16), основанном на .модификации запроса. Ограничения целостности определя-
лись с помощью оператора DEFINE INTEGRITY, имеющего следующий синтаксис.
DEFINE INTEGRITY ON <имя переменной-отношениЯ> IS Логическое выражение>
Например:
DEFINE INTEGRITY ON S IS S.STATUS > 0
Допустим, что пользователь U пытается выполнить операцию REPLACE языка
QUEL.
REPLACE S ( STATUS = S.STATUS - 10 )
WHERE S.CITY = "London"
336
Часть IL Реляционная модель
В системе INGRES она будет автоматически заменена следующей операцией.
REPLACE S ( STATUS = S.STATUS - 10 )
WHERE S.CITY = "London"
AND ( S.STATUS - 10 ) > 0
Конечно, измененная таким образом операция не сможет нарушить ограничение
целостности. Недостатком этого подхода является то, что не все ограничения це-
лостности могут быть реализованы таким же простым способом. Фактически в
языке QUEL поддерживаются только ограничения, которые задаются на основе
простого ограничивающего условия. Однако даже такую ограниченную поддержку
целостности в то время можно было найти далеко не во всех системах.
8.21. Walker A., Salveter S. С. Automatic Modification of Transactions to Preserve Data Base
Integrity Without Undoing Updates: Technical Report 81/026.— Stony Brook, N.Y.:
State University of New York, June, 1981.
В этой работе описан метод автоматической модификации любого “шаблона тран-
закции” (т.е. исходного кода транзакции) в соответствующий безопасный шаблон,
который является безопасным в том смысле, что ни один экземпляр транзакции,
созданной в соответствии с данным модифицированным шаблоном, не сможет на-
рушить заданные ограничения целостности. Этот метод функционирует за счет до-
бавления к исходному шаблону запросов и тестов, предназначенных для того, что-
бы еще до выполнения обновления можно было получить гарантии, что никакие
ограничения целостности не будут нарушены. Если один из этих тестов во время
выполнения даст неудовлетворительный результат, транзакция будет отменена с
выдачей сообщения об ошибке.
8.22. Widom J. and Ceri S. (eds.). Active Database Systems: Triggers and Rules for Advanced
Database Processing. San Francisco, Calif.: Morgan Kaufmann, 1996.
Это полезный конспект исследований и руководств по “активным системам баз
данных” (т.е. системам баз данных, которые автоматически выполняют опреде-
ленные действия в ответ на определенные события; другими словами, по систе-
мам с триггерными процедурами). Здесь описано несколько прототипов систем,
в частности СУБД Starburst лаборатории IBM Research [25.26], [25.14], [25.17],
[25.21], [25.22] и СУБД Postgres Калифорнийского университета в Беркли
[25.26], [25.30], [25.32]. В этой книге также излагаются вопросы, относящиеся к
стандартам SQL/92, SQL3 (начальной версии) и некоторым коммерческим про-
дуктам (к СУБД Oracle, Informix и Ingres в том числе). Также в книге представ-
лена обширная библиография.
Ответы к некоторым упражнениям
8.1.
a) TYPE CITY POSSREP ( CHAR )
CONSTRAINT THE_CITY (CITY ) = 'London'
OR THE_CITY (CITY ) = 'Paris'
OR THE_CITY (CITY j = 'Rome'
OR THE-CITY (CITY ) = 'Athens'
OR THE_CITY (CITY ) = 'Oslo'
Глава 8. Целостность данных
337
OR THE_CITY (CITY ) = 'Stockholm'
OR THE_CITY (CITY ) = 'Madrid'
OR THE_CITY (CITY ) = 'Amsterdam' ;
Очевидным вариантом сокращенной записи этого выражения может быть сле-
дующий.
TYPE CITY POSSREP ( CHAR )
CONSTRAINT THE_CITY ( CITY ) IN { 'London' , 'Paris' ,
'Rome' , 'Athens' ,
'Oslo' , 'Stockholm' ,
'Madrid' , 'Amsterdam' } ;
6) TYPE S# POSSREP ( CHAR ) CONSTRAINT
SUBSTR ( THE_S# ( S# ), 1, 1 ) = 'S' AND
CAST_AS_INTEGER (SUBSTR ( THE_S# ( S# ), 2 ) > 0 AND
CAST_AS_INTEGER (SUBSTR ( THE_S# ( S# ), 2 ) < 9999 ;
Здесь подразумевается, что в системе существуют операторы выделения под-
строки SUBSTR и явного преобразования типов CAST_AS_INTEGER.
в) CONSTRAINT С IS_EMPTY ( Р WHERE WEIGHT > WEIGHT ( 50.0 ) ) ;
г) CONSTRAINT D COUNT ( J ) = COUNT ( J { CITY } ) ;
д) CONSTRAINT E COUNT ( S WHERE CITY = 'Athens' ) < 1 ;
e) CONSTRAINT F
IS_EMPTY ( ( EXTEND SPJ ADD 2* AVG ( SPJ, QTY )
AS X ) WHERE QTY > X ) ;
ж) CONSTRAINT G
IS EMPTY ( ( S WHERE STATUS = MIN ( S { STATUS } ) ) JOIN
( S WHERE STATUS = MAX ( S { STATUS } ) ) ) ;
В действительности понятия “поставщик с наибольшим статусом” и “поставщик с
наименьшим статусом” не очень хорошо определены, поскольку значения статуса
не являются уникальными. Заданное требование интерпретируется так, что если
Sx и Sy — некоторые поставщики с “наибольшим статусом” и “наименьшим ста-
тусом” соответственно, то Sx и Sy не должны находиться в одном городе. Также
включена проверка того, что “наибольший статус” и “наименьший статус” не
равны между собой, иначе заданное требование не будет выполняться, в частно-
сти оно будет нарушаться, если существует лишь один поставщик.
3) CONSTRAINT Н IS_EMPTY ( J { CITY } MINUS S { CITY } ) ;
и) CONSTRAINT I IS_EMPTY ( J WHERE NOT ( TUPLE { CITY CITY } IN
( J { J# } JOIN SPJ JOIN S ) { CITY } ) ) ;
к) CONSTRAINT J NOT ( IS_EMPTY
( P WHERE COLOR = COLOR ( 'Red' ) ) ) ;
Заданное ограничение будет нарушено, если деталей нет совсем. Лучшей фор-
мулировкой ограничения могла бы быть такая.
CONSTRAINT J IS_EMPTY ( Р ) OR NOT ( IS_EMPTY
( P WHERE COLOR = COLOR ( 'Red' ) ) ) ;
338
Часть II. Реляционная модель
л) CONSTRAINT К IF NOT ( IS_EMPTY ( S ) )
THEN AVG ( S, STATUS ) > 18
END IF ;
В данном случае проверка существования поставщика необходима, поскольку
вычисление функции AVG при отсутствии аргумента могло бы привести к воз-
никновению исключительной ситуации.
м) CONSTRAINT L IS_EMPTY
( ( S WHERE CITY = 'London' ) { S# } MINUS
( SPJ WHERE P# = P# ( 'P2' ) ) { S# } ) ;
h) CONSTRAINT M IS_EMPTY ( P ) OR NOT
( IS_EMPTY ( P WHERE COLOR = COLOR ( 'Red' ) AND
WEIGHT < WEIGHT ( 50.0 ) ) ) ;
o) CONSTRAINT N
COUNT ( ( ( S WHERE CITY = 'London' ) JOIN SPJ ) { P# } ) >
COUNT ( ( ( S WHERE CITY = 'Paris' ) JOIN SPJ ) { P# } ) ;
n) CONSTRAINT 0
SUM ( ( ( S WHERE CITY = 'London' ) JOIN SPJ ), QTY ) >
SUM ( ( ( S WHERE CITY = 'Paris' ) JOIN SPJ ), QTY ) ;
p) CONSTRAINT P IS_EMPTY
( ( SPJ JOIN ( SPJ' RENAME QTY AS QTY' ) )
WHERE QTY > 0.5 * QTY' ) ;
c) CONSTRAINT Q IS_EMPTY (
( S JOIN ( S' WHERE CITY = 'Athens' ) ) WHERE
CITY * 'Athens' AND CITY * 'London' AND CITY * 'Paris' )
AND IS EMPTY (
( S JOIN ( S'“WHERE CITY = 'London' ) ) WHERE
CITY * 'London' AND CITY * 'Paris' ) ;
В качестве вспомогательного упражнения можно попытаться сформулировать
предыдущие ограничения в стиле реляционного исчисления, а не в стиле реля-
ционной алгебры.
8.2. Первые два ограничения, безусловно, являются ограничениями типа. Среди остав-
шихся ограничений в-ж, к, л, н, р и с — это ограничения переменной-отношения, а
все остальные — ограничения базы данных.
8.3.
а) Обращение к оператору выбора значения типа CITY.
б) Обращение к оператору выбора значения типа S#.
в) Операция вставки кортежа (INSERT) в переменную-отношение Р, операция об-
новления (UPDATE) значения атрибута веса детали WEIGHT.
г) Операция вставки (INSERT) кортежа в переменную-отношение J, операция обнов-
ления (UPDATE) значения атрибута CITY — города, в котором выполняется проект.
д) Операция вставки (INSERT) кортежа в переменную-отношение S, операция обнов-
ления (UPDATE) значения атрибута города, в котором находится поставщик CITY.
Глава 8. Целостность данных
339
е) Операция вставки (INSERT) или удаления (DELETE) кортежа из переменной-
отношения SPJ, операция обновления (UPDATE) значения атрибута размера по-
ставки QTY.
ж) Операция вставки (INSERT) или удаления (DELETE) кортежа из переменной-
отношения S, операция обновления (UPDATE) значения атрибута статуса постав-
щика STATUS.
з) Операция вставки (INSERT) кортежа в переменную-отношение J, операция уда-
ления (DELETE) кортежа из переменной-отношения S, операция обновления
(UPDATE) значения атрибута города, в котором находится поставщик или в кото-
ром выполняется проект CITY.
и) Операция вставки (INSERT) кортежа в переменную-отношение J, операция уда-
ления (DELETE) кортежа из переменной-отношения SPJ, операция обновления
(UPDATE) значения атрибута номера поставщика или номера проекта.
к) Операция вставки (INSERT) или удаления (DELETE) кортежа из переменной-
отношения Р, операция обновления (UPDATE) значения атрибута цвета детали COLOR.
л) Операция вставки (INSERT) или удаления (DELETE) кортежа из переменной-
отношения S, операция обновления (UPDATE) значения атрибута статуса постав-
щика STATUS.
м) Операция вставки (INSERT) кортежа в переменную-отношение S, операция уда-
ления (DELETE) кортежа из переменной-отношения SPJ, операция обновления
(UPDATE) значения атрибутов CITY — города, в котором находится поставщик,
номера поставщика S# или номера детали Р#.
н) Операция вставки (INSERT) или удаления (DELETE) кортежа из перемен-
ной-отношения Р, операция обновления (UPDATE) значения атрибута веса
детали WEIGHT.
о) Операция вставки (INSERT) или удаления (DELETE) кортежа из переменной-
отношения S или переменной-отношения SPJ, операция обновления (UPDATE)
значения атрибута CITY — города, в котором находится поставщик, номера по-
ставщика S# или номера детали Р#.
п) Операция вставки (INSERT) или удаления (DELETE) кортежа из переменной-
отношения S или переменной-отношения SPJ, операция обновления (UPDATE)
значения атрибута CITY — города, в котором находится поставщик, номера по-
ставщика S#, номера детали P# или размера поставки QTY.
р) Операция обновления (UPDATE) значения атрибута размера поставки QTY.
с) Операция обновления (UPDATE) значения атрибута CITY — города, в котором
находится поставщик.
8.4. Один тип. Уточнения “(5)” и “(3)” лучше рассматривать как ограничения целост-
ности. Как отмечалось в [3.3], первое желательное следствие такого подхода со-
стоит в том, что если переменные X и Y определены, как, скажем, CHAR(5) и
CHAR( 3) соответственно, то сравнение X и Y допустимо, поскольку в этом случае не
нарушается условие, требующее, чтобы участвующие в сравнении операнды были
одного и того же типа.
340
Часть II. Реляционная модель
8.5. Мы предлагаем в качестве “чернового” следующий перечень ответов (см. замеча-
ние в конце ответов к этому упражнению).
а) Любая операция выборки из переменной-отношения А наследует все потенци-
альные ключи этой переменной-отношения.
б) Если операция проекции включает любой потенциальный ключ К переменной-
отношения А, то К будет потенциальным ключом и для результирующего отно-
шения. В противном случае единственный потенциальный ключ результирую-
щего отношения — это комбинация из всех атрибутов данной проекции (в об-
щем случае).
в) Любое сочетание К потенциального ключа КА переменной-отношения А и по-
тенциального ключа КВ переменной-отношения В будет потенциальным ключом
для декартова произведения A TIMES В.
г) Единственный потенциальный ключ объединения A UNION В — это комбинация
из всех атрибутов (в общем случае).
д) Оставляем этот вариант в качестве упражнения для читателя (пересечение —
это не примитивная операция).
е) Каждый потенциальный ключ переменной-отношения А является потенциаль-
ным ключом для результата вычитания A MINUS В.
ж) Общий случай этого варианта оставляем в качестве упражнения для читателя
(естественное соединение — не примитивная операция). Однако заметим, что в
частном случае, когда соединяющий атрибут в переменной-отношении А явля-
ется ее потенциальным ключом, каждый потенциальный ключ переменной-
отношения В будет потенциальным ключом результата соединения.
з) Потенциальные ключи переменной-отношения А являются потенциальными
ключами и для произвольного расширения переменной-отношения А.
и) Потенциальными ключами для произвольной обобщающей операции в пере-
менной-отношении А “по переменной-отношению В” являются потенциальные
ключи переменной-отношения В.
к) Каждый потенциальный ключ переменной-отношения А является потенциальным
ключом для результата выполнения операции полусоединения A SEMIJOIN В.
л) Каждый потенциальный ключ переменной-отношения А является потенциальным
ключом для результата выполнения операции полувычитания A SEMIMINUS В.
Однако большинство упомянутых операторов в определенных ситуациях можно
некоторым образом усовершенствовать, как, например, показано ниже.
Сочетание атрибутов {S#, Р#, J#} не является потенциальным ключом для ре-
зультата выполнения операции выборки SPJ WHERE S# = S# ('S1'). Потенци-
альным ключом в этом случае является сочетание атрибутов {P#, J#}.
Если переменная-отношение А, имеющая заголовок {X, Y, Z} и единственный
потенциальный ключ X, удовлетворяет функциональной зависимости Y —> Z
(глава 10), то атрибут Y является потенциальным ключом проекции переменной-
отношения А по атрибутам Y и Z.
Глава 8. Целостность данных
341
Если переменные-отношения А и В одновременно являются результатами выполнения
операции выборки из переменной-отношения С, то каждый потенциальный ключ пе-
ременной-отношения С является потенциальным ключом объединения A UNION В.
И т.д. Вопрос о наследовании потенциальных ключей подробно обсуждается в [10.6].
8.6. Пусть ш— наименьшее целое число, большее либо равное п/2. Переменная-
отношение R будет иметь максимально возможное количество потенциальных
ключей, если все возможные множества из ш атрибутов являются потенциальными
ключами либо если п— нечетное число и все возможные множества из т-1 атри-
бутов являются потенциальными ключами. В обоих случаях максимальное количе-
ство потенциальных ключей равно п! / (m! * (n-ш)!).
Замечание. Переменные-отношения ELEMENT и MARRIAGE в разделе 8.8 могут слу-
жить примером переменных-отношений с максимально возможным количеством
потенциальных ключей.
8.7. Переменная-отношение R имеет в точности один потенциальный ключ, а имен-
но — пустое множество атрибутов {} (иногда обозначаемое как 0).
Замечание. Понятие пустого (или нульарного) потенциального ключа требует не-
которого уточнения. Такая переменная-отношение, как R, единственные допусти-
мые значения которой есть отношения DEE и DUM, не должна иметь атрибутов, и по-
этому “очевидно”, что ее единственный потенциальный ключ тоже не имеет атри-
бутов. Однако не только переменные-отношения без атрибутов могут иметь по-
добный потенциальный ключ. Отметим, что если пустое множество 0 является по-
тенциальным ключом некоторой переменной-отношения R, то должны быть вы-
полнены следующие условия.
Этот потенциальный ключ должен быть единственным потенциальным ключом
переменной-отношения R, так как любое другое множество атрибутов этой пере-
менной-отношения можно рассматривать как правильное надмножество пустого
множества, что нарушало бы требование неизбыточности потенциальных клю-
чей. (Следовательно, этот потенциальный ключ будет также первичным, если
первичный ключ обязательно должен быть выбран.)
В переменной-отношении R не может содержаться более одного кортежа, потому
что в пустом множестве атрибутов любой кортеж имеет одно и то же значение.
Заметим, что наш Синтаксис позволяет определить такую переменную-отношение,
как, например, показано ниже.
VAR R BASE RELATION { ... }
PRIMARY KEY { } ;
Также можно определить переменную-отношение без атрибутов, т.е. переменную-
отношение, которая может принимать только два значения: DEE и DUM.
VAR R BASE RELATION { }
PRIMARY KEY { } ;
Возвращаясь к вопросу о пустом потенциальном ключе, отметим, что если потенци-
альный ключ может быть пустым, то, конечно, может быть пустым и соответствую-
щий ему внешний ключ. В [5.5] эти возможности обсуждаются более подробно.
342
Часть II. Реляционная модель
8.8. Для внешних ключей “правило вставки” в явном виде не существует, поскольку
операции вставки (INSERT) для ссылающейся переменной-отношения (а также опе-
рации обновления (UPDATE) для внешнего ключа в ссылающейся переменной-
отношении) контролируются с помощью самого правила ссылочной целостности,
т.е. в соответствии с требованием, гласящим, что не должно быть несогласованных
значений внешнего ключа. Поясним это другими словами на конкретном примере
базы данных поставщиков и деталей.
Попытка вставить кортеж поставки (в переменную-отношение SP) будет успеш-
ной, только если номер поставщика в этом кортеже существует как номер по-
ставщика в переменной-отношении S и номер детали в этом кортеже существует
как номер детали в переменной-отношении Р.
Попытка обновить кортеж поставки будет успешной, если в обновленном кортеже
номер поставщика существует как номер поставщика в переменной-отношении S и
номер детали существует как номер детали в переменной-отношении Р.
Обратите особое внимание на то, что предыдущие замечания относятся к ссылаю-
щейся переменной-отношению, тогда как правила удаления и обновления (явные)
применяются к ссылочной переменной-отношению. Поэтому “правило вставки”
нельзя рассматривать как правило, подобное правилам удаления и обновления. Это
еще одна причина, по которой в конкретный синтаксис не включено никакое явное
“правило вставки”.
8.9.
а) Операция допустима.
б) Операция недопустима (нарушение уникальности потенциального ключа).
в) Операция недопустима (нарушение правила обновления с установленной опци-
ей RESTRICTED).
г) Операция допустима (удаляется кортеж поставщика с номером 'S3' и соответ-
ствующие кортежи его поставок).
д) Операция недопустима (нарушение правила обновления с установленной опци-
ей RESTRICTED).
е) Операция допустима (удаляется кортеж проекта под номером ' J4' и соответст-
вующие кортежи поставок для этого проекта).
ж) Операция допустима.
з) Операция недопустима (нарушение уникальности потенциального ключа).
и) Операция недопустима (нарушение ссылочной целостности).
к) Операция допустима.
л) Операция недопустима (нарушение ссылочной целостности).
м) Операция недопустима (нарушение ссылочной целостности— номер проекта
по умолчанию (' j j j') не существует в переменной-отношении J).
8.10. Ссылочная диаграмма показана на рис. 8.1. Возможный вариант определения базы
данных представлен ниже. Для упрощения никакие ограничения типов не опреде-
ляются, если не считать того, что спецификация POSSREP для данного определения
типа, безусловно, может априори пониматься, как его ограничение.
Глава 8. Целостность данных
343
TYPE COURSE# POSSREP ( CHAR ) ;
TYPE TITLE POSSREP ( CHAR ) ;
TYPE OFF# POSSREP ( CHAR ) ;
TYPE OFFDATE POSSREP ( DATE ) ;
TYPE CITY POSSREP ( CHAR ) ;
TYPE EMP# POSSREP ( CHAR ) ;
TYPE NAME POSSREP ( NAME ) ;
TYPE JOB POSSREP ( CHAR ) ;
TYPE GRADE POSSREP ( CHAR ) ;
VAR COURSE BASE RELATION
{ COURSE# COURSE#,
TITLE TITLE }
PRIMARY KEY { COURSE# } ;
VAR PREREQ BASE RELATION
{ SUP_COURSE# COURSE#,
SUB_COURSE# COURSE# }
PRIMARY KEY { SUP_COURSE#, SUB_COURSE# }
FOREIGN KEY { RENAME SUP_COURSE# AS COURSE# }
REFERENCES COURSE
ON DELETE CASCADE
ON UPDATE CASCADE
FOREIGN KEY { RENAME SUB_COURSE# AS COURSE# }
REFERENCES COURSE
ON DELETE CASCADE
ON UPDATE CASCADE ;
VAR OFFERING BASE RELATION
{ COURSE# COURSE#,
OFF# OFF#,
OFFDATE OFFDATE,
LOCATION CITY }
PRIMARY KEY { COURSE#, OFF# }
FOREIGN KEY { COURSE# } REFERENCES COURSE
ON DELETE CASCADE
ON UPDATE CASCADE ;
VAR EMPLOYEE BASE RELATION
{ EMP# EMP#,
ENAME ENAME,
JOB JOB }
PRIMARY KEY { EMP# } ;
VAR TEACHER BASE RELATION
{ COURSE# COURSE#,
OFF# OFF#,
EMP# EMP# }
PRIMARY KEY { COURSE#, OFF#, EMP# }
344
Часть II. Реляционная модель
FOREIGN KEY { COURSE#, OFF# } REFERENCES OFFERING
ON DELETE CASCADE
ON UPDATE CASCADE ;
FOREIGN KEY { EMP# } REFERENCES EMPLOYEE
ON DELETE CASCADE
ON UPDATE CASCADE •,
VAR ENROLLMENT BASE RELATION
{ COURSE# COURSE#,
OFF# OFF#,
EMP# EMP#
GRADE GRADE }
PRIMARY KEY { COURSE#, OFF#, EMP# }
FOREIGN KEY { COURSE#, OFF# } REFERENCES OFFERING
ON DELETE CASCADE
ON UPDATE CASCADE
FOREIGN KEY { EMP# } REFERENCES EMPLOYEE
ON DELETE CASCADE
ON UPDATE CASCADE ;
Puc. 8.1. Ссылочная диаграмма для учебной базы
данных
Пояснения
1. Множества атрибутов (единичные) {COURSE#} в переменной-отношении
TEACHER и {COURSE#} в переменной-отношении ENROLLMENT можно также рас-
сматривать как внешние ключи, ссылающиеся на переменную-отношение
COURSE. Если ссылочные ограничения от переменной-отношения TEACHER к
переменной-отношению OFFERING, от переменной-отношения ENROLLMENT к
переменной-отношению OFFERING и от переменной-отношения OFFERING к
переменной-отношению COURSE организованы должным образом, то ссылоч-
ные ограничения от переменной-отношения TEACHER к переменной-
отношению COURSE будут поддерживаться автоматически. Более детальное
обсуждение этого вопроса приведено в [8.10].
Глава 8. Целостность данных
345
2. Переменная-отношение OFFERING в этом примере является одновременно ссы-
лающейся и ссылочной: существует ссылочное ограничение к переменной-
отношению OFFERING от переменной-отношения ENROLLMENT (на самом деле от
переменной-отношения TEACHER) и от переменной-отношения OFFERING к пере-
менной-отношению COURSE.
ENROLLMENT ---> OFFERING ---> COURSE
3. Обратите внимание, что существует два различных ссылочных пути от пере-
менной-отношения ENROLLMENT к переменной-отношению COURSE: один непо-
средственный (внешний ключ {COURSE#} в переменной-отношении ENROLLMENT)
и другой — непрямой, через переменную-отношение OFFERING (внешние ключи
{COURSE#,OFF#} в переменной-отношении ENROLLMENT и {COURSE#} в перемен-
ной-отношении OFFERING).
I
ENROLLMENT -» OFFERING COURSE
Однако в действительности эти пути не являются независимыми (верхний путь
представляет собой комбинацию двух нижних). Более подробное обсуждение
этого вопроса можно найти в [8.10].
4. Также существует два различных ссылочных пути от переменной-отношения
PREREQ к переменной-отношению COURSE, но на этот раз они действительно не-
зависимы (и имеют совсем разный смысл). И вновь за подробным обсуждением
обратитесь к [8.10].
8.11. Ссылочная диаграмма показана на рис. 8.2.
Обратите внимание, что в базе данных име-
ется ссылочный цикл (т.е. существует ссы-
лочный путь от каждой из двух перемен-
ных-отношений к самой себе). Поскольку
определение базы данных для этого упраж-
нения несложное, мы его опускаем и не
вдаемся в подробности.
8.12. Ниже приведены только определения переменных-отношений (и лишь схематически).
VAR ЕМР BASE RELATION
{ EMP# ... ,
DEPT
MGR_EMP# | | DEPT#
EMP
Puc. 8.2. Ссылочная диаграмма с
циклом
JOB ... }
PRIMARY KEY { EMP# } ;
VAR PGMR BASE RELATION
{ EMP# ... ,
LANG ... }
PRIMARY KEY { EMP# }
346
Часть II Реляционная модель
FOREIGN KEY { EMP# } REFERENCES EMP
ON DELETE CASCADE
ON UPDATE CASCADE ;
Пояснения
1. В этом примере иллюстрируется наше замечание о том, что внешний ключ мо-
жет быть также потенциальным ключом содержащей его переменной отноше-
ния. В переменной-отношении ЕМР содержится список всех служащих, а в пе-
ременной-отношении PGMR— список тех служащих, которые работают про-
граммистами. Поэтому каждый номер служащего, присутствующий в перемен-
ной-отношении PGMR, должен присутствовать и в переменной-отношении ЕМР
(заметьте, что обратное утверждение неверно). Поэтому первичный ключ пере-
менной-отношения PGMR также является внешним ключом, ссылающимся на
первичный ключ переменной-отношения ЕМР.
2. Отметим, что в этом примере существует еще одно ограничение целостности,
которое также необходимо поддерживать: служащий должен быть представлен
в переменной-отношении PGMR тогда и только тогда, когда значение атрибута
ЕМР.JOB для этого служащего— 'Программист'. Однако это, безусловно, не
ссылочное ограничение.
8.14. Отметим, что приведенные ниже варианты решения для пп. а и б — это лишь при-
ближения к их аналогам, представленным в ответах к упр. 8.1.
a) CREATE DOMAIN CITY CHAR(15) VARYING
CONSTRAINT VALID_CITIES
CHECK ( VALUE IN ( 'London', 'Paris', 'Rome',
'Athens', 'Oslo', 'Stockholm',
'Madrid', 'Amsterdam' ) ) ;
6) CREATE DOMAIN S# CHAR(5)VARYING
CONSTRAINT VALID_S# CHECK
( SUBSTRING ( VALUE FROM 1 FOR 1 ) = 'S' AND
CAST ( SUBSTRING ( VALUE FROM 2 ) AS INTEGER ) >= 0 AND
CAST ( SUBSTRING ( VALUE FROM 2 ) AS INTEGER ) <= 9999 ) ;
в) CREATE ASSERTION SQL_C CHECK
( P.COLOR <> 'Red' OR P.WEIGHT < 50.0 ) ;
r) CREATE ASSERTION SQL_D CHECK
( NOT EXISTS ( SELECT * FROM J JX WHERE
EXISTS ( SELECT * FROM J JY WHERE
( JX.J# <> JY.J# AND
JX.CITY = JY.CITY ) ) ) ) ;
д) CREATE ASSERTION SQL_E CHECK
( ( SELECT COUNT (*) FROM S
WHERE S.CITY = 'Athens' ) < 2 ) ;
e) CREATE ASSERTION SQL_F CHECK
( NOT EXISTS ( SELECT *
FROM SPJ SPJX
WHERE SPJX.QTY > 2 *
Глава 8. Целостность данных
347
( SELECT AVG ( SPJY.QTY )
FROM SPJ SPJY ) ) ) ;
ж) CREATE ASSERTION SQL_G CHECK
( NOT EXISTS ( SELECT * FROM S SX WHERE
EXISTS ( SELECT * FROM S SY WHERE
SX.STATUS = ( SELECT MAX ( S.STATUS )
FROM S ) AND
SY.STATUS = ( SELECT MIN ( S.STATUS )
FROM S ) AND
SX.SATUS <> SY.STATUS AND
SX.CITY = SY.CITY ) ) ) ;
3) CREATE ASSERTION SQL_H CHECK
( NOT EXISTS ( SELECT * FROM J WHERE
NOT EXISTS ( SELECT * FROM S WHERE
S. CITY = J. CITY ) ) ) ;
и) CREATE ASSERTION SQL_I CHECK
( NOT EXISTS ( SELECT * FROM J WHERE
NOT EXISTS ( SELECT * FROM S WHERE
S.CITY = J.CITY AND
EXISTS ( SELECT * FROM SPJ
WHERE SPJ.S# = S.S#
AND SPJ.J# = J.J# ) ) ) ) ;
к) CREATE ASSERTION SQL_J CHECK
( NOT EXISTS ( SELECT * FROM P )
OR EXISTS ( SELECT * FROM P
WHERE P.COLOR = 'Red' ) ) ;
л) CREATE ASSERTION SQL_K CHECK
( ( SELECT AVG ( S.STATUS ) FROM S ) > 18 ) ;
Если таблица поставщиков пуста, SQL-оператор AVG будет (ошибочно!) воз-
вращать нулевое значение, результатом условного выражения будет значение
неизвестно и ограничение не будет считаться нарушенным. В главе 18 можно
получить дополнительные сведения по этому вопросу.
м) CREATE ASSERTION SQL_L CHECK
( NOT EXISTS ( SELECT * FROM S
WHERE S.CITY = 'London'
AND NOT EXISTS
( SELECT * FROM SPJ
WHERE SPJ.S# = S.S#
AND SPJ.P# = 'P2' ) ) ) ;
h) CREATE ASSERTION SQL_M CHECK
( NOT EXISTS ( SELECT * FROM P
WHERE P.COLOR = 'Red' )
OR EXISTS ( SELECT * FROM P
WHERE P.COLOR = 'Red'
AND P.WEIGHT <50.0 ) ) ;
348
Часть IL Реляционная модель
о) CREATE ASSERTION SQL_N CHECK
( ( SELECT COUNT (*) FROM P
WHERE EXISTS ( SELECT * FROM SPJ WHERE
EXISTS ( SELECT * FROM S WHERE
( P.P# = SPJ.P# AND
SPJ.S# = S.S# AND
S.CITY = 'London' ) ) ) ) >
( SELECT COUNT (*) FROM P
WHERE EXISTS ( SELECT * FROM SPJ WHERE
EXISTS ( SELECT * FROM S WHERE
( P.P# = SPJ.P# AND
SPJ.S# = S.S# AND
S.CITY = 'Paris' )))));
n) CREATE ASSERTION SQL_O CHECK
( ( SELECT SUM (SPJ.QTY) FROM SPJ
WHERE ( SELECT S.CITY FROM S
WHERE S.S# = SPJ.S# ) = 'London' ) >
( SELECT SUM (SPJ.QTY) FROM SPJ
WHERE ( SELECT S.CITY FROM S
WHERE S.S# = SPJ.S# ) = 'Paris' ) ) ;
p) Реализовать невозможно.
с) Реализовать невозможно.
Глава 8. Целостность данных
349
Глава
Представления
9.1. Введение
Как отмечалось в главе 3, представление, по сути, является именованным выражени-
ем реляционной алгебры (или чем-либо, что равносильно выражению реляционной ал-
гебры). Например:
VAR GOOD_SUPPLIER VIEW
( S WHERE STATUS >15 ) { S#, STATUS, CITY } ;
Когда данный оператор выполняется, выражение реляционной алгебры (т.е. выраже-
ние определения представления) не вычисляется, а просто запоминается системой по-
средством его записи в каталог базы данных под указанным именем GOOD_SUPPLIER. Тем
не менее со стороны пользователя это выглядит так, как будто в базе данных существует
реальная переменная-отношение GOOD_SUPPLIER с собственными кортежами и атрибута-
ми, показанными в незатененной части рис. 9.1 (имеется в виду, конечно, наш обычно
используемый пример значений данных). Другими словами, имя GOOD_SUPPLIERS обо-
значает производную (и виртуальную) переменную-отношение. Ее значение в любой
момент представляет собой отношение, которое было бы получено в качестве результата
в случае, если бы определяющее представление выражение было действительно вычис-
лено в данный момент.
GOOD_SUPPLIERS S# SNAME STATUS CITY
S1 Smith 20 London
S2 Jones 10 Paris
S3 Blake 30 Paris
S4 Clark 20 London
S5 Adams 30 Athens
Рис. 9.1. Представление G00D_SUPPLIER как заданный фрагмент базовой переменной-
отношения S (незатененные части таблицы)
В главе 3 также было показано, что любое представление в некотором смысле
можно считать просто окном для просмотра данных. Любые изменения, вносимые в
исходную базовую таблицу, будут автоматически и мгновенно отображаться в пред-
ставлении (как в окне), конечно, если они попадут в область видимости данного пред-
ставления. И наоборот, все изменения, вносимые в представление, будут автоматиче-
ски переноситься в данные исходной базовой таблицы, в результате чего станут види-
мы и в самом представлении.
350
Часть II. Реляционная модель
В реальной ситуации многие пользователи могут даже не предполагать, что
GOOD_SUPPLIER — это представление. Одни пользователи могут знать об этом, а также о
том, что существует реальная переменная-отношение S, тогда как другие могут искренне
верить, что GOOD_SUPPLIERS — настоящая переменная-отношение. Но в любом случае
главное то, что с представлением можно работать так, как будто оно является настоящей
переменной-отношением. Приведем пример запроса к представлению GOOD_SUPPLIER.
GOOD_SUPPLIER WHERE CITY * 'London' ;
Ниже показан результат выполнения этого запроса.
S# STATUS CITY
S3 30 Paris
S5 30 Athens
Этот запрос, безусловно, похож на обычный запрос к обычной “реальной” перемен-
ной-отношению. Как отмечалось в главе 3, система обрабатывает запросы подобного ти-
па путем их преобразования в запросы к базовой переменной-отношению (или базовым
переменным-отношениям). Подобное преобразование осуществляется посредством за-
мены в определении запроса всех вхождений имени представления тем выражением, ко-
торое его определяет. В нашем примере после процедуры подстановки будет получен
следующий запрос.
( ( S WHERE STATUS > 15 ) { S#r STATUS, CITY } )
WHERE CITY * 'London' ;
Данное выражение можно легко преобразовать в более простую форму.
( S WHERE STATUS > 15 AND CITY * 'London' )
{ S#, STATUS, CITY } ;
Результат вычисления последнего выражения совпадает с приведенным выше резуль-
татом запроса к представлению.
В этой связи необходимо отметить, что процесс подстановки (т.е. процесс замены
имени представления определяющим его выражением) выполняется корректно вследст-
вие реляционного свойства замкнутости. Свойство замкнутости (кроме всего прочего)
означает, что в любом месте выражения, где разрешено использовать имя переменной-
отношения R, вместо него можно применять некоторое выражение X (естественно, пред-
полагается, что в результате вычисления выражения X мы получим отношение того же
типа, что и R). Другими словами, представления работают точно, поскольку для реляци-
онной алгебры множество всех отношений замкнуто, и это еще один пример, подтвер-
ждающий фундаментальное значение свойства реляционной замкнутости.
Операции обновления на представлениях обрабатываются аналогично. Например,
рассмотрим следующую операцию.
UPDATE GOOD_SUPPLIER WHERE CITY = 'Paris'
STATUS := STATUS + 10 ;
При обработке она будет приведена к такому виду.
Глава 9. Представления
351
UPDATE S WHERE STATUS > 15 AND CITY = 'Paris'
STATUS := STATUS + 10 ;
Для операций INSERT и DELETE применяется тот же подход.
Дополнительные примеры
В этом подразделе представлено несколько примеров, на которые в дальнейшем мы
будем ссылаться.
1. VAR REDPART VIEW
( ( Р WHERE COLOR = COLOR ( 'Red' ) ) {ALL BUT COLOR } )
RENAME WEIGHT AS WT ;
В представлении REDPART присутствуют атрибуты P#, PNAME, WT и CITY. В него по-
мещаются только те кортежи, которые описывают красные детали.
2. VAR PQ VIEW
SUMMARIZE SP PER P { P# } ADD SUM ( QTY ) AS TOTQTY ;
В отличие от представлений GOODJSUPPLIER и REDPARTS, представление PQ не явля-
ется простым подмножеством данных, получаемым посредством операции выбор-
ки или проекции некоторой базовой переменной-отношения. Это представление
можно рассматривать как статистический итог или результат обобщения данных
исходной переменной-отношения.
3. VAR CITY_PAIR VIEW
( ( S RENAME CITY AS SCITY ) JOIN SP JOIN
( P RENAME CITY AS PCITY ) ) { SCITY, PCITY } ;
Пара имен городов (x, у) появляется в представлении CITY_PAIR тогда и только
тогда, когда поставщик, находящийся в городе х, поставляет детали, которые хра-
нятся в городе у. Например, поставщик с номером ' S1' поставляет детали с номе-
ром 'Р1'. При этом данный поставщик находится в Лондоне и поставляемые им
детали хранятся также в Лондоне. В результате в представлении CITY_PAIR будет
присутствовать пара названий городов (' London', ' London').
4. VAR HEAVY_REDPART VIEW
REDPART WHERE WT > WEIGHT ( 12.0 ) ;
В этом примере демонстрируется, как одно представление определяется через другое.
Определение и удаление представлений
Синтаксис оператора определения представления выглядит следующим образом.
VAR <имя переменной-отношениЯ> VIEW реляционное выражений
<список определения потенциальных ключей^
В приведенном выражении параметр <список определения потенциальных ключейР мо-
жет быть пустым, поскольку система должна уметь определять потенциальные ключи пред-
ставления самостоятельно [10.6]. Например, в случае представления GOODJSUPPLIER системе
должно быть известно, что единственным потенциальным ключом, о котором может идти
речь, является ключ {S#}, унаследованный от исходной базовой переменной-отношения S.
352
Часть II. Реляционная модель
Как уже отмечалось (используя терминологию ANSI/SPARC, обсуждавшуюся в
главе 2), определения представлений объединяют функции внешней схемы и функции
отображения уровня “внешний-концептуальный", поскольку они описывают и сам
внешний объект (т.е. представление), и способ его отображения на концептуальный уро-
вень (т.е. на одну или несколько исходных базовых переменных-отношений).
Замечание. Некоторые определения представлений задают не отображение уровня
“внешний-концептуальный”, а отображение уровня “внешний-внешний”. Представление
HEAVY_REDPART из предыдущего раздела относится именно к такой категории представлений.
Синтаксис оператора удаления представления имеет следующий вид.
DROP VAR <имя переменной-отношения» ;
Здесь параметр <имя переменной-отношения» определяет имя удаляемого представле-
ния. В главе 5 было установлено, что попытка удалить базовую переменную-отношение за-
вершится неудачей, если существует хотя бы одно определение представления, ссылаю-
щееся на удаляемую переменную-отношение. Аналогично следует полагать, что удаление
представления, на которое имеется ссылка в определении какого-либо другого представле-
ния, также приведет к ошибке. Дополнительно (по аналогии со ссылочными ограничения-
ми) можно расширить оператор определения представления, включив в него опцию
RESTRICT или CASCADE. Опция RESTRICT, подразумеваемая по умолчанию, означает, что по-
пытка удаления любой переменной-отношения, на которую имеется ссылка в определении
данного представления, будет отклонена. А опция CASCADE допускает такое удаление, но
при этом также удаляются все представления, которые ссылаются на данное.
Замечание. Стандартная версия языка SQL не поддерживает подобной опции в опера-
торе определения представления, однако она включена в оператор DROP. Также не огово-
рено, какое значение опции будет использоваться по умолчанию; требуется явно указы-
вать одно из значений опции (см. раздел 9.6).
9.2. Для чего нужны представления
Поддержка представлений желательна по многим причинам. Укажем некоторые из них.
Обеспечивается автоматическая защита скрытых данных
Под “скрытыми данными” здесь подразумеваются данные базовых таблиц, кото-
рые не видны в определенном представлении (например, в случае представления
GOOD_SUPPLIER это имена поставщиков). Такие данные надежно защищены от не-
желательного доступа через конкретное представление (по крайней мере, в отно-
шении операции выборки). Таким образом, ограничив доступ пользователей к ба-
зе данных некоторым набором представлений, можно получить простой и эффек-
тивный механизм обеспечения безопасности. Мы еще возвратимся к вопросу ис-
пользования представлений в целях безопасности в главе 16.
Пользователям предоставляются средства сокращенной записи или “макросы ”
Рассмотрим запрос “Определить все города, в которых хранятся детали, постав-
ляемые некоторым поставщиком из Лондона”. Требуемый запрос можно легко
сформулировать с помощью представления CITY_PAIR (пары городов), определен-
ного в предыдущем разделе.
( CITY_PAIR WHERE SCITY = 'London' ) { PCITY }
Глава 9. Представления
353
Сформулировать данный запрос, не пользуясь этим представлением, будет сложнее.
( ( ( S RENAME CITY AS SCITY )
JOIN SP
JOIN ( P RENAME CITY AS PCITY ) )
WHERE SCITY = 'London' ) { PCITY }
Хотя пользователь может применить последнюю формулировку, обращаясь не-
посредственно к базовой переменной-отношению (конечно, только в том случае,
когда установленные ограничения безопасности позволяют ему это сделать), пер-
вая формулировка запроса, безусловно, проще. (Первая формулировка запроса на
самом деле является просто сокращением второй. Перед выполнением запроса
системный механизм обработки представлений расширит первое выражение и по-
лучит запрос в виде второго выражения.)
Просматривается явная аналогия с макросами в языках программирования.
В принципе, пользователь может непосредственно записывать расширен-
ные выражения в собственный код, но намного удобнее (по известным при-
чинам) не делать этого и использовать сокращенную запись макросов, воз-
ложив процедуру их расширения на макропроцессор языка программирова-
ния. Аналогичные замечания применимы и в отношении представлений. Та-
ким образом, в СУБД представления играют роль, аналогичную роли макро-
сов в системах программирования, а хорошо известные преимущества и вы-
годы от использования макросов имеют место (с соответствующими ого-
ворками) и в случае представлений. В частности, следует отметить, что ис-
пользование представлений, как и использование макросов не приводит на
этапе выполнения к снижению производительности приложений — некото-
рые дополнительные затраты имеют место только на этапе раскрытия пред-
ставлений (как и в случае макросов).
Представления позволяют разным пользователям различным образом видеть од-
ни и те же данные в одно и то же время
Другими словами, представления позволяют различным пользователям сосредо-
точить свое внимание и, возможно, логически реструктуризировать только ту
часть базы данных, которая их интересует, игнорируя все остальные сохраняемые
данные. Это соображение особенно важно для интегрированных баз данных, с ко-
торыми одновременно и независимо друг от друга работает множество категорий
пользователей, имеющих самые различные требования.
Представления способны обеспечивать логическую независимость данных
Это одна из важнейших потенциальных возможностей представлений, поэтому мы
рассмотрим ее отдельно в следующем разделе.
Логическая независимость данных
Напомним, что логическая независимость данных может быть определена как имму-
нитет пользователей и пользовательских программ к изменениям в логической струк-
туре базы данных (где под логической структурой подразумевается концептуальный
или “общий логический” уровень; см. главу 2). Несомненно, что представления являются
354
Часть II Реляционная модель
именно тем средством, с помощью которого в реляционной системе может быть достиг-
нута логическая независимость данных. Логическая независимость данных имеет два
важных аспекта — рост и реструктуризация базы данных.
Замечание. Аспект роста здесь обсуждается только для полноты изложения. Он дос-
таточно важен, но его связь с представлениями весьма относительна.
Рост базы данных
По мере роста базы данных, аккумулирующей новые виды информации, должно
соответственно возрастать и количество определений. Возможны два типа роста.
а) Расширение существующей базовой переменной-отношения с целью включе-
ния нового атрибута. Новый атрибут предназначен для вновь добавляемых дан-
ных, относящихся к существующему типу объектов. В качестве примера приве-
дем добавление атрибута DISCOUNT (скидка) в базовую переменную-отношение
поставщиков.
б) Создание новой базовой переменной-отношения для добавления в базу данных
информации об объектах нового типа. Примером может служить добавление в
базу данных поставщиков и деталей сведений о проектах.
Ни один из указанных типов роста не должен оказывать какого-либо влияния на ра-
боту существующих пользователей или пользовательских программ, по крайней мере в
принципе (однако см. упр. 7.7 в главе 7, в котором рассматривается одна из проблем,
возникающих при использовании языка SQL).
Реструктуризация базы данных
Иногда возникает необходимость так реструктуризировать базу данных, чтобы ее
общее информационное наполнение осталось тем же, а изменилось только логиче-
ское расположение данных. Другими словами, требуется перегруппировка атри-
бутов базовых переменных-отношений. Рассмотрим простой пример реструктури-
зации. Предположим, что по какой-то причине (в данном случае точная причина
не имеет значения) необходимо заменить переменную-отношение S следующими
двумя переменными-отношениями.
VAR SNC BASE RELATION { S# S#, SNAME SNAME, CITY CHAR }
PRIMARY KEY { S# } ;
VAR ST BASE RELATION { S# S#, STATUS INTEGER }
PRIMARY KEY { S# } ;
Здесь существенно то, что прежняя переменная-отношение S является соедине-
нием двух новых переменных-отношений SNC и ST (а переменные-отношения SNC
и ST являются проекциями старой переменной-отношения S). Следовательно,
можно создать представление, которое будет предусматривать выполнение ука-
занного соединения, и присвоить ему имя S.
VAR S VIEW
SNC JOIN ST ;
Любая прикладная программа или интерактивная операция, в которой использо-
валась прежняя переменная-отношение S, теперь будет ссылаться на представле-
ние S. Следовательно, если предположить, что система корректно поддержива-
Глава 9. Представления
355
ет операции .манипулирования данными в представлениях, пользователи и поль-
зовательские программы действительно окажутся логически независимыми от по-
добной реструктуризации базы данных1.
Следует отметить, что замена исходной переменной-отношения S, содержащей
данные о поставщиках, двумя проекциями этой переменной-отношения, SNC и ST,
в общем случае является вовсе нетривиальной задачей. В частности, следует учи-
тывать, что некоторых дополнительных действий потребует переменная-
отношение SP, содержащая сведения о поставках, поскольку в ней используется
внешний ключ, ссылающийся на исходную переменную-отношение поставщиков
S (см. упр. 9.13).
Но возвратимся к главной теме обсуждения. Из примера с переменными-отношениями
SNC и ST, конечно, не следует, что логическая независимость данных может быть дос-
тигнута при любой возможной реструктуризации. Ключевой вопрос здесь состоит в
том, возможно ли однозначное отображение между версией базы данных после рест-
руктуризации и ее исходной версией (т.е. обратима ли выполненная реструктуризация
базы данных). Другими словами, вопрос заключается в том, являются ли эти две вер-
сии базы данных информационно-эквивалентными. Если нет, то совершенно оче-
видно, что логическая независимость данных будет недостижима.
Два важных принципа
В результате проведенного выше обсуждения логической независимости данных воз-
никает еще один вопрос. Фактически представления имеют два совершенно разных на-
значения.
Пользователь, который реально определяет некоторое представление V, безуслов-
но, знаком с соответствующим выражением X, определяющим это представление.
Он может использовать имя V везде, где применимо выражение X, причем, в сущ-
ности, как мы уже убедились, это просто сокращенная запись данного выражения.
Пользователь, которому просто известно, что представление V существует и его
можно применять, чаще всего не знаком с выражением X, определяющим это
представление. Для него представление V должно выглядеть и вести себя точно
так, как базовая переменная-отношение.
Из сказанного можно сделать вывод, что вопрос, какой является данная переменная-
отношение, базовой или производной (т.е. представлением), в известной мере является
спорным! Рассмотрим случай переменных-отношений S, SNC и ST, использовавшихся в
1 Это в принципе! К сожалению, современные продукты (и сам стандарт языка SQL) в целом
некорректно поддерживают операции обработки данных представлений и, следовательно, эти
программные продукты не обеспечивают в должной мере логической независимости от показан-
ных в примере изменений. Говоря конкретнее, большинство программных продуктов (но не все) в
настоящее время корректно поддерживает только операции выборки данных через представле-
ния и, насколько известно автору, ни один из продуктов не поддерживает операций обновления
данных в представлениях корректно на все 100%. Поэтому такие продукты обеспечивают логи-
ческую независимость от структуры базы данных для операций выборки данных, но не для опе-
раций обновления данных.
356
Часть II. Реляционная модель
обсуждении вопросов “реструктуризации” в предыдущем разделе. Очевидно, что можно
либо определить S как базовую переменную-отношение, a SNC и ST — как представления
проекции этой базовой переменной-отношения, либо определить SNC и ST как базовые
переменные-отношения, aS — как представление соединения этих двух базовых пере-
менных-отношений2. Отсюда следует, что не должно быть никаких предпочтений и
никаких ненужных различий между базовыми и производными переменными-
отношениями. Мы называем это утверждение принципом взаимозаменяемости
базовых и производных переменных-отношений. Заметим в частности, что из этого
принципа следует, что должна существовать возможность обновления представлений.
Иначе говоря, возможности обновления базы данных не должны зависеть от произволь-
ного по существу решения, каким переменным-отношениям быть базовыми, а каким —
производными. Обсуждение этого вопроса будет продолжено в разделе 9.4.
Условимся пока называть множество всех базовых переменных-отношений
“реальной” базой данных. Но типичный пользователь взаимодействует (в общем случае)
не с реальной базой данных самой по себе, а с тем, что можно назвать
“представительной” базой данных, состоящей (опять-таки, в общем случае) из некоторой
смеси базовых переменных-отношений и представлений. Теперь предположим, что ни
одна из переменных-отношений в такой представительной базе данных не может быть
производной от остальных (в противном случае такая переменная-отношение могла бы
быть удалена без потери данных)3. Поэтому, с точки зрения пользователя, все эти пере-
менные-отношения являются базовыми переменными-отношениями по определению,
поскольку они, безусловно, не зависят одна от другой (т.е. все они автономны в соответ-
ствии с терминологией главы 3). То же самое относится и к самой базе данных, т.е. вы-
бор, какая база данных является “реальной”, может быть сделан произвольно, поскольку
все возможные варианты информационно равносильны. Последний вывод мы будем на-
зывать принципом относительности базы данных.
9.3. Выборка данных из представлений
В предыдущих разделах кратко описывалась процедура преобразования операций
выборки из представлений в эквивалентные операции выборки из одной или нескольких
базовых переменных-отношений. В данном разделе приводится более формальное опи-
сание этого преобразования.
Прежде всего, следует отметить, что любое заданное реляционное выражение можно
рассматривать как функцию на множестве отношений. Иными словами, текущие значе-
ния различных переменных-отношений, упоминаемых в выражении, представляют собой
аргументы данного вызова этой функции, а результатом ее вычисления является другое
отношение. Пусть D — это база данных (которая будет представлена в данном случае как
множество переменных отношений), а V — это представление, определенное на множе-
стве D, т.е. представление, определение которого является функцией X на множестве D.
V = X ( D )
2 См. обсуждение декомпозиции без потерь в разделе 11.2 главы 11.
3 Здесь игнорируются любые представления, определенные пользователем, которые, как мы
уже убедились, являются просто сокращенной записью некоторого выражения
Глава 9. Представления
357
Пусть R — операция выборки из представления V. Тогда очевидно, что R также является
функцией на множестве отношений, а результат выборки будет иметь следующий вид.
R(V)=R(X(D))
Таким образом, результат операции выборки по определению совпадает с результа-
том вычисления функции X на множестве D, т.е. овеществления копии отношения, яв-
ляющегося текущим значением представления V, с последующим применением операции
R к этой овеществленной копии. Однако на практике эффективнее использовать описан-
ную выше процедуру подстановки (см. раздел 9.1). Эта процедура равносильна форми-
рованию функции С, являющейся композицией R( X) функций X и R (именно в этом по-
рядке), и вычислению результата применения функции С к множеству D. Но как бы то ни
было, все-таки удобнее, по крайней мере концептуально, дать определение семантики
операции выборки из представлений в терминах овеществления, а не подстановки. Дру-
гими словами, подстановка допустима потому, что она гарантирует получение того же
результата, который мог быть получен при использовании овеществления (и это, безус-
ловно, гарантируется).
Все изложенное в предыдущем разделе должно быть, в основном, уже знакомо чита-
телю. Тем не менее мы сочли необходимым еще раз привести этот материал здесь и вот
по каким причинам.
Во-первых, он дает основу для аналогичного (но более глубокого) обсуждения
операций обновления в разделе 9.4.
Во-вторых, становится очевидным, что овеществление представляет собой со-
вершенно законный способ реализации представлений, по крайней мере в слу-
чае операций выборки (хотя, возможно, довольно неэффективный). Однако этот
способ, конечно же, не может быть использован при операции обновления, по-
скольку смысл обновления представления заключается в применении указанной
операции обновления именно к лежащим в основе представления базовым пе-
ременным-отношениям, а не просто к некоторой материализованной копии их
данных (раздел 9.4).
В-третьих, хотя, в принципе, процедура выполнения подстановки определений
представления вполне понятна и теоретически отлично работает в ста процентах
случаев, весьма огорчает тот факт, что в некоторых программных SQL-продуктах
(на время написания книги) этот процесс не реализован. Иначе говоря, в подобных
продуктах выборка данных из представлений может совершенно неожиданно за-
вершиться ошибкой. Процедура подстановки не реализована в версиях стандарта
SQL, выпущенных до 1992 года. Причиной, по которой в приложениях и стандар-
тах языка SQL не работают операции выборки из представлений, является непол-
ная поддержка ими свойства реляционной замкнутости (см. упр. 9.14).
9.4. Обновление данных в представлениях
Проблема обновления данных в представлениях может быть сформулирована сле-
дующим образом. Пусть дана определенная операция обновления в заданном представ-
лении. Какие обновления и в какие исходные базовые переменные-отношения нужно
внести, чтобы реализовать исходное обновление представления? Формальное описание
358
Часть II. Реляционная модель
проблемы выглядит так. Пусть D — это база данных, а V — представление, определенное
на D (т.е. представление, определение которого является функцией X на множестве D).
Тогда, как известно из раздела 9.3, получаем следующее.
V = X ( D )
Теперь пусть U — это операция обновления в представлении V. Так как U можно счи-
тать операцией, результат выполнения которой состоит в изменении ее аргументов, пра-
вомочно представить ее в следующем виде.
U ( V ) = U ( X ( D ) )
Тогда проблема выполнения обновления в представлении сводится к поиску такой
операции обновления U' на множестве D, для которой истинно следующее выражение.
U(X(D))=X(U'(D))
Операция подобного вида требуется по той причине, что реально существует только
множество D (представления по определению виртуальны) и выполнять операции обнов-
ления непосредственно в представлениях как таковых невозможно.
Прежде чем продолжить изложение, хотелось бы подчеркнуть, что на протяжении не-
скольких последних лет проблема обновления представлений была предметом ряда важ-
ных исследований, в результате проведения которых было разработано множество раз-
личных подходов к решению этой проблемы (в том числе и автором этой книги). Под-
робные сведения об этих исследованиях можно найти, например, в [9.7], [9.10]—[9.13],
[9.15], [17.13] В частности, предложения Кодда (Codd) для системы RM/V2 описываются
в [5.2]. В этой главе изложен относительно новый подход [9.9], менее произвольный по
сравнению с существовавшими ранее подходами, но обладающий преимуществом со-
вместимости с лучшими аспектами этих подходов. Кроме того, новый подход позволяет
считать обновляемым гораздо более широкий класс представлений по сравнению с
прежними подходами. При этом подходе фактически все представления считаются по-
тенциально обновляемыми — за исключением лишь тех, которые нарушают установлен-
ные ограничения целостности.
Еще раз о “золотом правиле”
Напомним золотое правило, определенное в предыдущей главе.
Любым операциям изменения запрещается когда-либо переводить переменную-
отношение в состояние, которое противоречит ее собственному предикату.
При определении этого правила подчеркивалось, что оно применимо ко всем перемен-
ным-отношениям, как к базовым, так и к производным. Иначе говоря, производные пере-
менные-отношения также имеют предикаты, как и должно быть согласно принципу взаимо-
заменяемости. Эти предикаты должны быть известны системе, что позволит ей правильно
выполнять обновления представлений. Что же собой представляет предикат представле-
ния? Очевидно, что, прежде всего, нам необходим набор правил вывода предиката, та-
кой, что если известен предикат (предикаты) на входе (входах) любой реляционной опера-
ции, то с его помощью можно определить предикат на выходе этой операции. Если такой
набор правил будет получен, то мы сможем вывести предикат представления из предиката
базовой переменной-отношения (или переменных-отношений), в терминах которой прямо
или косвенно это представление было определено. (Безусловно, предикаты для всех базо-
Глава 9. Представления
359
вых переменных-отношений можно считать известными: они представляют собой логиче-
ское произведение всех ограничений переменной-отношения, т.е. ограничений потенци-
альных ключей, определенных для данной базовой переменной-отношения.)
На самом деле определить требуемый набор правил очень легко — они следуют не-
посредственно из определений реляционных операторов. Например, если А и В — две
произвольные переменные-отношения некоторого типа и их предикаты есть РА и РВ со-
ответственно, а представление С определено как A INTERSECT В, то очевидно, что преди-
кат PC этого представления будет определяться выражением (РА) AND (РВ). Другими
словами, некоторый кортеж будет появляться в представлении С тогда и только тогда,
когда при его подстановке оба предиката, РА и РВ, принимают значение истина. О дру-
гих реляционных операторах речь пойдет ниже в этом же разделе.
Замечание. Таким образом, производные переменные-отношения автоматически
“наследуют” определенные ограничения от тех переменных-отношений, на основе которых
они определены. Однако вполне возможно, что некоторая производная переменная-
отношение станет объектом определенных дополнительных ограничений, накладываемых
помимо и поверх наследуемых ограничений. Поэтому для производных переменных-
отношений желательно иметь возможность устанавливать требуемые ограничения явно
(например, это может быть возможность определения для представления потенциального
ключа). Язык Tutorial D действительно поддерживает такую возможность. Однако для
простоты изложения в дальнейшем мы эту возможность чаще всего будем игнорировать.
Механизм обновления представления
Существует несколько важных принципов, которые должны соблюдаться любым сис-
тематическим подходом к проблеме обновления представлений. (Золотое правило, без-
условно, важнейшее из них, но не единственное.) Перечислим эти принципы.
1. Обновляемость представления — понятие семантическое, а не синтаксическое. Дру-
гими словами, оно не зависит от выбранной формы записи определения представле-
ния. Например, два приведенных ниже представления семантически идентичны.
VAR V VIEW
S WHERE STATUS > 25 OR CITY = 'Paris' ;
VAR V VIEW
( S WHERE STATUS > 25 ) UNION ( S WHERE CITY = 'Paris' ) ;
Очевидно, что оба эти представления должны быть или обновляемыми, или не об-
новляемыми (на самом деле они, безусловно, должны быть обновляемыми). Одна-
ко этому утверждению противоречат и стандарт SQL, и большинство существую-
щих на данный момент SQL-продуктов, которые совершенно безосновательно по-
лагают, что первое из приведенных представлений обновляемо, а второе — нет
(подробности приводятся в разделе 9.6).
2. Как следует из предыдущего рассуждения, механизм обновления должен корректно
работать и в тех частных случаях, когда “представление” на самом деле является
базовой переменной-отношением, поскольку любая базовая переменная-отношение
В семантически неотличима от представления V, определенного как операция
В UNION В или В INTERSECT В, или В WHERE true, или любое другое выражение,
равносильное переменной-отношению В. Таким образом, правила обновления, ус-
360
Часть II. Реляционная модель
тановленные, например, для представления, которое определено с помощью опера-
ции объединения V = В UNION В, должны давать тот же результат, что и в случае,
когда рассматриваемая операция обновления применяется непосредственно к базо-
вой переменной-отношению В. Иначе говоря, хотя тема данного раздела и звучит
как “обновление представлений”, на самом деле в общем случае здесь рассматри-
вается обновление переменных-отношений. Мы рассмотрим теорию обновления,
применимую ко всем переменным-отношениям, а не только к представлениям.
3. Применяемые правила должны сохранять симметричность во всех случаях, когда
она применима. Например, правило удаления DELETE для представления, опреде-
ленного как пересечение V = A INTERSECT В, не должно допускать произвольного
удаления кортежа из переменной-отношения А или В даже тогда, когда такое одно-
стороннее удаление кортежа наверняка вызовет удаление этого кортежа из рас-
сматриваемого представления. В подобном случае кортеж должен удаляться из
обеих переменных-отношений А и В. (Другими словами, не должно быть никакой
неоднозначности. Всегда должен существовать единственный способ реализации
данного обновления, который срабатывает во всех случаях. В частности, не должно
быть никаких логических различий между представлениями, определенными как
A INTERSECT В и В INTERSECT А.)
4. В правилах обновления должны учитываться любые применимые триггерные про-
цедуры, включая, в частности, определенные ссылочные действия, подобные
“каскадному” удалению (устанавливаемому с помощью опции CASCADE).
5. Для упрощения синтаксиса желательно рассматривать операцию UPDATE как со-
кращенную запись последовательности операций удаления и вставки (DELETE-
INSERT); именно так мы и будем ее рассматривать. Это сокращение вполне прием-
лемо при соблюдении следующих условий.
Не осуществляется никаких проверок предикатов переменных-отношений в ходе
выполнения любого требуемого обновления. Имеется в виду, что расширенная
запись операции UPDATE выглядит как DELETE-INSERT-проверха, а не как DELETE-
npoBepxa-INSERT-проверка. Суть заключается в том, что операция DELETE вре-
менно нарушает истинность предиката переменной-отношения, в то время как
полная операция UPDATE ее не нарушает. Например, предположим, что перемен-
ная-отношение R содержит ровно 10 кортежей, и рассмотрим действие операции
UPDATE ее некоторого кортежа t при условии, что предикат этой переменной-
отношения R устанавливает, что в ней не может содержаться менее 10 кортежей.
Триггерные процедуры также никогда не должны вызываться в середине вы-
полнения любой операции обновления. (Фактически триггерные процедуры
обычно выполняются сразу же по окончании операции, но до проверки преди-
ката отношения.)
Сокращенная запись требует некоторых незначительных уточнений для пред-
ставлений, определяемых на основе операции проекции (подробности приводят-
ся ниже в этом разделе).
6. Все обновления данных в представлениях должны быть реализованы как обновления
того же типа в исходных переменных-отношениях. Иначе говоря, операции вставки
(INSERT) отображаются в операции вставки, операции удаления (DELETE) отобража-
Глава 9. Представления
361
ются в операции удаления (как было сказано выше, операции обновления (UPDATE)
можно игнорировать). Предположим противное, т.е. что существует некоторый тип
представлений (скажем, представлений, определяемых на основе операции объедине-
ния), для которых операции INSERT отображаются в операции DELETE в исходных пе-
ременных-отношениях. Но тогда операции INSERT для базовых переменных-
отношений также должны в каких-то случаях отображаться в операции DELETE! Этот
вывод непосредственно следует из утверждения (как мы уже убедились в ходе рассу-
ждений в п. 2), что любую базовую переменную-отношение В можно представить в
виде семантически идентичного представления V = В UNION В. Аналогичное рассуж-
дение можно применить и для представлений остальных типов (представлений на
основе операций выборки, проекции, пересечения и т.д.). Однако утверждение, что
в базовых переменных-отношениях операции вставки данных могут в действитель-
ности представляться операциями удаления, — очевидный абсурд. Таким образом,
утверждение, что операции INSERT и DELETE в представлениях отображаются в со-
ответствующие операции INSERT и DELETE в базовых переменных-отношениях, яв-
ляется истинным.
7. В общем случае правила обновления при их применении к заданному представле-
нию V определяют операции, которые должны быть применены к переменным-
отношениям, на которых определено данное представление V. Эти правила должны
правильно срабатывать даже в том случае, когда те переменные-отношения, на ос-
нове которых определено данное представление, в свою очередь, также являются
представлениями. Другим словами, правила должны допускать возможность рекур-
сивного применения. Конечно, если попытка обновить исходную переменную-
отношение по каким-то причинам завершится неудачно, то и исходная операция
обновления не будет выполнена. Другими словами, обновления в представлениях
выполняются по принципу “все или ничего”, точно так, как и в случае базовых пе-
ременных-отношений.
8. Правила не должны основываться на предположении, что база данных хорошо
спроектирована, т.е. полностью нормализована (подробности приводятся в гла-
вах И и 12). Тем не менее выполнение установленных правил может привести к
несколько неожиданным результатам, если база данных спроектирована неудачно.
Это еще раз свидетельствует в пользу необходимости создания добротных проек-
тов базы данных. В следующем разделе будет приведен подобный пример с не-
сколько неожиданными результатами.
9. Не должно существовать никаких веских причин, чтобы в любом заданном пред-
ставлении одни операции обновления разрешались, а другие — нет (например, раз-
решена операция DELETE, но запрещена операция INSERT).
10. Операции INSERT и DELETE должны быть, насколько это возможно, обратными по
отношению одна к другой.
Необходимо сделать одно важное напоминание. Как было показано в главе 5, реляци-
онные операции, в частности реляционные обновления, всегда выполняются на уровне
множеств, а множество, состоящее из одного кортежа, просто является одним из частных
случаев. Более того, иногда необходимо выполнить обновление сразу многих кортежей
(например, если операцию обновления нельзя воспроизвести с помощью серии обновле-
362
Часть II. Реляционная модель
ний отдельных кортежей). Это утверждение в общем случае верно как для базовых пере-
менных-отношений, так и для представлений. Для простоты изложения большую часть
обсуждаемых правил обновления представлений мы будем формулировать в терминах
операций обновления отдельных кортежей; тем не менее читатель не должен забывать о
том, что подобный подход — это всего лишь дань простоте изложения, в некоторых слу-
чаях даже чрезмерная.
Далее мы по очереди рассмотрим отдельные операции реляционной алгебры
(объединение, пересечение и вычитание), а затем — все остальные операции.
Замечание. В первых трех случаях, в частности, подразумевается, что речь идет о пред-
ставлении, определяющее выражение которого имеет соответственно одну из следующих
трех форм: A UNION В, A INTERSECT В и A MINUS В, где А и В, в свою очередь, являются не-
которыми реляционными выражениями (т.е. необязательно представляют базовые пере-
менные-отношения). Переменные-отношения А и В должны иметь один и тот же реляцион-
ный тип. Соответствующие предикаты данных переменных-отношений — это РА и РВ.
Операция объединения
Приведем правило вставки для представления вида A UNION В.
Правило INSERT. Вновь добавляемый кортеж должен удовлетворять либо пре-
дикату РА, либо предикату РВ, либо обоим предикатам одновременно. Если новый
кортеж удовлетворяет предикату РА, то этот кортеж должен быть вставлен в пере-
менную-отношение А (заметим, что операция вставки может иметь побочный эф-
фект, в результате которого новый кортеж будет вставлен и в переменную-
отношение В4). Если новый кортеж удовлетворяет предикату РВ, то он вставляется
и в переменную-отношение В, но лишь в том случае, если он еще не вставлен в эту
переменную-отношение в результате побочного эффекта от вставки кортежа в пе-
ременную-отношение А.
Замечание. Конкретное определение выполняемой процедуры, использованное при
формулировке правила (вставить сначала в переменную-отношение А, а затем — в пере-
менную-отношение В), следует воспринимать только как педагогический прием. Не нужно
полагать, что СУБД должна будет выполнять операцию вставки именно в той последова-
тельности, которая указана в определении правила. На самом деле это замечание следует из
принципа симметрии (принцип 3 из предыдущего подраздела), поскольку при вставке кор-
тежа ни одна из переменных-отношений А или В не имеет преимуществ перед другой. Ана-
логичные соображения относятся ко всем правилам, рассматриваемым в этом разделе.
Пояснение. Новый кортеж должен удовлетворять по крайней мере одному из преди-
катов РА или РВ, так как в противном случае данный кортеж не будет включен в объеди-
нение A UNION В, поскольку он не будет удовлетворять предикату производной перемен-
4 В нескольких обсуждаемых ниже правилах и примерах отмечается возможность возникно-
вения побочных эффектов. Конечно, всем известно, что побочные эффекты обычно нежела-
тельны. Однако проблема заключается в том, что некоторых побочных эффектов нельзя избе-
жать, если переменные-отношения А и В являются пересекающимися подмножествами корте-
жей одной и той же базовой переменной-отношения. Подобная ситуация часто встречается в
представлениях, определенных с помощью операций объединения, пересечения или вычитания. В
этом конкретном случае упомянутые побочные эффекты как раз желательны, а не наоборот.
Глава 9. Представления
363
ной-отношения для объединения A UNION В, а именно — (РА) OR (РВ). (Кроме того, мы
предполагаем, хотя такое предположение и не строго обязательно, что новый кортеж не
должен в данный момент присутствовать ни в переменной-отношении А, ни в перемен-
ной-отношении В, так как в противном случае это означало бы попытку вставить уже
существующий кортеж.) Если предположить, что перечисленные условия удовлетворя-
ются, то новый кортеж будет вставлен в переменную-отношение А или переменную-
отношение В в зависимости от того, к какой из них этот кортеж логически принадлежит
(возможно, к обеим).
Примеры. Пусть представление UV определено следующим образом.
VAR UV VIEW
( S WHERE STATUS > 25 ) UNION ( S WHERE CITY = 'Paris' ) ;
На рис. 9.2 приведены возможные значения в этом представлении для нашего приме-
ра базы данных.
S# SNAME STATUS CITY
S2 Jones 10 Paris
S3 Blake 30 Paris
S5 Adams 30 Athens
Рис. 9.2. Представление UV (пример значений)
Пусть кортеж, который необходимо вставить в представление UV, имеет вид
('S6', 'Smith', 50, 'Rome')5. Этот кортеж удовлетворяет предикату S WHERE
STATUS > 25, но не удовлетворяет предикату S WHERE CITY = 'Paris'. Следова-
тельно, новый кортеж вставляется в переменную-отношение, удовлетворяющую
предикату S WHERE STATUS > 25. В соответствии с правилами вставки кортежей в
представление на основе выборки (которые вполне очевидны; см. ниже) новый
кортеж будет вставлен в базовую переменную-отношение поставщиков, и по этой
причине он также появится в представлении, что и ожидалось.
Теперь предположим, что в представление UV требуется вставить кортеж вида
('S7', 'Jones', 50, 'Paris'). Этот кортеж удовлетворяет одновременно двум
предикатам— S WHERE STATUS > 25 и S WHERE CITY = 'Paris'. Логично пред-
положить, что он будет вставлен в обе переменные-отношения, удовлетворяющие
каждому из этих предикатов. Тем не менее следует заметить, что вставка кортежа в
одну из переменных-отношений будет иметь побочный эффект, вследствие кото-
рого кортеж окажется автоматически вставленным и в другую переменную-
отношение. Таким образом, вторую операцию вставки явно выполнять не нужно.
Рассмотрим две различные базовые переменные-отношения, SA и SB. Переменная-
отношение SA содержит информацию о поставщиках, для которых значение атрибута
STATUS превышает 25. а в переменной-отношении SB содержатся сведения о поставщиках
из Парижа (рис. 9.3). Предположим, что представление UV определено как объединение
5 Подобное упрощенное обозначение для кортежей переменной-отношения В используется в
этом разделе из соображений наглядности
364
Часть II. Реляционная модель
SA UNION SB, и вновь рассмотрим операцию вставки двух уже упомянутых выше корте-
жей. Вставка кортежа ('S6', 'Smith', 50, 'Rome') в представление UV приведет к
вставке кортежа в базовую переменную-отношение SA, что, по-видимому, и требуется.
Однако вставка кортежа ('S7', 'Jones', 50, 'Paris') в представление UV приведет к
вставке кортежа в обе переменные-отношения SA и SB! Полученный результат логически
корректен, хотя интуитивно и не совсем понятен (именно этот результат в предыдущем
подразделе был назван “несколько неожиданным”). В моем понимании подобные
"неожиданности” могут иметь место исключительно как следствие плохо спроекти-
рованной структуры базы данных. В частности, на наш взгляд, если проект базы данных
позволяет одним и тем же кортежам появляться (т.е. удовлетворять их предикатам) в
разных базовых переменных-отношениях, это, определенно, плохой проект. Такая пози-
ция (возможно, спорная) детально рассматривается в разделе 12.6 главы 12.
SA SB
S# SNAME STATUS CITY S# SNAME STATUS CITY
S3 Blake 30 Paris S2 Jones 10 Paris
S5 Adams 30 Athens S3 Blake 30 Paris
Рис. 9.3. Базовые переменные-отношения SA и SB (пример значений атрибутов)
Теперь сосредоточимся на правилах удаления кортежей из представлений типа A UNION В.
Правило DELETE. Если удаляемый кортеж принадлежит переменной-отно-
шению А, то он удаляется из нее (заметьте, что данное удаление может иметь по-
бочный эффект, вследствие которого этот же кортеж будет удален и из перемен-
ной-отношения В). Если после удаления кортежа из переменной-отношения А этот
кортеж все еще остается в переменной-отношении В, то он будет удален и из пе-
ременной-отношения В.
В качестве упражнения придумайте примеры, иллюстрирующие данное правило.
Следует заметить, что удаление кортежа из переменной-отношения А или В может при-
вести к “каскадному” удалению или к запуску триггерных процедур.
И наконец, рассмотрим правило операции обновления.
Правило UPDATE. Обновляемый кортеж должен быть таким, чтобы его обновлен-
ная версия удовлетворяла либо предикату РА, либо предикату РВ, либо обоим этим
предикатам одновременно. Если кортеж принадлежит переменной-отношению А, то
его удаляют из нее без запуска каких-либо триггерных процедур (каскадное удале-
ние и т.п.), запускаемых при обычной операции удаления. Кроме того, проверка
удовлетворения предиката переменной-отношения А не выполняется. Следует заме-
тить, что эта операция удаления может иметь побочный эффект, вследствие которо-
го выбранный кортеж будет удален и из переменной-отношения В. Если после уда-
ления из переменной-отношения А обновляемый кортеж все еще сохраняется в пе-
ременной-отношении В, то он удаляется из этой переменной-отношения (опять же,
без проверки ее предиката и запуска каких-либо триггерных процедур). Далее, если
обновленная версия кортежа удовлетворяет предикату РА, кортеж вставляется в пе-
ременную-отношение А (эта операция может иметь побочный эффект, вследствие
Глава 9. Представления
365
которого новая версия данного кортежа может появиться и в переменной-
отношении В). И наконец, если обновленная версия кортежа удовлетворяет предика-
ту РВ, то кортеж вставляется в переменную-отношение В, но только в том случае, ес-
ли он не был вставлен в данную переменную-отношение в результате побочного эф-
фекта от вставки обновленного кортежа в переменную-отношение А.
Приведенное выше правило обновления, по сути, состоит из правила удаления, за ко-
торым следует правило вставки, за исключением того, что, как указывалось и ранее, по-
сле удаления старой версии кортежа не выполняются проверка предикатов и запуск триг-
герных процедур (все триггерные процедуры, связанные с операцией обновления, кон-
цептуально выполняются после завершения всех операций удаления и вставки, непо-
средственно перед проверкой предикатов).
Необходимо отметить одно важное следствие такого рода трактовки операции обновле-
ния, которое состоит в том, что после выполнения операции обновления представления из-
мененный кортеж может мигрировать из одной переменной-отношения в другую. В базе
данных, показанной на рис. 9.3, обновление кортежа ('S5', 'Adams', 30, 'Athens') в
представлении UV в виде ('S5', 'Adams', 15, 'Paris') приведет к удалению старого
кортежа из переменной-отношения SA и его вставке в переменную-отношение SB.
Операция пересечения
Приведем правила обновления представлений вида A INTERSECT В. Причем в данном
случае ограничимся формулированием правил без каких-либо дополнительных поясне-
ний (они аналогичны пояснениям для правил обновления объединений). Единственное, о
чем следует сказать, — это то, что для представлений вида A INTERSECT В предикат при-
нимает вид (РА) AND (РВ). Примеры для приведенных ниже правил предлагаем читате-
лю привести самостоятельно в качестве упражнения.
Правило INSERT. Новый кортеж должен удовлетворять предикатам РА и РВ
одновременно. Если новый кортеж на текущий момент отсутствует в перемен-
ной-отношении А, то он будет вставлен в эту переменную-отношение (заметьте,
что операция вставки может иметь побочный эффект, вследствие которого но-
вый кортеж появится и в переменной-отношении В). Если новый кортеж все
еще отсутствует в переменной-отношении В, то он будет вставлен в эту пере-
менную-отношение.
Правило DELETE. Удаляемый из представления кортеж удаляется из перемен-
ной-отношения А (заметьте, что эта операция удаления может иметь побочный
эффект, в результате которого удаляемый кортеж исчезнет и из переменной-
отношения В). Если удаляемый кортеж все еще присутствует в переменной-
отношении В, то он будет удален и из этой переменной-отношения.
Правило UPDATE. Обновляемый кортеж должен быть таким, чтобы его обнов-
ленная версия удовлетворяла одновременно обоим предикатам РА и РВ. Кортеж
удаляется из переменной-отношения А без запуска триггерных процедур и про-
верки предиката этой переменной-отношения (заметим, что данная операция мо-
жет иметь побочный эффект, вследствие которого кортеж будет удален и из пере-
менной-отношения В). Если до этого момента обновляемый кортеж все еще не
был удален из переменной-отношения В, то он будет удален из нее, опять же, без
366
Часть II. Реляционная модель
запуска триггерных процедур и проверки предиката. Далее, если обновленная вер-
сия кортежа в данный момент в переменной-отношении А отсутствует, то изме-
ненный кортеж будет вставлен в переменную-отношение А (заметьте, что опера-
ция вставки также может иметь побочный эффект, вследствие которого новый
кортеж автоматически появится и в переменной-отношении В). Если измененный
кортеж все еще отсутствует в переменной-отношении В, то он будет вставлен и в
эту переменную-отношение.
Операция вычитания
Ниже приведены правила обновления представлений вида A MINUS В (для представлений
данного вида предикат переменной-отношения можно записать так: (РА) AND NOT (РВ)).
Правило INSERT. Новый кортеж должен удовлетворять предикату РА и не дол-
жен удовлетворять предикату РВ. Новый кортеж вставляется в переменную-
отношение А.
Правило DELETE. Удаляемый из представления кортеж удаляется и из перемен-
ной-отношения А.
Правило UPDATE. Обновляемый кортеж должен быть таким, чтобы его обнов-
ленная версия удовлетворяла предикату РА и не удовлетворяла предикату РВ.
Кортеж удаляется из переменной-отношения А без выполнения триггерных про-
цедур и проверки предиката. Затем обновленная версия кортежа вставляется в пе-
ременную-отношение А.
Операция выборки
Допустим, что выражение определения представления V можно задать в следующем
виде: A WHERE р. И пусть РА будет предикатом переменной-отношения А. Тогда предикат
представления V примет следующий вид: (РА) AND (р). Например, предикат для опера-
ции выборки S WHERE CITY = 'London' будет иметь вид (PS) AND (CITY = 'London'),
где PS является предикатом переменной-отношения поставщиков. Приведем правила об-
новления для представлений вида A WHERE р.
Операция INSERT. Новый кортеж должен удовлетворять предикату РА и усло-
вию р. Новый кортеж вставляется в переменную-отношение А.
Операция DELETE. Удаляемый кортеж удаляется из переменной-отношения А.
Операция UPDATE. Обновляемый кортеж должен быть таким, чтобы его об-
новленная версия удовлетворяла предикату РА и условию р. Кортеж удаляется
из переменной-отношения А без запуска каких-либо триггерных процедур и
проверки предиката. Затем в переменную-отношение А вставляется обновлен-
ная версия кортежа.
Примеры. Пусть представление LS определено следующим образом.
VAR LS
S WHERE CITY = 'London' ;
На рис. 9.4 приведен пример значений для этого представления.
Глава 9. Представления
367
S# SNAME STATUS CITY
S1 Smith 20 London
S4 Clark 20 London
Рис 9.4. Представление LS (пример значений)
Попытка вставить в представление LS кортеж вида ('S6', 'Green', 20,
'London') будет завершена успешно. Новый кортеж будет вставлен в перемен-
ную-отношение S и, следовательно, появится также в представлении LS.
Попытка вставить в представление LS кортеж вида ('SI', 'Green', 20,
'London') будет воспринята, как ошибка, поскольку этот кортеж не удовлетворяет
предикату переменной-отношения S (и, следовательно, представления LS). Причи-
на ошибки в том, что этот кортеж нарушает требование уникальности потенци-
ального ключа {S#}.
Попытка вставить в представление LS кортеж вида ('S6', 'Green', 20,
'Athens') завершится неудачно, поскольку этот кортеж нарушает условие CITY =
'London'.
Попытка удалить из представления LS кортеж ('SI', 'Smith', 20, 'London')
завершится успешно. Кортеж будет удален из переменной-отношения S и, следо-
вательно, из представления LS.
Попытка обновить в представлении LS кортеж ('SI', 'Smith', 20, 'London') к
виду ('S6', 'Green', 20, 'London') завершится успешно. Попытка обновить
тот же кортеж ('SI', 'Smith', 20, 'London') к виду ('S2', 'Smith', 20,
'London') или к виду ('SI', 'Smith', 20, 'Athens') будет неудачной (в каж-
дом конкретном случае объясните, почему).
Операция проекции
Этот раздел также начинается с рассмотрения соответствующего предиката.
Пусть атрибуты переменной-отношения А (с предикатом РА) разделены на две несвя-
занные группы, например X и Y . Полагая, что X и Y представляют собой составные
атрибуты, рассмотрим проекцию А{Х} переменной-отношения А по атрибуту X.
Пусть {X: х} будет кортежем этой проекции. Тогда, очевидно, предикатом для этой
проекции будет следующий предикат: “Существует такое значение у из домена зна-
чений атрибута Y, что кортеж {Х:х, Y:y} удовлетворяет предикату РА”. Например,
рассмотрим проекцию переменной-отношения S по атрибутам S#, SNAME и CITY. Для
каждого кортежа (s, п, с), который входит в данную проекцию, существует значе-
ние статуса t, такое, что кортеж (s, n, t, с) удовлетворяет предикату перемен-
ной-отношения S.
Ниже приведены правила обновления проекции А{Х}.
Правило INSERT. Пусть (х) — кортеж, который нужно вставить, и пусть у —
значение по умолчанию, выбираемое из области значений атрибута Y (будет
ошибкой, если такого значения по умолчанию не существует, т.е. для атрибута Y
368
Часть II. Реляционная модель
применяется правило “значения по умолчанию запрещены”)6- Кортеж (х, у), кото-
рый должен удовлетворять предикату РА, будет вставлен в переменную-отно-
шение А.
Замечание. Так как для потенциальных ключей обычно (но не всегда) применяет-
ся правило “значения по умолчанию запрещены” (глава 18), представление, которое
содержит не все потенциальные ключи исходной переменной-отношения, обычно
не допускает выполнения операций вставки.
Правило DELETE. Из переменной-отношения А будут удалены все кортежи, у
которых значение атрибута X совпадает со значением кортежа, удаляемого из
представления А{Х}.
Замечание. На практике желательно, чтобы множество атрибутов X включало хотя
бы один потенциальный ключ, тогда удаляемому из проекции А{Х} кортежу будет
соответствовать единственный кортеж а в переменной-отношении А. Тем не менее
нет никаких логических причин превращать это пожелание в жесткое требование.
Аналогичное замечание относится и к операции UPDATE (см. ниже).
Правило UPDATE. Пусть (х) — это кортеж, который необходимо обновить, а
(х') — это обновленная версия кортежа (х). Пусть а — это кортеж переменной-
отношения А, имеющий те же значения атрибутов х, что и кортеж X. И пусть
значения атрибутов множества Y в кортеже а будут иметь значения у. Сначала
из переменной-отношения А будут удалены все кортежи а, отвечающие указан-
ным выше требованиям, причем без выполнения триггерных процедур и про-
верки предиката отношения. После этого для каждого определенного выше зна-
чения у в переменную-отношение А будет вставлен кортеж (х', у), если он удов-
летворяет предикату РА.
Замечание. В этом определении присутствуют те “незначительные уточнения”
применительно к операции проекции, которые упоминались в принципе 5 обнов-
ления в разделе “Механизм обновления представления”. Обратите внимание, что
на последнем этапе правила для операции UPDATE (этапе вставки) в каждом встав-
ляемом кортеже восстанавливается предыдущее значение атрибутов Y вместо
обычной замены значениями, используемыми по умолчанию, как это имеет место
при выполнении самостоятельных операций INSERT.
Примеры. Пусть представление SC определено с помощью следующего выражения.
SC { S#, CITY }
На рис. 9.5 показан пример содержимого этого представления.
6 Как следует из этого высказывания, здесь мы подразумеваем, что имеются какие-то сред-
ства (как в языке SQL), позволяющие устанавливать значения по умолчанию для атрибутов ба-
зовых переменных отношений. Соответствующий синтаксис языка Tutorial D может иметь вид
нового предложения в определении базовой переменной отношения, например DEFAULT (<список
определений значений по умолчанию> ), где каждый элемент списка в параметре <список опреде-
лений значений по умолчанию> имеет вид <имя атрибута> <значение по умолчанию>. Например,
в определении переменной-отношения поставщиков S может быть добавлено предложение
DEFAULT (STATUS 0f CITY '').
Глава 9. Представления
369
S# CITY
S1 London
S2 Paris
S3 Paris
S4 London
S5 Athens
Рис. 9.5. Представление SC (значения для примера)
Попытка вставить в представление SC кортеж ('S6', 'Athens') будет успешной.
В результате этой операции в переменную-отношение S будет вставлен кортеж
('S6', п, t, 'Athens'), где п и t являются значениями, которые используются
по умолчанию для атрибутов SNAME и STATUS соответственно.
Попытка вставить в представление SC кортеж ('SI', 'Athens') приведет к ошиб-
ке, так как этот кортеж не удовлетворяет предикату переменной-отношения S (а
значит, и представления SC). В частности, вставка этого кортежа нарушает прави-
ло уникальности потенциального ключа {S#}.
Попытка удалить из представления SC кортеж ('SI', 'London') будет успешной.
Кортеж поставщика с номером 'S1' будет удален из переменной-отношения S.
Попытка обновить кортеж ('SI', 'London') представления SC к виду ('S1',
'Athens') будет успешной. Это повлечет замену в переменной-отношении S кор-
тежа ('SI', 'Smith', 20, 'London') кортежем ('SI', 'Smith', 20,
'Athens'), но не кортежем ('SI', п, t, 'Athens'), где п и t— значения по
умолчанию. Обязательно обратите на это внимание.
Попытка обновить в представлении SC тот же кортеж ('SI', 'London') к виду
(' S2', 'London') приведет к ошибке (укажите конкретную причину).
Случай, когда проекция не включает потенциальных ключей исходной переменной-
отношения (например, проекция переменной-отношения S по атрибутам STATUS и CITY),
оставлен в качестве упражнения для читателей.
Операция расширения
Пусть представление V создано с помощью следующего определяющего выражения.
EXTEND A ADD ехр AS X
(Как обычно, предикатом переменной-отношения А будет РА.) Тогда предикат РЕ
представления V будет иметь такой вид.
РА ( a ) AND е.Х = ехр ( a )
Здесь е — это кортеж представления V, а а — кортеж, который остается, когда добав-
ленный с помощью операции расширения компонент X удаляется (т.е. проще говоря, а —
это проекция кортежа е по всем атрибутам переменной-отношения А). На обычном языке
это можно сформулировать следующим образом.
370
Часть II. Реляционная модель
Каждый кортеж е в результирующем отношении операции расширения имеет сле-
дующие свойства: 1) кортеж а, получаемый из кортежа е посредством операции
проекции, исключающей компонент X, удовлетворяет предикату РА; 2) значение
компонента Xравно результату вычисления выражения ехр для кортежа а.
Приведем правила обновления для представлений, определяемых с помощью опера-
ции расширения.
Правило INSERT. Пусть е — это кортеж, который нужно вставить. Он должен
удовлетворять предикату РЕ. В переменную-отношение А будет вставлен кортеж
а, порожденный из кортежа е посредством операции проекции, исключающей
компонент X.
Правило DELETE. Пусть е — это кортеж, который нужно удалить. Из перемен-
ной-отношения А будет удален кортеж а, порожденный из кортежа е посредством
операции проекции, исключающей компонент X.
Правило UPDATE. Пусть е — это кортеж, который нужно обновить, а е' — обнов-
ленная версия кортежа е, причем кортеж е' должен удовлетворять предикату РЕ.
Сначала из переменной-отношения А без выполнения триггерных процедур и про-
верки предиката этой переменной-отношения будет удален кортеж а, который поро-
жден из кортежа е посредством операции проекции, исключающей компонент X. За-
тем в переменную-отношение А будет вставлен кортеж а', который порожден из
кортежа е' посредством операции проекции, исключающей компонент X.
Примеры. Пусть представление VPX определено с помощью следующего выражения.
EXTEND Р ADD ( WEIGHT * 454 ) AS GMWT
На рис. 9.6 приведен пример возможных значений этого представления.
P# PNAME COLOR WEIGHT CITY GMWT
Р1 Nut Red 12.0 London 5448.0
Р2 Bolt Green 17.0 Paris 7718.0
РЗ Screw Blue 17.0 Rome 7718.0
Р4 Screw Red 14.0 London 6356.0
Р5 Cam Blue 12.0 Paris 5448.0
Р6 Cog Red 19.0 London 8626.0
Рис. 9.6. Представление VPX (значения для примера)
Попытка вставить кортеж ('Р7', 'Cog', 'Red', 12, 'Paris', 5448) будет за-
вершена успешно и приведет к вставке кортежа ('Р7', 'Cog', 'Red', 12,
'Paris') в переменную-отношение Р.
Попытка вставить кортеж ('Р7', 'Cog', 'Red', 12, 'Paris', 5449 ) потерпит
неудачу (почему?).
Попытка вставить кортеж ('Pl', 'Cog', 'Red', 12, 'Paris', 5448) потерпит
неудачу (почему?).
Попытка удалить кортеж с ключом 'Р1' будет успешной и приведет к удалению
кортежа с ключом 'Р1' из переменной-отношения Р.
Глава 9. Представления
371
Попытка обновить кортеж с ключом'Pl'к виду ('Pl', 'Nut', 'Red', 10, 'Paris',
4540) будет успешной и приведет к замене кортежа ('Pl', 'Nut', 'Red', 12,
'London') в переменной-отношении Р кортежем ('Pl', 'Nut', 'Red', 10,
'Paris').
Закончится неудачей попытка обновить тот же кортеж посредством замены
номера детали номером 'Р2' (без изменения остальных атрибутов) или по-
пытка его приведения к виду, в котором значение атрибута GMWT не будет рав-
но значению атрибута WEIGHT, умноженному на 454 (в каждом случае укажите
причину неудачи).
Операция соединения
В большинстве предлагавшихся ранее трактовок проблемы обновления представле-
ний (включая трактовки, изложенные в предыдущих редакциях этой книги и в других
книгах автора) утверждалось, что для результата операции соединения возможность (или
невозможность) его обновления зависит (по крайней мере, частично) от того, принадле-
жит ли соединение к типу “один к одному”, “один ко многим” или “многие ко многим”.
В отличие от всех предыдущих трактовок проблемы обновления подобных представле-
ний здесь автор утверждает, что результат операции соединения обновляем всегда. Более
того, для всех трех перечисленных типов соединений правила идентичны и, в целом,
вполне очевидны. Правдоподобность этого утверждения, на первый взгляд кажущегося
удивительной, подкрепляется новым видением проблемы, ставшим возможным благода-
ря принятию золотого правила, что мы и постараемся сейчас пояснить.
В общем случае назначение функции поддержки представлений всегда состояло в
стремлении стереть, насколько это возможно, разницу между представлениями и базо-
выми переменными-отношениями, что весьма похвально. Тем не менее
обычно предполагалось (неявно), что отдельный кортеж базовой переменной-
отношения всегда можно обновить независимо от всех остальных кортежей этой
базовой переменной-отношения;
в то же время очевидно (явно), что обновить отдельный кортеж представления не-
зависимо от всех остальных кортежей этого представления возможно не всегда.
Например, в [11.2] Кодд показал, что из результата определенного соединения невоз-
можно удалить хотя бы один кортеж, так как это приведет к получению отношения, ко-
торое “вовсе не является соединением двух каких-либо отношений” (это, в свою очередь,
означает, что результат, возможно, не будет удовлетворять предикату переменной-
отношения представления). Исторически сложилось так, что подобные операции обнов-
ления представлений полностью отбрасывались ввиду невозможности сделать эти опе-
рации полностью идентичными обновлениям базовых переменных-отношений.
Наш подход значительно отличается от изложенного выше. Говоря конкретнее, мы
признаем тот факт, что даже в базовых переменных-отношениях не всегда можно об-
новить отдельный кортеж независимо от остальных кортежей. Поэтому мы принимаем
как допустимые те операции обновления представлений, которые по сложившейся
традиции не рассматривались, и даем интерпретацию этих операций в виде четкого и
логически корректного способа обновления исходных переменных-отношений. Более
того, мы принимаем эти операции с полным пониманием того факта, что обновление
372
Часть II. Реляционная модель
исходных переменных-отношений может оказывать побочный эффект на представле-
ния. Однако такие побочные эффекты неизбежны и необходимы, так как в против-
ном случае возникает опасность, что представление перестанет удовлетворять
своему предикату.
Закончив вступительную часть, давайте перейдем к собственно обсуждению про-
блемы. Прежде всего определим необходимые термины. После этого приведем прави-
ла обновления представлений на основе соединений. Затем рассмотрим применение
этих правил для каждого из трех типов соединений (“один к одному”, “один ко мно-
гим”, “многие ко многим”).
Рассмотрим соединение J = A JOIN В. Здесь (как и в разделе 6.4 главы 6) перемен-
ные-отношения А, В и J имеют заголовки {X, Y}, {Y, Z} и {X, Y, Z} соответственно.
Пусть РА и РВ — это предикаты переменных-отношений А и В. Тогда предикат PJ пред-
ставления J будет иметь следующий вид.
РА ( a ) AND РВ ( b )
Здесь для каждого заданного кортежа j соединения а является “A-частью” кортежа
j (т.е. а — это кортеж, порождаемый из кортежа j посредством операции проекции,
исключающей компонент Z), а b является “В-частью” кортежа j (т.е. кортежем, поро-
ждаемым из кортежа j посредством операции проекции, исключающей компонент X).
Другими словами,
Каждый кортеж в соединении таков, что A-часть удовлетворяет предикату
РА, а В-часть удовлетворяет предикату РВ.
Например, предикат для соединения переменных-отношений S и SP по атрибуту S#
можно сформулировать следующим образом.
Каждый кортеж (s, n, t, с, р, q) в соединении таков, что кортеж (s, n, t, с)
удовлетворяет предикату переменной-отношения S, а кортеж (s, р, q) удовлетворяет
предикату переменной-отношения SP.
Приведем правила обновления представлений вида J = A JOIN В.
Правило INSERT. Новый кортеж j должен удовлетворять предикату PJ. Если А-
часть кортежа j не входит в переменную-отношение А, то она вставляется в А7.
Если В-часть не присутствует в переменной-отношении В, то она вставляется в В.
Правило DELETE. A-часть удаляемого кортежа удаляется из переменной-
отношения А и В-часть удаляемого кортежа удаляется из переменной-отношения В.
Правило UPDATE. Обновляемый кортеж должен быть таким, чтобы его обнов-
ленная версия удовлетворяла предикату PJ. A-часть этого кортежа удаляется из
переменной-отношения А без выполнения каких-либо триггерных процедур и
проверки предиката, а В-часть кортежа удаляется из переменной-отношения В,
опять же, без выполнения каких-либо триггерных процедур и проверки предиката.
7 Отметим, что операция INSERT может иметь побочный эффект, вследствие которого В-
часть кортежа j будет вставлена в переменную-отношение В, как в случае с представлениями, ос-
нованными на объединении, пересечении и вычитании (см. выше). Аналогичное замечание касается
правил для представлений, основанных на операциях DELETE и UPDATE. Для краткости мы не будем
вам докучать, детально рассматривая возможность побочных эффектов в каждом случае.
Глава 9. Представления
373
Если после этого A-часть обновленного кортежа все еще отсутствует в перемен-
ной-отношении А, то A-часть вставляется в А. Если В-часть обновленного корте-
жа отсутствует в переменной-отношении В, то она вставляется в В.
Теперь проверим возможность применения сформулированных правил ко всем трем
существующим типам соединений.
Соединения типа “один к одному”
Прежде всего отметим, что в данном случае термин “один к одному” можно заменить
более точным термином “(нуль или один) к (нулю или одному)”. Другими словами, име-
ет место ограничение целостности, гарантирующее, что для каждого кортежа перемен-
ной-отношения А будет существовать не более одного соответствующего кортежа пере-
менной-отношения В и наоборот. А это означает, что множество атрибутов Y, по которо-
му выполняется соединение, должно быть суперключом для обеих переменных-
отношений А и В (см. раздел 8.8 в главе 8, если необходимо освежить в памяти что-либо,
касающееся суперключей).
Примеры
В качестве первого примера читателю предлагается рассмотреть эффект примене-
ния приведенных выше правил к соединению переменной-отношения поставщи-
ков S с самой собой по атрибуту номера поставщика S# (только).
Во втором примере предположим, что в базе данных поставщиков и деталей со-
держится еще одна переменная-отношение SR с атрибутами S# и REST, где атрибут
S# идентифицирует поставщика, а атрибут REST содержит данные о его любимом
ресторане. Предположим, что в переменной-отношении SR представлены не все
поставщики, сведения о которых имеются в переменной-отношении S. Читателю
предлагается рассмотреть результат применения правила обновления к представ-
лению, определенному как соединение вида S JOIN SR (по атрибуту S#). Что из-
менится, если поставщик будет представлен в переменной-отношении SR, но не
будет представлен в переменной-отношении S?
Соединения типа “один ко многим ”
Здесь термин “один ко многим” можно заменить более точным термином “(нуль
или один) к (нулю или многим)”. Другими словами, имеет место ограничение целост-
ности, гарантирующее, что для каждого кортежа из переменной-отношения В сущест-
вует не более одного соответствующего кортежа в переменной-отношении А. Обычно
это означает, что множество атрибутов Y, по которому выполняется операция соеди-
нения, должно содержать подмножество (скажем, К), такое, что К является потенци-
альным ключом для переменной-отношения А и соответствующим внешним ключом
для переменной-отношения В.
Замечание Если сформулированные выше требования выполняются, то выражение
“нуль или один” можно заменить выражением “точно один”.
Примеры. Пусть представление SSP определено следующим выражением.
S JOIN SP
(Безусловно, это соединение типа “внешний ключ к соответствующему потенциаль-
ному ключу”.) Пример содержимого этого представления показан на рис. 9.7.
374
Часть II. Реляционная модель
S# SNAME STATUS CITY P# QTY
S1 Smith 20 London Pl 300
S1 Smith 20 London P2 200
S1 Smith 20 London P3 400
S1 Smith 20 London P4 200
S1 Smith 20 London P5 100
S1 Smith 20 London P6 100
S2 Jones 10 Paris Pl 300
S2 Jones 10 Paris P2 400
S3 Blake 30 Paris P2 200
S4 Clark 20 London P2 200
S4 Clark 20 London P4 300
S4 Clark 20 London P5 400
Рис. 9.7. Представление SSP (значения для примера)
Попытка вставить в представление SSP кортеж ('S4', 'Clark', 20, 'London',
'Рб', 100) будет завершена успешно и приведет к вставке кортежа ('S4', 'Рб',
100) в переменную-отношение SP (в результате чего новый кортеж появится и в
представлении).
Попытка вставить в представление SSP кортеж ('S5', 'Adams', 30, 'Athens',
'Рб', 100) будет завершена успешно и приведет к вставке кортежа ('S5', 'Рб',
100) в переменную-отношение SP (следовательно, новый кортеж добавится и к
представлению).
Попытка вставить в представление SSP кортеж ('S6', 'Green', 20, 'London',
'Рб', 100) будет завершена успешно и приведет к вставке кортежа ('S6',
'Green', 20, 'London') в переменную-отношение Зик вставке кортежа (' S6',
'Рб', 100) в переменную-отношение SP (в результате чего новый кортеж появит-
ся и в представлении).
Замечание. Предположим на мгновение, что в переменной-отношении SP возмож-
но наличие кортежей, не имеющих соответствующих кортежей в переменной-
отношении S. Более того, предположим, что переменная-отношение SP уже со-
держит несколько кортежей с номером поставщика 'S6' (но в этой переменной-
отношении отсутствует кортеж с номером поставщика 'S6' и номером детали
'Р1'). Тогда последняя из перечисленных операций вставки приведет к вставке в
представление дополнительных кортежей, а именно: в нем появятся соединения
кортежа ('S6', 'Green', 20, 'London') переменной-отношения S и тех корте-
жей с номером поставщика 'S6', которые присутствовали в переменной-
отношении SP ранее.
Попытка вставить в представление SSP кортеж ('S4', 'Clark', 20, 'Athens',
'Рб', 100) завершится неудачей (почему?).
Попытка вставить в представление SSP кортеж ('SI', 'Smith', 20, 'London',
'Pl', 400) завершится неудачей (почему?).
Глава 9. Представления
375
Попытка удалить из представления SSP кортеж ('S3', 'Blake', 30, 'Paris',
'Р2', 200) завершится успешно и приведет к удалению кортежа ('S3', 'Blake',
30, 'Paris') из переменной-отношения S и кортежа ('S3', 'Р2', 200)изпере-
менной-отношения SP.
Попытка удалить из представления SSP кортеж ('SI', 'Smith', 20, 'London',
'Pl', 300) завершится успешно (условно!) (см. замечание ниже) и приведет к
удалению кортежа ('SI', 'Smith', 20, 'London') из переменной-отношения S
и кортежа ('SI', 'Р1 ', 300) из переменной-отношения SP.
Замечание. На самом деле общий результат приведенной операции удаления будет
зависеть от установленного правила удаления внешнего ключа между отношения-
ми поставок и поставщиков. Если указана опция RESTRICT, то данная операция
удаления завершится ошибкой. Если указана опция CASCADE, то операция удаления
будет иметь побочный эффект, который выразится в удалении из переменной-
отношения SP дополнительно всех остальных кортежей (а значит, и кортежей
представления SSP), содержащих данные о поставщике с номером ' S1'.
Попытка обновить в представлении SSP кортеж ('SI', 'Smith', 20, 'London',
'Pl', 300) к виду ('SI', 'Smith', 20, 'London', 'Pl', 400) будет успешно
завершена и приведет к обновлению кортежа ('SI', 'Р1 ', 300) в переменной-
отношении SP к виду ('S1', 'Р1', 400).
Попытка обновить в представлении SSP кортеж ('SI', 'Smith', 20, 'London',
'Pl', 300) к виду ('Si', 'Smith', 20, 'Athens', 'Pl', 400) будет успешно
завершена и приведет к обновлению кортежа ('SI', 'Smith', 20, 'London') в
переменной-отношении S к виду ('SI', 'Smith', 20, 'Athens') и кортежа
('SI', 'Р1', 300) в переменной-отношении SP к виду ('SI', 'Р1', 400).
Попытка обновить в представлении SSP кортеж ('SI', 'Smith', 20, 'London',
'Pl', 300) к виду ('S6', 'Smith', 20, 'London', 'Pl', 300) будет успешно
завершена (условно!) (см. замечание ниже) и приведет к обновлению кортежа
('SI', 'Smith', 20, 'London') в переменной-отношении S к виду ('S6',
'Smith', 20, 'London') и кортежа ('Si', 'Р1 ', 300) в переменной-отношении
SPк виду ('S6', 'Р1', 300).
Замечание. На самом деле общий эффект приведенной выше операции обновле-
ния будет зависеть от установленного правила обновления внешнего ключа между
отношениями поставок и поставщиков. Детальное рассмотрение этого вопроса мы
оставляем читателю в качестве упражнения.
Соединения типа “многие ко многим”
Здесь термин “многие ко многим” следует заменить более точным термином “(нуль
или многие) к (нулю или многим)”. Другими словами, не существует стандартного огра-
ничения целостности, которое могло бы дать гарантии, аналогичные тем, которые мы
имели в случае соединений первого или второго типа.
Примеры. Предположим, что обсуждаемое представление определено с помощью
следующего выражения.
S JOIN Р
376
Часть II. Реляционная модель
Это соединение переменных-отношений S и Р по атрибуту CITY имеет тип “многие
ко многим”. Пример содержимого данного представления показан на рис. 9.8.
S# SNAME STATUS CITY P# PNAME COLOR WEIGHT
S1 Smith 20 London Pl Nut Red 12.0
S1 Smith 20 London P4 Screw Red 14.0
S1 Smith 20 London P6 Cog Red 19.0
S2 Jones 10 Paris P2 Bolt Green 17.0
S2 Jones 10 Paris P5 Cam Blue 12.0
S3 Blake 30 Paris P2 Bolt Green 17.0
S3 Blake 30 Paris P5 Cam Blue 12.0
S4 Clark 20 London Pl Nut Red 12.0
S4 Clark 20 London P4 Screw Red 14.0
S4 Clark 20 London P6 Cog Red 19.0
Рис. 9.8. Соединение переменных-отношений S и Р по атрибуту CITY
Вставка в представление кортежа ('S7', 'Bruce', 15, 'Oslo', 'Р8', 'Wheel',
'White', 25) будет успешно завершена и приведет к вставке кортежа ('S7',
'Bruce', 15, 'Oslo') в переменную-отношение S и кортежа (' Р8', 'Wheel',
'White', 25, 'Oslo') в переменную-отношение Р (в результате указанный кор-
теж попадет в представление).
Вставка в представление кортежа ('SI', 'Smith', 20, 'London', 'Р7', 'Washer',
'Red', 5) будет успешно завершена и приведет к вставке кортежа ('Р7', 'Washer',
' Red', 5, ' London') в переменную-отношение Р (в результате чего в представление
попадут два кортежа— ('SI', 'Smith', 20, 'London', 'Р7', 'Washer', 'Red',
5) и('S4', 'Clark', 20, 'London', 'P7', 'Washer', 'Red', 5)).
Вставка в представление кортежа ('S6', 'Green', 20, 'London', ' P7',
'Washer', 'Red', 5) будет успешно завершена и приведет к вставке кортежа
('S6', 'Green', 20, 'London') в переменную-отношение S и кортежа ('Р7',
'Washer', 'Red', 5, 'London') в переменную-отношение Р (в результате в
представление будет добавлено шесть новых кортежей).
Удаление из представления кортежа ('SI', 'Smith', 20, 'London', 'Pl',
'Nut', 'Red', 12) будет успешно завершено и приведет к удалению кортежа
('SI', 'Smith', 20, 'London') из переменной-отношения S и кортежа ('Р1',
'Nut', 'Red', 12, 'London') из переменной-отношения Р (в результате из пред-
ставления будут удалены четыре кортежа).
Дополнительные примеры читателю предлагается подготовить самостоятельно в ка-
честве упражнения.
Прочие операции
В этом разделе кратко описаны случаи использования в представлениях остальных
операций реляционной алгебры. Прежде всего, отметим, что операции ©-соединения,
полусоединения, полувычитания и деления не примитивные, поэтому правила для них
могут быть производными от правил для тех операций, в терминах которых они опреде-
лены. Относительно других операций можно сказать следующее.
Глава 9. Представления
377
Переименование. Тривиальный случай.
Декартово произведение. Как уже отмечалось в конце раздела 6.4 главы 6, декар-
тово произведение является частным случаем естественного соединения (операция
A JOIN В вырождается в операцию A TIMES В, если отношения А и В не имеют
общих атрибутов). Поэтому правила обновления для операции декартова произве-
дения (A TIMES В) являются частным случаем правил обновления для операции
соединения (конечно, как и правила обновления для операции пересечения
A INTERSECT В).
Обобщение. Операция обобщения (SUMMARIZE) тоже не является примитивной
и определяется в терминах операции расширения. Поэтому правила обновления
для операции обобщения являются производными от правил обновления для опе-
рации расширения.
Замечание. Для большинства представлений, определенных с использованием
операции обобщения, подавляющая часть обновлений фактически неприменима.
Однако причина заключается не в том, что такие представления не обновляемы по
своей сути. Попытки их обновления обычно завершаются неудачно из-за проти-
воречий с некоторыми установленными ограничениями целостности. Например,
пусть для определения представления используется следующее выражение.
SUMMARIZE SP PER SP { S# } ADD SUM ( QTY ) AS TOTQTY
Тогда попытка удаления кортежа, скажем, для поставщика с номером ' S1', будет
вполне успешной. Однако попытка вставки кортежа, скажем, ('S5', 500), приведет к
ошибке, поскольку эта попытка нарушает ограничение, согласно которому значение ат-
рибута TOTQTY должно быть равным сумме всех соответствующих отдельных значений
QTY. Попытка вставить кортеж ('S5', 0) тоже приведет к ошибке, но уже по другой
причине (по какой?).
Группирование и разгруппирование. Все замечания, которые были сделаны для
операции подведения итогов, справедливы и для этих операций.
Транзитивное замыкание. Почти такие же замечания применимы и в данном случае.
9.5. Моментальные снимки
Здесь будет уместно, несколько отклонившись от основной темы, обсудить понятие
моментальных снимков (snapshots) [9.2]. Моментальные снимки в действительности
имеют много общего с представлениями8, но не следует путать эти понятия. Как и пред-
ставления, моментальные снимки — это производные переменные-отношения, но в от-
личие от представлений снимки реальны, а не виртуальны, т.е. снимки представляются в
базе данных не только своими определениями в терминах других переменных-отноше-
ний, но и (по крайней мере, концептуально) собственной овеществленной копией дан-
ных, как, например, показано ниже.
8 Моментальные снимки иногда иначе называют овеществленными представлениями [9.1],
[9.3], [9.6], [9.14], [9.16]. Однако этот термин неудачен и его не рекомендуется использовать,
поскольку овегцествлены представления или нет — это вопрос реализации, а не модели. Что же
касается модели, то в ее понимании представления не овеществляются по определению и тер-
мин “овеществленное представление" является лдгической несообразностью.
378
Часть II. Реляционная модель
VAR P2SC SNAPSHOT
( ( S JOIN SP ) WHERE P#=P#('P2')){S#, CITY }
REFRESH EVERY DAY ;
Определение моментального снимка во многом подобно выполнению запроса, за ис-
ключением следующего.
1. Результат выполнения этого запроса хранится в базе данных под указанным име-
нем (в приведенном выше примере это P2SC) как переменная-отношение, доступ к
которой разрешен только для чтения (не считая операции периодического обнов-
ления; см. ниже).
2. Периодически (в нашем примере — каждый день, что устанавливается опцией
EVERY DAY) содержание моментального снимка обновляется, т.е. текущие данные
аннулируются и запрос выполняется повторно, после чего полученный результат
запроса записывается в качестве нового значения моментального снимка.
Таким образом, моментальный снимок P2SC всегда представляет состояние данных,
которое они имели не более 24 часов назад (каким в этом случае должен быть предикат
данного отношения?).
Суть идеи моментальных снимков состоит в том, что многие приложения (возможно,
даже большинство) могут допускать или даже требовать для обработки данные в том со-
стоянии, в котором они находились в определенный момент. В частности, в эту категорию
приложений попадают многие приложения для создания отчетов и ведения бухгалтерского
учета. Подобные приложения обычно требуют фиксации состояния данных в установлен-
ное время (например, в конце периода отчетности), и концепция моментальных снимков
позволяет выполнить такую фиксацию, не влияя на работу других транзакций, обновляю-
щих рассматриваемые данные в режиме реального времени. Аналогично может потребо-
ваться зафиксировать состояние большого объема данных, которые используются для вы-
полнения сложного запроса или приложения, не требующего модификации исходных дан-
ных, опять же, чтобы избежать блокирования обновления данных на время их выполнения.
Замечание. Эта идея становится еще привлекательнее в среде распределенных баз дан-
ных или приложений поддержки принятия решений (подробности приводятся в главах 20 и
21 соответственно). Отметим также, что моментальные снимки представляют важный ча-
стный случай контролируемой избыточности (см. главу 1), а процедура “обновление
снимка” — это соответствующий процесс распространения обновления (снова см. главу 1).
В общем случае определение моментального снимка имеет следующий синтаксис.
VAR <имя переменной-отношениЯ> SNAPSHOT реляционное выражение>
<список определений потенциальных ключей>
REFRESH EVERY <период> ;
В этом определении для указания периода обновления моментального снимка ис-
пользуется параметр <период>, который может принимать, например, следующие значе-
ния: MONTH (месяц), WEEK (неделя), HOUR (час), n MINUTES (п минут), MONDAY (понедельник),
WEEKDAY (день недели) и т.п. Ниже приведен синтаксис выражения для удаления опреде-
ления моментального снимка.
DROP VAR <имя переменной-отношения> }
Здесь параметр <имя переменной-отношения> задает имя удаляемого моментально-
го снимка.
Глава 9. Представления
379
Замечание. Мы подразумеваем, что операция DROP завершится неудачно, если какая-
либо переменная-отношение в данный момент ссылается на удаляемый моментальный
снимок. Альтернативным решением может быть расширение приведенного выше опре-
деления моментального снимка за счет включения опций RESTRICT и CASCADE. Здесь мы
не будем обсуждать эту возможность.
9.6. Поддержка представлений в языке SQL
В этом разделе будут рассмотрены средства поддержки представлений, существую-
щие в языке SQL (к сожалению, на данный момент язык SQL не предусматривает под-
держки моментальных снимков). Прежде всего, рассмотрим синтаксис оператора созда-
ния представления CREATE VIEW.
CREATE VIEW <имя представлений AS <табличное выражение>
[ WITH [ <квалификатор> ] CHECK OPTION ] ;
Здесь параметр <квалификатор> может принимать значение CASCADED или LOCAL, при-
чем значение CASCADED принимается по умолчанию (и фактически это единственная ра-
зумная опция, как подробно объясняется в [4.19]), поэтому здесь опцию LOCAL мы рас-
сматривать не будем.
Пояснения
1. Значение параметра <табличное выражение> представляет собой определение
представления. Формат этого выражения подробно описывается в приложении А.
2. Фраза WITH CHECK OPTION, если она указана, означает, что операции вставки
(INSERT) и обновления (UPDATE) для данного представлении будут отменены в слу-
чае нарушения ограничений целостности, указанных в определении представления.
Поэтому заметьте, что подобные операции будут завершаться выдачей ошибки
лишь в том случае, когда определитель WITH CHECK OPTION указан явно, т.е. по
умолчанию любые операции вставки и обновления кортежей будут завершаться ус-
пешно. На основании выводов, сделанных в разделе 9.4, можно заключить, что по-
добное поведение логически некорректно. Поэтому настоятельно рекомендуется
всегда указывать опцию WITH CHECK OPTION в определениях любых создаваемых
представлений9 [9.8].
Примеры
1. CREATE VIEW SUPPLIER
AS SELECT S.S#, S.STATUS, S.CITY
FROM S
WHERE S.STATUS > 15
WITH CHECK OPTION ;
2. CREATE VIEW REDPART
AS SELECT P.P#, P.NAME, P.WEIGHT AS WT, P.CITY
9 Безусловно, речь идет только об обновляемых представлениях. Как мы убедимся позже, в
языке SQL представления часто не являются обновляемыми и наличие опции WITH CHECK
OPTION в таких случаях недопустимо в соответствии с требованиями языка SQL.
380
Часть II. Реляционная модель
FROM P
WHERE P.COLOR = 'Red'
WITH CHECK OPTION ;
3. CREATE VIEW PQ
AS SELECT SP.P#, SUM ( SP.QTY ) AS TOTQTY
FROM SP
GROUP BY SP.P# ;
В отличие от приведенного выше аналога этого представления (см. в разделе 9.1
подраздел “Дополнительные примеры”), данное представление не будет включать
строк для деталей, которые не поставляются ни одним из поставщиков. Подробно-
сти приводятся в обсуждении примера 7.7.8 в главе 7.
4. CREATE VIEW CITY_PAIR
AS SELECT DISTINCT S.CITY AS SCITY, P.CITY AS PCITY
FROM S, SP, P
WHERE S.S# = SP.S#
AND SP.P# = P.P# ;
5. CREATE VIEW HEAVY_REDPART
AS SELECT RP.P#, RP.PNAME, RP.WT, RP.CITY
FROM REDPART AS RP
WHERE RP.WT >12.0
WITH CHECK OPTION ;
Существующее представление может быть удалено с помощью SQL-оператора DROP
VIEW, синтаксис которого приведен ниже.
DROP VIEW <имя представления> <режим> ;
В этом операторе (как и в SQL-операторах DROP TABLE и DROP DOMAIN) значением па-
раметра <режим> могут быть опции RESTRICT и CASCADE. Если указана опция RESTRICT и
на удаляемое представление имеются ссылки в определениях других представлений или
ограничений целостности, то данная операция DROP будет признана ошибочной. Если
указана опция CASCADE, то выполнение данной операции DROP завершится успешно и бу-
дет сопровождаться “каскадным” удалением всех представлений и ограничений целост-
ности, определения которых ссылаются на данное удаляемое представление.
Выборка данных из представлений
Как было показано в разделе 9.3, для всех операций выборки данных из любых пред-
ставлений в текущей версии стандарта языка SQL (SQL/92) гарантируется корректность
выполнения. К сожалению, этого нельзя сказать о некоторых современных программных
продуктах, как и о предыдущих версиях стандарта языка SQL (см. упр. 9.14).
Обновление данных в представлениях
Стандарт SQL/92 поддерживает весьма ограниченный набор операций обновле-
ния данных в представлениях. В качестве обновляемых, в основном, рассматрива-
ются только те представления, которые являются производными от одной базовой
таблицы и описаны с использованием некоторой комбинации операций выборки и
Глава 9. Представления
381
проекции. Более того, поддержка даже такого простейшего типа представлений
трактуется неправильно, поскольку в стандарте языка SQL не используется понятие
предиката переменной-отношения и, в частности, в SQL-таблицах разрешается на-
личие повторяющихся строк.
Ниже приведено более точное изложение правил обновляемости представлений в со-
ответствии со стандартом языка SQL (этот список взят из [4.19], хотя здесь он несколько
упрощен). Стандартом языка SQL предполагается, что представление является обнов-
ляемым только в том случае, если выполнены все следующие условия.
1. Табличное выражение, определяющее область видимости представления, должно
быть выражением выборки, т.е. в него не должны непосредственно входить такие
ключевые слова, как JOIN, UNION, INTERSECT и EXCEPT.
2. Предложение SELECT в выражении выборки не должно непосредственно содержать
ключевое слово DISTINCT.
3. Каждый выбираемый элемент в предложении SELECT (после любых требуемых
расширений этого списка, заданных шаблоном “звездочка” (*)) должен быть
именем столбца (возможно, уточненным и при необходимости сопровождае-
мым фразой AS), представляющим простую ссылку на столбец исходной табли-
цы (см. п. 5).
4. Предложение FROM в выражении выборки должно содержать ровно одну ссылку
на таблицу.
5. Данная ссылка на таблицу должна задавать либо базовую таблицу, либо обновляе-
мое представление.
Замечание. Таблица, которую задает ссылка, является единственной исходной таб-
лицей для рассматриваемого обновляемого представления (см. п. 3).
6. Заданное выражение выборки не должно включать предложения WHERE с подзапро-
сом, в котором содержится предложение FROM, ссылающееся на ту же таблицу, что
и основное предложение FROM, рассмотренное в п. 4.
7. Выражение выборки не должно включать предложения GROUP BY.
8. Выражение выборки не должно включать предложения HAVING.
Сделаем пару замечаний к перечисленным правилам.
1. Подход к обновляемости представлений в языке SQL следует принципу “все
или ничего”. Это значит, что по отношению к любому представлению все три
операции, INSERT, UPDATE и DELETE, либо можно применять, либо нельзя. На-
пример, в языке SQL невозможна ситуация, когда к некоторому представлению
допускается применение операции DELETE, но запрещено применять операцию
INSERT (хотя отдельные коммерческие программные продукты такую возмож-
ность поддерживают).
2. В языке SQL операция UPDATE либо применима к данному представлению, либо
нет. Иначе говоря, в языке SQL недопустима ситуация, когда одни столбцы пред-
ставления являются обновляемыми, а другие — нет (хотя некоторые коммерческие
программные продукты в этом отношении пошли дальше стандарта).
382
Часть II. Реляционная модель
9.7. Резюме
Представление — это, по сути, именованное реляционное выражение. Представле-
ние можно рассматривать как производную виртуальную переменную-отношение.
Операции над представлениями обычно реализуются с помощью процедуры подстанов-
ки, состоящей в замене ссылки на имя представления тем выражением, которое это
представление определяет. Процедура подстановки работает корректно благодаря свой-
ству реляционной замкнутости. Для операций выборки процесс подстановки коррект-
но выполняется в 100% случаев (по крайней мере, теоретически, но необязательно на
практике для существующих продуктов). Для операций обновления процесс подстанов-
ки корректно выполняется также в 100% случаев10 (опять же, теоретически, но необяза-
тельно на практике). Однако для некоторых представлений (например, представлений,
определяемых в терминах операции обобщения) попытка обновления обычно приводит к
ошибке, поскольку нарушаются установленные в системе ограничения целостности. В
этой главе также рассматривался обширный набор принципов, которым должна удовле-
творять схема обновления. Была подробно рассмотрена работа схемы обновления для
представлений, определенных в терминах операций объединения, пересечения, вычи-
тания, выборки, проекции, соединения и расширения. Для каждой из этих операций
были описаны соответствующие правила вывода предиката (переменной-отношения).
Также была затронута проблема представлений и логической независимости дан-
ных. Существует два аспекта такой независимости: аспект роста и аспект реструктури-
зации. Среди других преимуществ представлений можно отметить их способность скры-
вать данные и, следовательно, обеспечивать определенный уровень защиты, а также их
способность выступать в роли сокращенной записи и тем самым упрощать работу поль-
зователей. Были рассмотрены два важных принципа: принцип взаимозаменяемости (из
которого, в частности, следует, что представления должны быть обновляемы) и принцип
относительности базы данных.
Отклонившись на некоторое время от основной темы, мы бегло обсудили использо-
вание моментальных снимков. И наконец в главе кратко были описаны те аспекты
языка SQL, которые имеют отношение к обсуждаемой теме.
Упражнения
9.1. Используя реляционное исчисление, предоставьте аналоги алгебраических опре-
делений представлений, приведенных в подразделе “Дополнительные примеры”
раздела 9.1.
9.2. Дайте определение представления, содержащего номера поставщиков и номера дета-
лей для тех поставщиков и деталей, которые размещены не в одном и том же городе.
9.3. Дайте определение представления, содержащее кортежи для тех поставщиков, ко-
торые находятся в Лондоне.
9.4. В контексте базы данных поставщиков, деталей и проектов переопределите пере-
менную-отношение SP как представление на базе переменной-отношения SPJ.
10 Поскольку мы рассматриваем представления как переменные-отношения, а любые пере-
менные всегда обновляемы по определению.
Глава 9. Представления
383
9.5. В контексте базы данных поставщиков, деталей и проектов определите представ-
ление, включающее данные обо всех проектах (атрибуты номера проекта и назва-
ния города), детали для которых поставляет поставщик с номером 'S1' ив кото-
рых используется деталь с номером ' Р1'.
9.6. Пусть имеется представление, определенное следующим образом.
VAR HEAVYWEIGHT VIEW
( ( Р RENAME WEIGHT AS WT, COLOR AS COL )
WHERE WT > WEIGHT ( 14.0 ) ) { P#, WT, COL } ;
Покажите преобразованную форму каждого из перечисленных ниже операторов
после выполнения процедуры подстановки.
a) RA := HEAVYWEIGHT WHERE COL = COLOR ( 'Green' ) ;
6) RB := ( EXTEND HEAVYWEIGHT ADD WT + WEIGHT ( 5.3 ) AS WTP )
{ P#, WTP } ;
в) UPDATE HEAVYWEIGHT WHERE WT = WEIGHT ( 18.0 ) COL := 'White' ;
r) DELETE HEAVYWEIGHT WHERE WT < WEIGHT ( 10.0 ) ;
д) INSERT INTO HEAVYWEIGHT
RELATION { TUPLE { P# P# ( 'P99' ),
WT WEIGHT ( 12.0 ),
COL COLOR ( 'Purple' ) } } ;
9.7. Предположим, что приведенное в упр. 9.6 определение представления HEAVYWEIGHT
изменено следующим образом.
VAR HEAVYWEIGHT VIEW
( ( ( EXTEND Р ADD WEIGHT * 454 AS WT ) RENAME COLOR AS COL )
WHERE WT > WEIGHT ( 14.0 )){ Pfl, WT, COL } ;
(Атрибут WT теперь содержит вес в граммах, а не в фунтах.) Выполните упр. 9.6 для
этого случая.
9.8. В главе 8 указывалось, что для представлений иногда желательно иметь возмож-
ность объявления потенциальных ключей (или первичного ключа). Почему такая
возможность может быть желательной?
9.9. Какие расширения системного каталога, описанного в главах 3 и 5, необходимы
для поддержки механизма представлений? Что можно дополнительно сказать по
поводу моментальных снимков?
9.10. Предположим, что базовая переменная-отношение R была заменена выборками А и
В, такими, что объединение A UNION В всегда эквивалентно исходному отношению
R, а пересечение A INTERSECT В всегда пустое. Достижима ли в этом случае логи-
ческая независимость данных?
9.11.
а) Пересечение A INTERSECT В эквивалентно соединению A JOIN В (это соедине-
ние типа “один к одному”, что не совсем точно, поскольку в переменной-
отношении А могут существовать кортежи, для которых нет соответствующих
кортежей в переменной-отношении В, и наоборот). Совместимы ли с подобной
эквивалентностью изложенные в разделе 9.4 правила обновления представле-
ний, определенных посредством операций пересечения и соединения?
384
Часть II. Реляционная модель
б) Пересечение A INTERSECT В также эквивалентно вычитанию A MINUS
(A MINUS В) и вычитанию В MINUS (В MINUS А). Совместимы ли с подобной
эквивалентностью изложенные в разделе 9.4 правила обновления представле-
ний, определенных посредством операций пересечения и вычитания?
9.12. Один из принципов, изложенных в разделе 9.4, состоит в том, что операции
INSERT и DELETE, насколько это возможно, должны быть противоположными од-
на другой. Следуют ли этому принципу изложенные в этом разделе правила об-
новления представлений, определенных посредством операций объединения,
вычитания и пересечения?
9.13. В разделе 9.2 (при рассмотрении проблемы логической независимости данных) об-
суждалась возможность реструктуризации базы данных поставщиков и деталей по-
средством замены базовой переменной-отношения S двумя проекциями этой пере-
менной-отношения с именами SNC и ST. Там же отмечалось, что подобная реструк-
туризация не всегда тривиальна. Какой смысл имеет последнее замечание?
9.14. Исследуйте любой доступный для вас SQL-продукт и дайте ответы на следую-
щие вопросы.
а) Можно ли привести примеры каких-либо операций выборки данных из пред-
ставлений, которые приведут к ошибке?
б) Каковы правила обновления представлений для этого продукта? (Возможно,
они окажутся менее строгими в сравнении с теми требованиями, которые были
изложены в разделе 9.6.)
9.15. Рассмотрим базу данных поставщиков и деталей, но для простоты будем игнори-
ровать наличие переменной-отношения деталей. Ниже сокращенно описаны два
возможных варианта проекта базы данных поставщиков и поставок.
a) S { S#, SNAME, STATUS, CITY }
SP { S#, P#, QTY }
6) SSP { S#, SNAME, STATUS, CITY, P#, QTY }
XSS { S#, SNAME, STATUS, CITY }
Проект а можно считать обычным. В проекте б, напротив, переменная-
отношение SSP содержит кортеж для каждой поставки, включающий соответст-
вующий номер детали, количество деталей и полную информацию о поставщике,
тогда как переменная-отношение XSS содержит информацию о тех поставщиках,
которые вовсе не поставляют деталей. (Обратите внимание, что оба проекта ин-
формационно равносильны и, следовательно, эти проекты служат иллюстрацией
принципа взаимозаменяемости.) Напишите определения представлений для вы-
ражения проекта б в виде представлений в составе проекта а и наоборот. Также
предоставьте все необходимые ограничения базы данных для каждого из вариан-
тов проекта (см. главу 8, если потребуется освежить в памяти материал об огра-
ничениях базы данных). Имеет ли каждый из проектов какие-либо явные пре-
имущества по сравнению с другим? Если да, то какие?
9.16. Выполните упр. 9.2-9.5 с использованием языка SQL.
9.17. Еще раз обратитесь к определению реляционной модели, приведенному в конце
раздела 3.2 в главе 3, и убедитесь, что теперь вы его понимаете полностью.
Глава 9. Представления
385
Список литературы
9.1. Adelberg В., Garcia-Molina Н., Widom J. The STRIP Rule System for Efficiently
Maintaining Data // Proc. ACM SIGMOD Int. Conf on Management of Data. —
Tucson, Ariz., May, 1997.
STRIP — это сокращение полного названия процессора Stanford Real-time
Information Processor. Данный процессор использует “правила”, т.е., по сути, триг-
герные процедуры (см., например, [8.22]), для обновления моментальных снимков
(здесь они называются производными данными) при каждом изменении исходных
данных в базе. Проблема использования такой системы заключается в том, что ес-
ли данные в базе изменяются достаточно часто, то дополнительная нагрузка на
систему в связи с выполнением установленных правил оказывается чрезмерной. В
статье описываются методы STRIP, позволяющие уменьшить эту нагрузку.
9.2. Adiba М, Derived Relations: A Unified Mechanism for Views, Snapshots, and
Distributed Data // Proc. Int. Conf. On Very Large Data Bases. — Cannes, France.,
September, 1981. См. также более раннюю версию: Adiba М.Е., Lindsay B.G.
Database Snapshots // IBM Research Report RJ2772. — March, 1980.
В работе впервые представлена концепция моментальных снимков, а также пред-
ложены соответствующая семантика и принципы реализации. Относительно реали-
зации следует заметить, что внутри системы можно использовать различные типы
“дифференциальных обновлений” или инкрементное сопровождение, т.е. системе
не всегда потребуется при обновлении снимка повторно выполнять исходный за-
прос в полном объеме.
9.3. Agrawal D., El Abbadi A., Singh A., and Yurek T. Efficient View Maintenance of Data
Warehouses // Proc. ACM SIGMOD Int. Conf, on Management of Data. — Tucson,
Ariz., May, 1997.
Вспомним из главы 1, что хранилище данных — это база данных, в которой содер-
жатся данные для поддержки принятия решений, т.е., по сути, моментальные снимки,
если использовать терминологию настоящей главы (и термин “представление” (view)
в заголовке этой статьи на самом деле относится не к представлениям, а к момен-
тальным снимкам). Как указывалось в аннотации к [9.2], моментальные снимки мож-
но сопровождать инкрементно и такое сопровождение весьма желательно с точки
зрения производительности системы. Однако инкрементное сопровождение может
привести к затруднениям, если моментальные снимки создаются с нескольких от-
дельных баз данных, которые в это же время подвергаются обновлению. В настоя-
щей статье предлагается решение данной проблемы.
9.4. Buff H.W. Why Codd's Rule №6 Must Be Reformulated // ACM SIGMOD.—
Desember, 1988. — 17, № 4.
В 1985 году Кодд (Codd) опубликовал набор из двенадцати правил, предназначен-
ных для использования в качестве “части теста для определения, является ли про-
дукт, объявленный как полностью реляционный, на самом деле таковым” [9.5].
Правило Кодда № 6 требует, чтобы все представления, теоретически обновляемые,
были обновляемы и в данной конкретной системе. В этой короткой заметке Буфф
(Buff) утверждает, что общая проблема обновляемости представлений неразреши-
ма, т.е. не существует общего алгоритма определения обновляемости (в смысле
386
Часть II. Реляционная модель
определения Кодда) или ее отсутствия для произвольного представления. Тем не
менее следует заметить, что определение обновляемости, использованное в этой
главе, несколько отличается от определения, введенного Коддом. Различие состоит
в том, что использованное в данной главе определение обновляемости сформули-
ровано в терминах предикатов переменных-отношений.
9.5. Codd E.F. Is Your DBMS Really Relational? and Does Your DBMS Run by the Rules?
Computerworld. — October, 1985. — № 14, № 21.
9.6. Colby L.S. Supporting Multiple View Maintenance Policies // Proc. ACM SIGMOD Int.
Conf, on Management of Data. — Tucson, Ariz., May, 1997.
“Представлениями” в этой статье именуются не представления, а моментальные
снимки. Существует три широко распространенных подхода к поддержке актуаль-
ности моментальных снимков.
1. Непосредственный. При каждом обновлении любых исходных переменных-
отношений немедленно запускается соответствующая процедура обновления
моментального снимка.
2. Отложенный. Моментальный снимок обновляется только по требованию поль-
зователя.
3. Периодический. Моментальный снимок обновляется через указанные интерва-
лы времени (например, каждый день).
В сущности, моментальные снимки предназначены для повышения производи-
тельности выполнения запросов за счет расходов на обновление, и три упомянутые
выше стратегии представляют различные компромиссы между повышением про-
изводительности и потерями в связи с этим. В статье изучаются вопросы, связан-
ные с применением различных стратегий для различных моментальных снимков в
одной и той же системе в одно и то же время.
9.7. Chamberlin D.D., Gray J.N., Traiger I.L. Views, Authorization, and Locking in a
Relational Data Base System // Proc. NCC 44. — Calif. Montvale, N.J.: AFIPS Press,
May, 1975.
Содержит краткое логическое обоснование подхода, выбранного для организации
обновления представлений в прототипе системы System R (и, следовательно, в сис-
темах SQL/DS и DB2, в стандарте SQL и т.п.). См. также [9.15], где можно найти
аналогичное обоснование для прототипа системы INGRES.
9.8. Darwen Н. Without Check Option. Relational Database Writings 1989-1991.—
Reading, Mass.: Addison-Wesley, 1992.
9.9. Date C.J., McGoveran D. Updating Union, Intersection, and Difference Views, and
Updating Joins and Other Views. Relational Database Writings 1989-1991. — Reading,
Mass.: Addison-Wesley, 1995.
Замечание. Формальные версии этих статей на время написания настоящей книги
находились в процессе подготовки.
9.10. Dayal U., Bernstein Р.А. On the Correct Translation of Update Operations on Relational
Views 11 ACM TODS. — September, 1982. — 7, № 3.
Это первое действительно формальное изложение правил обновления представлений
(только для представлений, описанных с помощью операции выборки, проекций и
соединения). Однако предикаты переменных-отношений здесь не рассматриваются.
Глава 9. Представления
387
9.11. Furtado A.L., Casanova M.A. Updating Relational Views // Query Processing in
Database Systems. — New York, N.Y.: Springer Verlag, 1985.
Здесь описаны два достаточно общих подхода к решению проблемы обновления пред-
ставлений. Один из них (в книге детально изложен только один подход) является по-
пыткой разработки общего механизма, работающего независимо от сложности струк-
туры базы данных. В этом подходе используется исключительно определение иссле-
дуемого представления. Другой подход, менее амбициозный, требует, чтобы админист-
ратор базы данных явно указал для каждого представления, какие обновления для него
допустимы и какова семантика соответствующих операций. Это выполняется посредст-
вом создания процедурного кода, реализующего обновления представлений в контексте
исходных базовых переменных-отношений. Работа включает обзор показателей эффек-
тивности каждого из подходов (по состоянию на 1985 год). Кроме того, в книге пред-
ставлен обширный список литературы, изданной до 1985 года.
9.12. Goodman N. View Update Is Practical // InfoDB.— 1990. — 5, №2.
Весьма неформальный прагматический обзор проблемы обновляемости
представлений. Вот цитата из введения (несколько перефразированная): “Дайал
(Dayal) и Бернштейн (Bernstein) [9.10] доказали, что, по существу, все интересные
представления не являются обновляемыми. Буфф (Buff) [9.4] доказал, что не
существует алгоритма определения обновляемости произвольного представления.
Но, кажется, есть небольшая надежда. [Однако] ничто не может быть дальше от
истины. Обновления представлений возможны и реальны”. И далее в статье
приводится ряд методов обновления представлений. Однако ключевое понятие
предикатов переменных-отношений не рассматривается.
9.13. Keller A.M. Algorithms for Translating View Updates to Database Updates for Views
Involving Selections, Projections, and Joins // Proc. 4th ACM SIGACT-SIGMOD
Symposium on Principles of Database Systems. — Portland, Ore., March, 1985.
Предложен набор из пяти критериев, которым должен удовлетворять алгоритм об-
новления представлений: отсутствие побочных эффектов, только одноэтапные из-
менения, отсутствие ненужных изменений, отсутствие возможности более простых
замен и отсутствие пар операций DELETE-INSERT вместо операции UPDATE. В этой
работе также представлены алгоритмы, которые удовлетворяют изложенным кри-
териям. Кроме всего прочего, приведенные в книге алгоритмы позволяют реализо-
вать обновления одного типа с помощью операций другого типа. Например, опе-
рация DELETE для представления может быть реализована посредством операции
UPDATE в исходной базовой переменной-отношении (например, поставщик может
быть удален из представления, описывающего лондонских поставщиков, посредст-
вом замены значения атрибута города CITY значением 'Paris'). Другой пример (не
вошедший в работу Келлера (Keller)): операция DELETE в представлении V (где V
определено посредством операции вычитания A MINUS В) может быть реализована
как вставка кортежа в переменную-отношение В, а не как удаление кортежа из пе-
ременной-отношения А. Заметьте, что в данной главе мы отбросили подобные спо-
собы реализации операций обновления на основании описанных в ней принципов.
9.14. Quass D. and Widom J. On-Line Warehouse View Maintenance // Proc. ACM SIGMOD
Int. Conf, on Management of Data. —Tucson, Ariz., May, 1997.
388
Часть IL Реляционная модель
Под представлениями (view), упомянутыми в заголовке этой статьи, понимаются
не представления, а моментальные снимки. В ней приведен алгоритм поддержки
моментальных снимков. Он позволяет одновременно выполнять транзакции со-
провождения моментальных снимков и запросы к их данным.
9.15. Stonebraker M.R. Implementation of Views and Integrity Constraints by Query
Modification // Proc. ACM SIGMOD Intern. Conf, on Management of Data. — San
Jose, Calif., May, 1975.
См. комментарии к [9.7].
9.16. Zhuge Y., Garcia-Molina H., Hammer J. and Widom J. View Maintenance in a
Warehousing Environment // Proc. ACM SIGMOD Int. Conf, on Management of
Data. — San Jose, Calif, May, 1995.
Представлениями в этой статье именуются не представления, а моментальные
снимки. После обновления некоторых исходных данных со стороны хранилища
данных может потребоваться выдать запрос к базе данных прежде, чем будет вы-
полнено необходимое сохранение снимка, и время задержки между таким запро-
сом и обновлением исходной базы данных может привести к аномалиям. В статье
представлен алгоритм для обработки подобных аномалий.
Ответы к некоторым упражнениям
9.1. Приведенные ниже ответы пронумерованы как 9.1./?, где п— номер примера в
разделе 9.1. Здесь используются наши обычные допущения относительно перемен-
ных диапазона.
9.1.1. VAR REDPART VIEW
( PX.P#, РХ.PNAME, РХ.WEIGHT AS WT, PX.CITY )
WHERE PX.COLOR = COLOR ( 'Red' ) ;
9.1.2. VAR PQ VIEW
( PX.P#,
SUM ( SPX WHERE SPX.P# = PX.P#, QTY ) AS TOTQTY ) ;
9.1.3. VAR CITY_PAIR VIEW
( SX.CITY AS SCITY, PX.CITY AS PCITY )
WHERE EXISTS SPX ( SPX.S# = SX.S# AND
SPX.P# = PX.P# ) ;
9.1.4. VAR HEAVY_REDPART VIEW
RPX WHERE RPX.WT > WEIGHT ( 12.0 ) ;
Здесь RPX — это переменная диапазона, которая изменяется на представлении
REDPART.
9.2. VAR NON_COLOCATED VIEW
( S TIMES P ) { S#, P# } MINUS
( S JOIN P ) { S#, P# } ;
9.3. VAR LONDON_SUPPLIER VIEW
( S WHERE CITY = 'London' ) { ALL BUT CITY } ;
Глава 9. Представления
389
Замечание. Из представления исключен атрибут CITY, так как известно, что он все-
гда будет иметь значение 'London'. Тем не менее следует заметить, что подобный
пропуск атрибута приводит к тому, что любая операция INSERT для данного пред-
ставления будет завершаться неудачей (только если для атрибута CITY в исходной
переменной-отношении поставщиков не установлено принимаемое по умолчанию
значение, равное 'London'). Другими словами, подобные представления, вероятно,
вовсе не могут поддерживать операцию INSERT. (В качестве альтернативы сущест-
вует идея определения значения по умолчанию для атрибута CITY, равного значе-
нию 'London', но только для кортежей, вставляемых через данное представле-
ние. Идея значений по умолчанию, специфических для представления, требует
более глубокого изучения.)
9.4. Проблема здесь состоит в следующем: “Как определить атрибут QTY в представле-
нии SP?”. Разумным решением будет такой ответ: для данной пары S#-P# атрибут
SP.QTY нужно определить как сумму всех значений SPJ.QTY, вычисляемую по всем
номерам J# для выбранной пары S#-P#.
VAR SP VIEW
SUMMARIZE SPJ PER SPJ { S#, P# }
AND SUM ( QTY ) AS QTY ;
9.5. VAR JC VIEW
( SPJ WHERE S# = S# ( 'SI' ) ) { J# } JOIN
( SPJ WHERE P# = P# ( 'Pl' ) ) { J# } ) JOIN
J { J#, CITY } ;
9.6. Преобразованные формы читателю предлагается записать самостоятельно. Тем не
менее заметим, что случай д приведет к ошибке, так как вставляемый кортеж не
удовлетворяет предикату представления.
9.7. И снова случай д приведет к ошибке, но теперь причина несколько иная. Во-первых,
СУБД будет использовать для атрибута WEIGHT значение по умолчанию (скажем, w),
поскольку пользователь не передает системе конкретного значения этого атрибута (и,
конечно, не может этого сделать). Во-вторых, значение атрибута WT, которое указал
пользователь, необязательно будет равным w*454, даже если (что в нашем примере
не наблюдается) значение атрибута WT превышает 14.0. Следовательно, вставляемый
кортеж опять не удовлетворяет предикату представления.
Замечание. Можно привести доводы, что значение атрибута WEIGHT в новом кортеже
должно быть установлено правильно, т.е. равняться указанному для атрибута WT зна-
чению, деленному на 454. Эта возможность также требует дальнейшего изучения.
9.8. Приведенный список причин взят из [5.7].
Если вместо базовых переменных-отношений пользователи оперируют представле-
ниями, то очевидно, что эти представления должны выглядеть для пользователей, как
базовые переменные-отношения, насколько это возможно. В идеальном случае поль-
зователь не должен даже догадываться, что оперирует представлениями, но ему
должно быть позволено обращаться с представлениями, как с базовыми переменны-
ми-отношениями, в соответствии с принципом относительности базы данных. И по-
добно тому, как пользователю базовых переменных-отношений необходима инфор-
мация об их потенциальных ключах (в общем случае), так и пользователю представ-
390
Часть II. Реляционная модель
лений необходимы сведения о потенциальных ключах этих представлений (опять же,
в общем случае). Явное объявление потенциальных ключей представлений— это
очевидный способ сделать данную информацию доступной пользователям.
СУБД может не включать средств определения потенциальных ключей для соб-
ственных нужд (это утверждение истинно для всех современных СУБД). Таким
образом, явное объявление потенциальных ключей — единственно доступный
(для администратора базы данных) способ информирования СУБД и пользовате-
лей о наличии таких ключей.
Даже если бы СУБД могли самостоятельно определять потенциальные ключи
для собственных нужд, явное объявление по крайней мере позволило бы системе
удостовериться, что определенные ею ключи не являются несовместимыми с
ключами, которые объявил администратор базы данных.
Администратор базы данных может располагать дополнительной информацией,
которая не заложена в СУБД, и, следовательно, оптимизировать ключи, опреде-
ленные СУБД автоматически. В [5.7] приведен пример такого случая.
В [11.3] предложен другой довод, который, по существу, сводится к тому, что по-
добная возможность (явное объявление потенциальных ключей) обеспечивает про-
стой и удобный способ описания некоторых важных ограничений целостности, ко-
торые в противном случае потребовали бы весьма многословного описания.
9.9. Очевидно, что на эти вопросы невозможно дать окончательных ответов. Ниже из-
ложены некоторые соображения.
Каждому представлению и каждому моментальному снимку в базе данных в ее
каталоге будет соответствовать запись в переменной-отношении RELVAR со зна-
чением 'View' или 'Snapshot' в атрибуте RVKIND соответственно.
Каждому определенному в базе данных представлению в ее каталоге будет также-
соответствовать запись в новой переменной-отношении, которая может так и на-
зываться— VIEW. Запись должна включать то выражение, которое использова-
лось при определении данного представления.
Аналогично каждому определенному в базе данных моментальному снимку в ка-
талоге будет соответствовать запись в еще одной новой переменной-отношении
(например, SNAPSHOTS). Эта запись должна включать выражение, которое ис-
пользовалось при определении данного моментального снимка, а также сведения
об установленном для него интервале обновления.
Еще одна переменная-отношение в каталоге должна содержать сведения о том,
какие переменные-отношения использовались в определениях каждого из
представлений и моментальных снимков. Обратите внимание, что структура
этой переменной-отношения в определенной степени подобна структуре пере-
менной-отношения PART_STRUCTURE (см. рис. 4.6 в главе 4): как одна деталь
(или узел) может включать в себя другую, так и некоторое представление (или
моментальный снимок) может быть определено в терминах других представ-
лений (или снимков). Поэтому проблемы, обсуждавшиеся в ответе к упр. 7.7 в
главе 7, имеют отношение и к данному случаю.
9.10. Да! Но отметим следующее. Предположим, что переменная-отношение S с данными
о поставщиках заменена выборками SA и SB, где переменная-отношение SA содержит
данные о поставщиках из Лондона, а переменная-отношение SB — данные о постав-
Глава 9. Представления
391
щиках не из Лондона. Теперь представление с именем S можно создать, объединив
переменные-отношения SA и SB. Если в данном представлении попытаться для по-
ставщика из Лондона заменить название города каким-либо другим названием либо
для поставщика не из Лондона попытаться указать, что поставщик находится в Лон-
доне, то при реализации запроса операция UPDATE будет преобразована в операцию
DELETE для одной переменной-отношения и в операцию INSERT — для другой. Изло-
женные в этой главе правила работают в данном случае корректно, так как операция
UPDATE определена как пара операций DELETE-INSERT. Однако было сделано неявное
предположение, что для обеспечения большей эффективности в практической реали-
зации может использоваться единственная операция UPDATE. Данный пример показы-
вает, что преобразование операции UPDATE для представлений в операцию UPDATE для
исходных базовых переменных-отношений не всегда дает правильный результат.
Фактически поиск случаев, когда названное преобразование работает корректно,
можно отнести к задачам оптимизации.
9.11. Вариант а — да; вариант б — да.
9.12. Операции INSERT и DELETE всегда будут противоположными, если база данных
спроектирована в соответствии с принципом ортогонального проектирования
(раздел 12.6 главы 12) и если СУБД соответствующим образом поддерживает ра-
боту с предикатами переменных-отношений. Но если данные условия не выполня-
ются, возможно, что эти операции не будут взаимно противоположными. Напри-
мер, если А и В — различные базовые переменные-отношения, вставка кортежа t в
пересечение V = A INTERSECT В может привести к вставке кортежа t только в пе-
ременную-отношение А (если этот кортеж уже присутствует в переменной-
отношении В). Далее, удаление кортежа t из представления V приведет к тому, что
кортеж будет удален и из переменной-отношения А, и из переменной-отношения В.
(С другой стороны, удаление кортежа t и его последующая повторная вставка все-
гда гарантируют сохранение статус-кво.) Однако обратите внимание на то, что по-
добная асимметрия может возникнуть только тогда, когда кортеж t удовлетворяет
предикату переменной-отношения А, но до начала операции еще не представлен в
этой переменной-отношении.
9.13. Ниже изложены некоторые комментарии. Прежде всего, отметим, что процесс за-
мены выполняется в несколько этапов. (Эта последовательность операций будет
усовершенствована ниже.)
/* Определение новых базовых переменных-отношений */
VAR SNC BASE RELATION
{ S# Sfl, SNAME SNAME, CITY CHAR }
PRIMARY KEY { S# } ;
VAR ST BASE RELATION
{ S# Sfl, STATUS INTEGER }
PRIMARY KEY { S# } ;
/* Копирование данных в новые базовые переменные-отношения */
INSERT INTO SNC S { Sfl, SNAME, CITY } ;
INSERT INTO ST S { Sfl, STATUS } ;
392
Часть IL Реляционная модель
/* Уничтожение исходной переменной-отношения */
DROP VAR S ;
Теперь можно создать требуемое представление.
VAR S VIEW
SNC JOIN ST ;
Заметим, что каждый из атрибутов S# (в переменных-отношениях SNC и ST) можно
рассматривать как внешние ключи, ссылающиеся друг на друга. Фактически мы
имеем строгое отношение “один к одному” между кортежами переменных-
отношений SNC и ST. Это позволяет перейти на уровень сложности “один к одно-
му”, подробно обсуждавшийся в [13.7].
Отметим также, что нужно что-то предпринять относительно внешнего ключа S# в пе-
ременной-отношении SP. Этот внешний ключ ссылается на старую базовую перемен-
ную-отношение S. Хорошо, если бы можно было просто перенаправить внешний ключ
на представление S. Если этого сделать нельзя (а этого нельзя делать в большинстве со-
временных продуктов), то в базе данных лучше создать еще одну проекцию базовой
переменной-отношения S. Соответствующее определение приведено ниже.
VAR SS BASE RELATION .
{ S# S# } PRIMARY KEY { S# } ;
INSERT INTO SS S { S# } ;
(Фактически именно этот проект рекомендуется использовать в [8.10], однако по
совсем другим причинам.) Теперь определение представления S можно изменить
следующим образом.
VAR S VIEW
SS JOIN SNC JOIN ST ;
Добавим также в определения переменных-отношений SNC и ST определения
внешнего ключа.
FOREIGN KEY { S# } REFERENCES SS
ON DELETE CASCADE
ON UPDATE CASCADE
И наконец так изменим спецификацию внешнего ключа {S#} в переменной-
отношении SP, чтобы этот ключ ссылался не на переменную-отношение S, а на пе-
ременную-отношение SS.
Замечание. Идея позволить внешним ключам ссылаться на представления вместо
базовых переменных-отношений требует более глубокого изучения.
9.14. Что касается п. а данного упражнения, то ниже приведен пример операции выбор-
ки из представления, которая, определенно, завершится ошибкой в некоторых про-
граммных продуктах, существовавших на момент написания книги. Рассмотрим
следующее SQL-определение представления (пример 3 из раздела 9.6).
Глава 9. Представления
393
CREATE VIEW PQ AS
SELECT SP.P#, SUM (SP.QTY ) AS TOTQTY
FROM SP
GROUP BY SP.P# ;
Проанализируем результат попытки выполнить следующий запрос.
SELECT AVG ( PQ.TOTQTY ) AS PT
FROM PQ ;
Если следовать обсуждавшейся в данной главе процедуре простой подстановки
(т.е. попытаться заменить все ссылки на имя представления выражением, которое
это представление определяет), то получим следующее.
SELECT AVG ( SUM ( SP.QTY ) ) AS PT
FROM SP
GROUP BY SP.P#;
Однако этот оператор SELECT некорректен, поскольку (как отмечалось при обсуж-
дении примера 7.7.7 в главе 7) язык SQL не допускает, чтобы обобщающие опера-
торы были вложены подобным образом.
Вот еще один пример запроса к тому же представлению PQ, который также вызовет
ошибку в некоторых продуктах и по той же причине.
SELECT PQ.P#
FROM PQ
WHERE PQ.TOTQTY >500 ;
Именно в связи с затруднениями, продемонстрированными в приведенных выше
примерах, некоторые программные продукты (в частности, СУБД DB2 фирмы IBM)
иногда овеществляют представление (вместо использования обычного в этих случаях
процесса подстановки) и после этого выполняют запрос в уже овеществленной вер-
сии представления. Этот прием, конечно, всегда дает правильные результаты, но су-
щественно снижает производительность. Кроме того, в случае СУБД DB2 для неко-
торых типов представлений все еще существуют отдельные операции выборки, кото-
рые не срабатывают, т.е. в СУБД DB2 либо овеществление используется не во всех
случаях, когда подстановка не срабатывает, либо возникают ситуации, когда система
затрудняется точно сказать, сработает ли процедура подстановки. Например, второй
из двух приведенных выше примеров завершался в СУБД DB2 ошибкой (на время
написания книги). См. [4.20], где этот вопрос освещен подробнее.
9.15. Сначала приведем определение проекта варианта б в терминах проекта варианта а.
VAR SSP VIEW
S JOIN SP ;
VAR XSS VIEW
S MINUS ( S JOIN SP ) { S#, SNAME, STATUS, CITY } ;
Теперь приведем определение проекта варианта а в терминах проекта варианта б.
VAR S VIEW
XSS UNION SSP { S#, SNAME, STATUS, CITY } ;
394
Часть IL Реляционная модель
VAR SP VIEW
SSP { Sfl, P#, QTY } ;
Для двух проектов были бы уместны следующие ограничения целостности базы
данных.
CONSTRAINT DESIGN_A
IS_EMPTY ( SP { S# } MINUS S { S# } ) ;
CONSTRAINT DESIGN_B
IS_EMPTY ( SSP { S# } INTERSECT XSS { S# } ) ;
(Обратите внимание, что ограничение DESIGN_A здесь иллюстрирует иной способ
формулировки ссылочного ограничения.)
Проект варианта а, очевидно, лучший по причинам, которые подробно объясняют-
ся в главе 11.
9.16. Приведенные ниже ответы пронумерованы как 9.16.И, где п— номер исходного
упражнения.
9.16.2. CREATE VIEW NON_COLOCATED
AS SELECT S.S#, P.P#
FROM S, P
WHERE S.CITY <> P.CITY ;
9.16.3. CREATE VIEW LONDON_SUPPLIER
AS SELECT S.S#, S.SNAME, S.STATUS
FROM S
WHERE S.CITY = 'London' ;
9.16.4. CREATE VIEW SP
AS SELECT SPJ.S#, SPJ.P#, SUM ( SPJ. QTY ) AS QTY
FROM SPJ
GROUP BY SPJ.S#, SPJ.P# ;
9.16.5. CREATE VIEW JC
AS SELECT J.J#, J.CITY
FROM J
WHERE J.J# IN ( ! SELECT SPJ.J#
FROM SPJ
WHERE SPJ.S# = 'SI
AND J.J# IN | [ SELECT SPJ.J#
FROM SPJ
WHERE SPJ.P = 'Pl'
Глава 9. Представления
395
Часть III
Проектирование
базы данных
В этой части книги речь пойдет о проектировании базы данных, точнее — о проектиро-
вании реляционной базы данных. В общем эта задача формулируется следующим образом:
выбрать подходящую логическую структуру для заданного массива данных, которые тре-
буется поместить в базу данных. Иначе говоря, нужно решить вопрос, какие необходимы
базовые переменные-отношения и какой набор атрибутов они должны включать. Совер-
шенно очевидно, что решение этой задачи имеет большое практическое значение.
Прежде чем приступить к подробному изложению данной темы, сделаем несколько
предварительных замечаний.
Следует заметить, что речь здесь пойдет о логическом (или концептуальном) про-
ектировании, а не о разработке физического проекта. Это вовсе не значит, что фи-
зическое проектирование не имеет большого значения. Наоборот, создание физи-
ческого проекта играет очень важную роль. Тем не менее необходимо сделать
следующие оговорки.
а) Физическое проектирование может рассматриваться как отдельный последую-
щий этап. Иначе говоря, для “правильного” проектирования базы данных преж-
де всего необходимо создать ее приемлемый логический (т.е. реляционный)
проект. И лишь затем как отдельный этап разработки выполнить отображение
этого логического проекта на определенные физические структуры, поддержи-
ваемые конкретной СУБД. (Иначе говоря, как уже отмечалось в главе 2, физи-
ческий проект создается на базе логического и никак иначе.)
б) Физическое проектирование по определению является зависимым от специфи-
ки конкретной целевой СУБД. Однако эта тема выходит за рамки учебника об-
щего плана, к которым следует отнести настоящую книгу. Логический макет,
наоборот, совершенно независим от СУБД, и для его реализации могут исполь-
зоваться некоторые строгие теоретические принципы. Безусловно, именно эти
принципы и должны описываться в книге подобного толка.
К сожалению, мы живем в несовершенном мире и на практике часто случается так,
что решения, принятые в процессе физической реализации проекта, могут оказывать су-
щественное обратное влияние на его логический уровень. (Если говорить точнее, то это
имеет место, в основном, из-за того (как уже несколько раз отмечалось в этой книге), что
в современных СУБД обычно поддерживаются только относительно простые средства
397
отображения между логическим и физическим уровнями.) Иначе говоря, для достижения
компромисса может потребоваться выполнение нескольких итераций цикла “логическое
проектирование— физическое проектирование”. Тем не менее изложение материала в
этой части ведется исходя из того, что предварительно необходимо создать логический
проект без учета особенностей его будущей физической реализации (например, без учета
требований к определенному уровню производительности). Таким образом, материал
этой части книги, в основном, нацелен на решение задачи предварительного создания
логического проекта базы данных.
Хотя, как отмечалось ранее, речь пойдет, главным образом, о проекте реляцион-
ной системы, представленные здесь идеи в равной степени относятся и к нереля-
ционным базам данных. Иначе говоря, мы считаем, что правильный способ созда-
ния проекта нереляционной системы состоит в предварительной разработке ее
корректного реляционного проекта с его последующим отображением (в виде от-
дельного этапа) на любые нереляционные структуры (например, иерархии), под-
держиваемые в целевой СУБД.
После всего сказанного следует подчеркнуть, что проектирование базы данных —
это скорее искусство, чем наука. Конечно, здесь снова следует повторить, что су-
ществуют некоторые научные принципы такого проектирования, которые будут
изложены в следующих четырех главах. Однако при проектировании базы данных
возникает множество других проблем, которые не всегда можно решить, руково-
дствуясь этими принципами. В результате теоретики и практики в области созда-
ния баз данных разработали множество методологий1 проектирования. Среди них
есть как достаточно точные и строгие, так и не относящиеся к таковым. Однако
все они в той или иной степени специализированы и предназначены для решения
именно той проблемы, которая считалась неразрешимой на момент создания кон-
кретной методики. Иными словами, они предназначались для поиска такого вари-
анта логического проекта, который был бы, бесспорно, лучшим в данной
ситуации. Поскольку все эти методологии являются в большей или меньшей сте-
пени специализированными, существует мало объективных критериев для пред-
почтения одной из них. Все же, несмотря на это в главе 13 будет описан один ши-
рокоизвестный подход, менее специализированный, чем другие. Там же вы кратко
ознакомитесь и с другими подходами, получившими коммерческую поддержку.
Следует отметить некоторые допущения, используемые в дальнейшем изложении.
а) Проектирование базы данных заключается не только в создании правильной
структуры данных. Другой и, вероятно, более важной задачей является обеспе-
чение целостности данных. Это замечание будет неоднократно повторено и
усилено в тексте последующих глав.
б) Далее в большинстве случаев проектирование рассматривается независимо от
приложения. Иначе говоря, интерес представляют сами данные, а не то, как они
будут использоваться. Независимость от приложения в этом смысле желательна
1 Термин “методология” изначально означал изучение методов, но со временем стал исполь-
зоваться и для обозначения “системы методов и правил, которые применяются для исследова-
ний или выполнения работы в некоторой области науки или искусства” (см. Chambers Twentieth
Century Dictionary/
398
Часть III. Проектирование базы данных
по той простой причине, что в момент проектирования базы данных обычно еще
неизвестны все возможные способы использования ее данных. Таким образом,
необходимо, чтобы созданный проект был стабильным, т.е. оставался работоспо-
собным даже при возникновении в приложениях новых (т.е. неизвестных на мо-
мент создания исходного макета) требований к данным. Следуя этим допущениям
(и используя терминологию из главы 2), можно сказать, что в этой части книги
обсуждается создание концептуальной схемы, т.е. абстрактного логического ма-
кета, не зависящего от аппаратного обеспечения, операционной системы, целевой
СУБД, языка программирования, пользователей и т.д. В частности, как указыва-
лось ранее, здесь нас не интересуют компромиссные решения, принимаемые, на-
пример, в целях достижения требуемой производительности.
Как отмечалось выше, задача проектирования базы данных заключается в том, что-
бы решить, какие базовые переменные-отношения и с каким набором атрибутов
следует использовать. Фактически для этого также необходимо выяснить, какие сле-
дует использовать домены или типы. На момент создания книги этой теме было по-
священо совсем немного публикаций, поэтому освещение данного вопроса будет
очень кратким (исключениями являются лишь публикации [13.11], [13.39]).
Данная часть имеет следующую структуру. В главе 10 описаны некоторые теоретиче-
ские основы, а в главах И и 12 — основные идеи дальнейшей нормализации, построен-
ные на этих теоретических принципах и позволяющие придать смысл неформальным ут-
верждениям о преимуществах того или иного проекта. Затем в главе 13 рассматривается
семантическое моделирование, в частности описываются концепции построения модели
“сущность/связь” (или ER-модели) и демонстрируется, как их можно использовать на
практике для нисходящего проектирования систем (начиная с сущностей реального мира
и заканчивая формальным реляционным проектом базы данных).
399
Глава 10
Функциональные
зависимости
10.1. Введение
В этой главе речь пойдет о концепции функциональной зависимости, которая если
“не совсем фундаментальна, то очень близка к таковой” [10.7]. Эта концепция лежит в
основе многих обсуждаемых в последующих главах тем, включая, в частности, теорию
проектирования базы данных, описанную в главе 11.
По сути, функциональная зависимость (далее для ее обозначения часто будет исполь-
зоваться аббревиатура ФЗ) является связью типа “многие к одному" между множества-
ми атрибутов внутри данной переменной-отношения. Например, для переменной-
отношения поставок SP существует функциональная зависимость между множествами
атрибутов {S#, P#} и {QTY}. Это означает, что для любого допустимого значения этой пе-
ременной-отношения справедливы следующие правила.
Для любой заданной пары значений атрибутов S# и P# существует только одно со-
ответствующее им значение атрибута QTY.
Многие разные пары значений атрибутов S# и P# могут иметь одно и то же соот-
ветствующее им значение атрибута QTY (в общем случае).
Обратите внимание, что в показанном на рис. 3.8 примере значения переменной-
отношения SP удовлетворяют этим правилам.
В разделе 10.2 этой главы концепция функциональной зависимости определяется бо-
лее точно, с разделением функциональных зависимостей на выполняемые лишь в неко-
торых частных случаях и выполняемые всегда. Как говорилось выше, функциональные
зависимости представляют собой основу для применения научного подхода к решению
нескольких практических задач, поскольку обладают богатым набором интересных фор-
мальных свойств, позволяющих формально и строго решить многие проблемы. Ниже, в
разделах 10.3-10.6, будут подробно описаны некоторые из этих формальных свойств и
даны объяснения по поводу их практического применения. В конце главы, в разде-
ле 10.7, представлено краткое резюме.
Замечание. При первом чтении этой главы многие разделы можно пропустить,
поскольку большая часть материала, необходимого для понимания проводимого в
последующих главах обсуждения, содержится в разделах 10.2 и 10.3. Поэтому все
остальные разделы можно лишь просмотреть, а затем вновь вернуться к ним, озна-
комившись со остальными тремя главами этой части.
400
Часть III. Проектирование базы данных
Небольшое замечание в отношении используемой терминологии. В англоязычной
литературе одновременно употребляются два термина: functional dependence и
functional dependency. Согласно нормам использования английского языка термин
“dependence” следовало бы применять для обозначения самой функциональной зави-
симости, а термин “dependency” — для обозначения зависимых объектов. Однако
термин “функциональная зависимость” часто приходится применять во множествен-
ном числе, а в таких случаях термин “dependencies” кажется более удобным для
произношения, чем “dependences”. Именно это и определяет смешанное использова-
ние обоих терминов.
10.2. Основные определения
Для демонстрации основных идей данного раздела используется несколько изменен-
ная версия переменной-отношения поставок, которая в дополнение к обычным атрибу-
там Sfl, P# и QTY будет содержать также атрибут CITY, представляющий город соответст-
вующего поставщика. Во избежание путаницы далее эту измененную переменную-
отношение мы будем называть SCP. Она представлена на рис. 10.1 в виде таблицы.
S# CITY P# QTY
S1 London Pl 100
S1 London P2 100
S2 Paris Pl 200
S2 Paris P2 200
S3 Paris P2 300
S4 London P2 400
S4 London P4 400
S4 London P5 400
Рис. 10.1. Пример значения переменной-отношения SCP
Следует четко различать а) значение переменной-отношения в определенный момент;
б) набор всех возможных значений, которые переменная-отношение может принимать в
различные моменты. Сначала дадим определение концепции функциональной зависимо-
сти для п. а, а затем — для п. б.
Пусть г является отношением, а X и Y — произвольными подмножествами множе-
ства атрибутов отношения г. Тогда Y функционально зависимо от X, что в сим-
волическом виде записывается как
X —» Y
(читается либо как “X функционально определяет Y”, либо как “X стрелка Y”) то-
гда и только тогда, когда каждое значение множества X отношения г связано в
точности с одним значением множества Y отношения г. Иначе говоря, если два
кортежа отношения г совпадают по значению X, они совпадают и по значению Y.
Глава 10. Функциональные зависимости
401
Например, отношение SCP (см. рис. 10.1) удовлетворяет требованиям для приведен-
ной ниже функциональной зависимости, поскольку все кортежи отношения SCP с одина-
ковыми значениями атрибута S# имеют одно и то же значение атрибута CITY.
{ S# } -> { CITY }
На самом деле это отношение удовлетворяет требованиям сразу нескольких функцио-
нальных зависимостей.
{ S#, P# } —> { QTY }
{ S#, P# } —> { CITY }
{ S#, P# } -> { CITY, QTY }
{ S#, P# } -> { S# }
{ S#, P# } -> { S#, P#, CITY, QTY }
{ S# } —» { QTY }
{ QTY } -> { S# }
Упражнение. Проверьте правильность этого утверждения.
Левая и правая части символической записи функциональной зависимости ино-
гда называются детерминантом и зависимой частью соответственно. Как гово-
рится в определении, детерминант и зависимая часть являются множествами ат-
рибутов. Когда множество содержит только один атрибут, оно называется одно-
элементным множеством, скобки опускаются и символическая запись принимает
следующий вид.
S# -> CITY
Как уже было замечено, эти функциональные зависимости относятся к п. а, т.е. к от-
дельным значениям переменных-отношений. Однако при рассмотрении самих перемен-
ных-отношений, в частности базовых переменных-отношений, интерес представляют не
столько функциональные зависимости в их существующих на некоторый момент кон-
кретных значениях, сколько функциональные зависимости, выполняющиеся для всех
возможных значений данной переменной-отношения. Например, в случае переменной-
отношения SCP функциональная зависимость
S# -> CITY
выполняется для всех возможных значений переменной-отношения SCP, поскольку в лю-
бой момент одному поставщику соответствует в точности один город. По этой причине
любые два кортежа переменной-отношения SCP в один и тот же момент и с одним и тем
же номером поставщика должны соответствовать одному и тому же городу. Практически
утверждение, что данная функциональная зависимость выполняется “всегда” (т.е. для
всех возможных значений SCP), является ограничением целостности для переменной-
отношения SCP, поскольку при этом накладываются определенные ограничения на все ее
допустимые значения. Вот формулировка этого ограничения, которая выполнена с ис-
пользованием синтаксиса, введенного в главе 10.
CONSTRAINT S#_CITY_FD
COUNT ( SCP { S# } ) = COUNT ( SCP { S#, CITY } ) ;
402
Часть III. Проектирование базы данных
Выражение S# —» CITY может расцениваться как сокращенный способ представления
этой более длинной формулировки.
Ниже приведено определение концепции функциональной зависимости для п. б
(расширения определения, данного для п. а, отмечены полужирным шрифтом).
Пусть R является переменной-отношением, а X и Y — произвольными подмноже-
ствами множества атрибутов переменной-отношения R. Тогда Y функционально
зависимо от X, что в символическом виде записывается как
X —> Y
(и читается либо как “X функционально определяет Y”, либо как “X стрелка Y”) то-
гда и только тогда, когда для любого допустимого значения переменной-
отношения R каждое значение множества X отношения R связано в точности с од-
ним значением множества Y отношения R. Иначе говоря, для любого допустимо-
го значения переменной-отношения R, если два кортежа переменной-отношения
R совпадают по значению X, они также совпадают и по значению Y.
Следовательно, далее термин “функциональная зависимость” будет использо-
ваться в последнем безотносительном ко времени смысле (за исключением особо
оговоренных случаев).
Ниже перечислено несколько безотносительных ко времени функциональных зави-
симостей, выполняющихся для переменной-отношения SCP.
{ S#, P# } —> QTY
{ S#, P# } —> CITY
{ S#, P# } —> { CITY, QTY }
{ S#, p# } -> s#
{ S#, P# } -» { S#, P#, CITY, QTY }
{ S# } -> CITY
Обратите внимание, в частности, на функциональные зависимости, которые выпол-
няются для отношения, представленного на рис. 10.1, но не выполняются “всегда” для
переменной-отношения SCP.
S# -> QTY
QTY -> S#
Иначе говоря, такое утверждение, как “число деталей для каждой поставки дан-
ного поставщика одинаково”, истинно для конкретных значений, присутствующих в
отношении на рис. 10.1, но ложно для всех возможных допустимых значений пере-
менной-отношения SCP.
Следует отметить, что если X является потенциальным ключом переменной-
отношения R, то все атрибуты Y переменной-отношения R должны обязательно быть
функционально зависимы от X (этот факт упоминается в разделе 8.8 и непосредственно
следует из определения потенциального ключа). Аналогично в переменной-отношении
деталей Р необходимо, чтобы всегда выполнялась следующая зависимость.
P# —> { Р#, PNAME, COLOR, WEIGHT, CITY }
Глава 10. Функциональные зависимости
403
Действительно, если переменная-отношение R удовлетворяет функциональной
зависимости А —» В и Ане является потенциальным ключом1, то R будет характери-
зоваться некоторой избыточностью. Например, если обратиться к переменной-
отношению SCP, наличие в ней функциональной зависимости S# —» CITY приведет к
тому, что сведения о месте расположения поставщика в определенном городе по-
вторятся много раз (это хорошо видно на рис. 10.1). Подробнее данный вопрос об-
суждается в следующей главе.
Теперь, даже если ограничиться рассмотрением функциональных зависимостей, ко-
торые имеют место в любой момент, полный набор функциональных зависимостей, вы-
полняющихся для всех допустимых значений заданной переменной-отношения, может
быть все еще очень большим, что можно видеть на примере переменной-отношения SCP.
(Упражнение. Попробуйте записать полное множество функциональных зависимостей,
существующих в переменной-отношении SCP.) Большая часть оставшегося в этой главе
материала посвящена поискам методов сокращения обширного множества функцио-
нальных зависимостей до некоторых допустимых размеров.
Почему эта цель столь важна? Как уже отмечалось, одна из причин состоит в том,
что функциональные зависимости являются ограничениями целостности, поэтому при
каждом обновлении данных в базе СУБД вынуждена будет проверять соблюдение всех
этих ограничений. Следовательно, для каждого заданного множества функциональных
зависимостей S желательно найти такое множество Т, которое (в идеальной ситуации)
было бы существенно меньше множества S и при этом каждая функциональная зави-
симость в множестве S могла бы быть заменена функциональной зависимостью из
множества Т. Если бы такое множество Т было найдено, то СУБД достаточно было бы
контролировать выполнение функциональных зависимостей из множества Т, что авто-
матически подразумевало бы соблюдение всех функциональных зависимостей из мно-
жества S. Именно поэтому задача поиска подходящего множества Т представляет
большой практический интерес.
10.3. Тривиальные и нетривиальные
зависимости
Замечание. Далее в этой главе выражение “функциональная зависимость” будет
иногда для краткости заменяться слово.м “зависимость”, а “функционально зависим
от ” — словами “функционально определяется как” и т.п.
Очевидным .способом сокращения существующего набора функциональных зависи-
мостей является исключение из него тривиальных зависимостей. Зависимость
называется тривиальной, если она не может не выполняться. В качестве примера приве-
дем тривиальную функциональную зависимость, существующую в переменной-
отношении SCP, которая обсуждалась в предыдущем разделе.
{ S#, P# } —> S#
1 Эта функциональная зависимость не является тривиальной (раздел 10.3), причем А не явля-
ется суперключом (раздел 10.5), a R содержит по крайней мере два кортежа.
404
Часть III. Проектирование базы данных
Действительно, функциональная зависимость является тривиальной тогда и только
тогда, когда правая часть ее символической записи является подмножеством (необя-
зательно правильным подмножеством) левой части.
Как следует из определения, с практической точки зрения подобные зависимости не
представляют никакого интереса— в отличие от нетривиальных зависимостей, кото-
рые действительно являются реальными ограничениями целостности. Однако в фор-
мальной теории зависимостей необходимо учитывать все зависимости, как тривиальные,
так и нетривиальные.
10.4. Замыкание множества зависимостей
Как упоминалось выше, одни функциональные зависимости могут подразумевать
другие функциональные зависимости. Например, рассмотрим приведенную ниже за-
висимость.
{ S#, P# } —> { CITY, QTY }
Она подразумевает следующие функциональные зависимости.
{ S#, P# } -Э CITY
{ S#, P# } ~> QTY
В качестве более сложного примера можно привести переменную-отношение R с ат-
рибутами А, В и С, для которых выполняются функциональные зависимости А ч В и
В —> С. Нетрудно заметить, что в этом случае также выполняется функциональная зави-
симость А —> С, которая называется транзитивной функциональной зависимостью, т.е.
С зависит от А транзитивно, через В.
Множество всех функциональных зависимостей, которые подразумеваются заданным
множеством функциональных зависимостей S, называется замыканием множества S и
обозначается символом S+. Из приведенного определения следует, что для решения сфор-
мулированной задачи необходимо найти способ вычисления S+ на основе S. Первая попыт-
ка решить эту проблему была предпринята в статье Армстронга (Armstrong) [10.1], в кото-
рой автор предложил набор правил вывода новых функциональных зависимостей на ос-
нове заданных (эти правила также называются аксиомами Армстронга). Правила вывода
могут формулироваться разными способами, и самым простым из них является
следующий. Пусть А, В и С — произвольные подмножества множества атрибутов заданной
переменной-отношения R. Условимся также, что символическая запись АВ означает объе-
динение множеств А и В. Тогда правила вывода определяются следующим образом.
1. Правило рефлексивности: если множество В является подмножеством множества
А, то А —> В.
2. Правило дополнения: если А —> В, то АС —> ВС.
3. Правило транзитивности: если А —> В и В —» С, то А —> С.
Каждое из этих трех правил может быть непосредственно доказано на основе опре-
деления функциональной зависимости (первое из них — просто определение триви-
альной зависимости). Более того, эти правила являются полными в том смысле, что
Глава 10. Функциональные зависимости
405
для заданного множества функциональных зависимостей S минимальный набор функ-
циональных зависимостей, которые подразумевают все зависимости из множества S,
может быть выведен из ФЗ множества S на основе этих правил. Они также являются
исчерпывающими, поскольку никакие дополнительные функциональные зависимо-
сти (т.е. зависимости, которые не подразумеваются функциональными зависимостями
множества S) с их помощью не могут быть выведены. Иначе говоря, эти правила могут
использоваться для получения замыкания S+.
С целью упрощения задачи практического вычисления замыкания S+ из трех приве-
денных выше правил можно вывести несколько дополнительных правил. (Примем, что
D — это другое произвольное подмножество множества атрибутов R.)
4. Правило самоопределения: А —> А.
5. Правило декомпозиции: если А —> ВС, тоА —> ВиА —> С.
6. Правило объединения: если А —» В и А —> С, то А —> ВС.
7. Правило композиции: если А —> В и С —> D, то АС —BD.
Кроме того, Дарвен (Darwen) в своей работе [10.6] доказал следующее правило, кото-
рое называется общей теоремой объединения.
8. Если А—> В и С —» D, то А и (С - В) —> BD (здесь символ “и” обозначает опе-
рацию объединения множеств, а символ — операцию разности множеств).
Название “общая теорема объединения” указывает на то, что некоторые из перечис-
ленных выше правил могут быть выведены как частные случаи этой теоремы [10.6].
Пример. Пусть дана некоторая переменная-отношение R с атрибутами А, В, С, D, Е, F и
следующими функциональными зависимостями.
А —> ВС
В —> Е
CD —> ЕЕ
Обратите внимание, что способ записи несколько изменился (без ущерба для
смысла); например, символы ВС означают множество, состоящее из атрибутов В и С, хотя
ранее они означали объединение В и С, где В и С были множествами атрибутов.
Замечание. Если необходимо, то этому примеру можно придать более конкретный
смысл, а именно: А— личный номер сотрудника, В— номер отдела, С— личный номер
руководителя (начальника) данного сотрудника, D — номер проекта, возглавляемого дан-
ным руководителем (уникальный для каждого отдельно взятого руководителя), Е — назва-
ние отдела, F — доля времени, уделяемая данным руководителем заданному проекту.
Теперь можно показать, что для переменной-отношения R также выполняется функ-
циональная зависимость AD —> F, которая вследствие этого принадлежит к замыканию
заданного множества функциональных зависимостей.
1. А —> ВС (дано)
2. А —» С (следует из п. 1 согласно правилу декомпозиции)
3. AD —» CD (следует из п. 2 согласно правилу дополнения)
406
Часть III. Проектирование базы данных
4. CD
5. AD
6. AD
-> EF
-> EF
-> F
(дано)
(следует из пп. 3 и 4 согласно правилу транзитивности)
(следует из п. 5 согласно правилу декомпозиции) |
10.5. Замыкание множества атрибутов
В принципе, замыкание S+ для заданного множества функциональных зависимостей S
можно вычислить с помощью следующего алгоритма: “Применять правила из предыдущего
раздела до тех пор, пока создание новых функциональных зависимостей не прекратится”. На
практике редко требуется вычислить замыкание само по себе, а потому и только что упомяну-
тый алгоритм вряд ли будет достаточно эффективным. Однако из этого раздела вы узнаете,
как можно вычислить некоторое подмножество замыкания, а именно — то подмножество, ко-
торое состоит из всех функциональных зависимостей с некоторым (указанным) множеством Z
атрибутов, расположенных слева. Точнее говоря, мы покажем, что для заданной переменной-
отношения R, заданного множества атрибутов этой переменной-отношения Z и заданного
множества функциональных зависимостей S, выполняющихся для переменной-отношения R,
можно найти множество всех атрибутов переменной-отношения R, которые функционально
зависимы от Z, т.е. так называемое замыкание Z+ множества Z в пределах S2. Простой алго-
ритм вычисления этого замыкания показан на рис. 10.2.
Упражнение. Докажите правильность этого алгоритма.
CLOSURE[Z,S] := Z ;
do <бесконечно>;
for each FD X -э Y in S /* для каждой ФЗ X —» Y в S */
do ;
if X < CLOSURE[Z,S] /* < = <является подмножеством> */
then CLOSURED,S] := CLOSURE[Z,S] u Y ;
end ;
if CLOSURE[Z,S] <не изменилось в этой итерации>
then leave loop ; /* вычисления завершаются */
end ;
Рис. 10.2. Вычисление замыкания Z .множества Z в пределах S
Пример. Предположим, что дана переменная-отношение R с атрибутами А, В, С, D, Е и
F и следующими функциональными зависимостями.
А —> ВС
Е —> CF
2 Множество функциональных зависимостей с атрибутами Z, расположенными слева, пред-
ставляет собой множество из всех функциональных зависимостей вида Z—>Z', где Z' является
некоторым подмножеством Z . Тогда замыкание S исходного множества S представляет со-
бой объединение всех таких множеств функциональных зависимостей, взятых для всех возмож-
ных множеств атрибутов Z
Глава 10. Функциональные зависимости
407
В —> Е
CD -> EF
Вычислим замыкание {А,В}+ множества атрибутов {А,В}, исходя из заданного мно-
жества функциональных зависимостей.
1. Присвоим замыканию CLOSURE[ Z,S] начальное значение — множество {А,В}.
2. Выполним внутренний цикл четыре раза — по одному разу для каждой заданной
функциональной зависимости. На первой итерации (для зависимости А —> ВС) бу-
дет обнаружено, что левая часть действительно является подмножеством замыка-
ния CLOSURE [ Z, S ]. Таким образом, к результату можно добавить атрибуты В и С.
Замыкание CLOSURE[ Z,S] теперь представляет собой множество {А,В,С}.
3. На второй итерации (для зависимости Е —» CF) обнаруживается, что левая часть не
является подмножеством полученного до этого момента результата, который, та-
ким образом, остается неизменным.
4. На третьей итерации (для зависимости В —> Е) к замыканию CLOSURE[Z,S] будет
добавлено множество Е, которое теперь будет иметь вид {А,В,С,Е}.
5. На четвертой итерации (для зависимости CD —> EF) замыкание CLOSURE[Z,S] оста-
нется неизменным.
6. Далее внутренний цикл выполняется еще четыре раза. На первой итерации резуль-
тат останется прежним, на второй он будет расширен до {A,B,C,E,F}, а на третьей
и четвертой — снова не изменится.
7. Наконец после еще одного четырехкратного прохождения цикла замыкание
CLOSURE [Z,S] останется неизменным и весь процесс завершится с результатом
{А,В}+ = {A,B,C,E,F}. |
Из сказанного выше можно сделать очень важное заключение: для заданного мно-
жества функциональных зависимостей S легко можно указать, будет ли заданная
функциональная зависимость X —» Y следовать из S, поскольку это возможно тогда и
только тогда, когда множество Y является подмножеством замыкания Х+ множества X
для заданного множества S. Иначе говоря, таким образом представлен простой способ
определения, будет ли данная функциональная зависимость X —> Y включена в замы-
кание S+ множества S.
Еще одно важное заключение основано на следующем факте. Прежде всего, вспом-
ним определение понятия суперключ из главы 8. Суперключ переменной-отношения
R — это множество атрибутов переменной-отношения R, которое в виде подмножества
(но необязательно собственного подмножества) содержит по крайней мере один потен-
циальный ключ. Из этого определения прямо следует, что суперключи для данной пере-
менной-отношения R— это такие подмножества К множества атрибутов переменной-
отношения R, что функциональная зависимость К —» А будет истинна для каждого атри-
бута А переменной-отношения R. Другими словами, множество К является суперключом
тогда и только тогда, когда замыкание К+ для множества К в пределах заданного множе-
ства функциональных зависимостей является множеством абсолютно всех атрибутов пе-
ременной-отношения R. (Кроме того, множество К является потенциальным ключом то-
гда и только тогда, когда оно является неприводимым суперключом).
408
Часть III. Проектирование базы данных
10.6. Неприводимые множества зависимостей
Пусть S1 и S2 — два множества функциональных зависимостей. Если любая функ-
циональная зависимость, которая выводится из множества зависимостей S1, также выво-
дится из множества зависимостей S2 (т.е. если замыкание Sl+ является подмножеством
замыкания S2+, то множество S2 называется покрытием для множества S13. Это значит,
что если СУБД обеспечит соблюдение ограничений, представленных зависимостями
множества S2, то автоматически будут соблюдены и все ограничения, устанавливаемые
зависимостями множества S1.
Далее, если множество S2 является покрытием для множества S1, а множество S1
одновременно является покрытием для множества S2 (т.е. если S1+=S2+), то множе-
ства S1 и S2 эквивалентны. Ясно, что если множества S1 и S2 эквивалентны, то со-
блюдение СУБД ограничений, представленных зависимостями множества S2, авто-
матически обеспечит соблюдение ограничений, представленных зависимостями
множества S1, и наоборот.
Множество функциональных зависимостей называется неприводимым4 тогда и
только тогда, когда оно обладает всеми перечисленными ниже свойствами.
1. Правая (зависимая) часть каждой функциональной зависимости из множества S со-
держит только один атрибут (т.е. является одноэлементным множеством).
2. Левая часть (детерминант) каждой функциональной зависимости из множества S
является неприводимой, т.е. ни один атрибут из детерминанта не может быть опу-
щен без изменения замыкания S+ (без конвертирования множества S в некоторое
иное множество, не эквивалентное множеству S). В этом случае функциональная
зависимость называется неприводимой слева.
3. Ни одна функциональная зависимость из множества S не может быть удалена из
множества S без изменения его замыкания S+ (т.е. без конвертирования множества
S в некоторое иное множество, не эквивалентное множеству S).
В отношении пп. 2 и 3 следует отметить, что необязательно иметь точную информа-
цию о составе замыкания S+ для получения ответа на вопрос, изменится ли это замыка-
ние при удалении из исходного множества какой-либо функциональной зависимости. В
качестве примера рассмотрим уже знакомую переменную-отношение деталей Р с функ-
циональными зависимостями, перечисленными ниже.
P# —> PNAME
P# -> COLOR
P# -> WEIGHT
P# -> CITY
Нетрудно заметить, что это множество функциональных зависимостей является не-
приводимым: правая часть каждой зависимости содержит только один атрибут, а левая
часть, очевидно, является неприводимой. Кроме того, ни одна из перечисленных функ-
3 Некоторые авторы используют термин “покрытие” для обозначения эквивалентного
множества.
4 В литературе подобное множество часто называется минимальным.
Глава 10. Функциональные зависимости
409
циональных зависимостей не может быть опущена без изменения замыкания множества
(т.е. без утраты некоторой информации). В противоположность этому приведенные
ниже множества функциональных зависимостей не являются неприводимыми.
1. P# -> { PNAME, COLOR }
P# -> WEIGHT
P# -> CITY
(Правая часть первой ФЗ не является одноэлементным множеством.)
2. ( Р#, PNAME ) -> COLOR
P# -> PNAME
P# -» WEIGHT
P# -> CITY
(Первую ФЗ можно упростить, опустив атрибут PNAME в левой части без изменения
замыкания, т.е. она не является неприводимой слева.)
3. P# -» P#
P# -» PNAME
P# -> COLOR
P# -> WEIGHT
P# —> С1ТУ(Здесь первую ФЗ можно опустить без изменения замыкания.)
Теперь можно сделать утверждение, что для любого множества функциональных
зависимостей существует по крайней мере одно эквивалентное множество, которое
является неприводимым. Это достаточно легко продемонстрировать на следующем
примере. Пусть дано исходное множество зависимостей S. Тогда благодаря правилу
декомпозиции можно без утраты общности предположить, что каждая функциональ-
ная зависимость в этом множестве S имеет одноэлементную правую часть. Далее для
каждой зависимости f из этого множества S следует проверить каждый атрибут А в ле-
вой части зависимости f. Если множество S и множество зависимостей, полученное в
результате устранения атрибута А в левой части зависимости f, эквивалентны, значит,
этот атрибут следует удалить. Затем для каждой оставшейся в множестве S зависимо-
сти^, если множества S и S - f эквивалентны, следует удалить зависимость f из мно-
жества S. Получившееся в результате таких действий множество S является неприво-
димым и эквивалентно исходному множеству S.
Пример. Пусть дана переменная-отношение R с атрибутами А, В, С, D и следующими
функциональными зависимостями.
А —» ВС
ВЧС
А Ч В
АВ —» С
АС —» D
Теперь попробуем найти неприводимое множество функциональных зависимостей,
эквивалентное данному множеству.
410
Часть III. Проектирование базы данных
1. Прежде всего следует переписать заданные ФЗ таким образом, чтобы каждая из
них имела одноэлементную правую часть.
А —» В
А —> С
В —> С
А —> В
АВ —> С
АС -Э D
Нетрудно заметить, что зависимость А —> В записана дважды, так что одну из них
можно удалить.
2. Затем в левой части зависимости АС —> D может быть опущен атрибут С, поскольку
дана зависимость А —> С, из которой по правилу дополнения можно получить зави-
симость А —> АС. Кроме того, дана зависимость АС —> D, из которой по правилу
транзитивности можно получить зависимость А —> D. Таким образом, атрибут С в
левой части исходной зависимости АС —> D является избыточным.
3. Далее можно заметить, что зависимость АВ —> С может быть исключена, поскольку
дана зависимость А —> С, из которой по правилу дополнения можно получить зави-
симость АВ —> СВ, а затем по правилу декомпозиции — зависимость АВ —> С.
4. Наконец зависимость А —> С подразумевается зависимостями А —> В и В —> С, так
что она также может быть отброшена. В результате мы получили неприводимое
множество зависимостей.
А —> В
В —> С
А —» D
Множество функциональных зависимостей I, которое неприводимо и эквивалентно
другому множеству функциональных зависимостей S, называется неприводимым по-
крытием множества S. Таким образом, с тем же успехом в системе вместо исходного
множества функциональных зависимостей S может использоваться его неприводимое
покрытие I (здесь следует повторить, что для вычисления неприводимого эквивалентно-
го покрытия I необязательно вычислять замыкание S+). Однако необходимо отметить,
что для заданного множества функциональных зависимостей не всегда существует уни-
кальное неприводимое покрытие (см. упр. 10.12).
10.7. Резюме
Функциональная зависимость — это связь типа “многие к одному” между двумя
множествами атрибутов заданной переменной-отношения. Для заданной переменной-
отношения R зависимость А —> В (где А и В являются подмножествами множества ат-
рибутов переменной-отношения R) выполняется для переменной-отношения R тогда и
только тогда, когда любые два кортежа переменной-отношения R с одинаковыми зна-
чениями атрибутов множества А имеют одинаковые значения атрибутов множества В.
Глава 10. Функциональные зависимости
411
Каждая переменная-отношение обязательно удовлетворяет некоторым тривиальным
функциональным зависимостям; причем функциональная зависимость тривиальна то-
гда и только тогда, когда ее правая (зависимая) часть является подмножеством ее ле-
вой части (детерминанта).
Одни функциональные зависимости подразумевают другие зависимости. Для дан-
ного множества зависимостей S замыканием S+ называется множество всех функцио-
нальных зависимостей, подразумеваемых зависимостями множества S. Множество S
обязательно является подмножеством собственного замыкания S+. Правила логиче-
ского вывода Армстронга обеспечивают исчерпывающую и полную основу для
вычисления замыкания S+ для заданного множества S, хотя несколько дополнительных
правил вывода (легко выводимых из правил Армстронга) позволяют упростить прак-
тические вычисления.
Для данного подмножества Z множества атрибутов переменной-отношения R и
множества функциональных зависимостей S, которые выполняются в переменной-
отношении R, замыканием Z+ подмножества Z для множества S называется такое
множество всех атрибутов А переменной-отношения R, что функциональная зависи-
мость Z —» А является членом замыкания S+. Если замыкание Z+ состоит из всех атри-
бутов переменной-отношения R, то подмножество Z называют суперключом перемен-
ной-отношения R (а неприводимый суперключ, в свою очередь, называется потенци-
альным ключом). В этой главе было дано описание простого алгоритма для получе-
ния замыкания Z+ на основе Z и S и, следовательно, для определения, является ли дан-
ная зависимость X —> Y членом замыкания S+ (функциональная зависимость X —> Y
является членом замыкания S+ тогда и только тогда, когда множество Y является под-
множеством замыкания Х+).
Два множества функциональных зависимостей S1 и S2 эквивалентны тогда и только
тогда, когда они являются покрытиями друг для друга, т.е. S1+=S2+. Каждое множество
функциональных зависимостей эквивалентно по крайней мере одному неприводимому
множеству. Множество функциональных зависимостей является неприводимым, если,
во-первых, каждая функциональная зависимость этого множества имеет одноэлемент-
ную правую часть; во-вторых, если ни одна функциональная зависимость множества не
может быть устранена без изменения замыкания этого множества; в-третьих, если ни
один атрибут не может быть устранен из левой части любой функциональной зависимо-
сти данного множества без изменения замыкания множества. Если I является неприво-
димым множеством, которое эквивалентно множеству S, то проверка выполнения функ-
циональных зависимостей из множества I автоматически обеспечит выполнение всех
функциональных зависимостей из множества S.
В заключение следует отметить, что многие высказанные выше соображения можно
расширить в отношении ограничений целостности вообще, а не только функциональных
зависимостей. Например, в общем случае следующие допущения являются верными.
Некоторые ограничения целостности являются тривиальными.
Одни ограничения целостности подразумевают другие ограничения.
Множество всех ограничений, подразумеваемых заданным множеством, может
рассматриваться как замыкание этого заданного множества.
412
Часть III Проектирование базы данных
Выяснение вопроса, будет ли некоторое ограничение находиться в некотором за-
мыкании (т.е. будет ли заданное ограничение подразумеваться некоторыми дан-
ными ограничениями), является очень интересной практической задачей.
Не менее интересной практической задачей является поиск неприводимого по-
крытия для некоторого заданного множества установленных ограничений.
Благодаря наличию исчерпывающего и полного множества правил вывода различных
функциональных зависимостей, работать с ними удобнее, чем с ограничениями целост-
ности вообще. В списках рекомендуемой литературы в конце этой и главы 12 даны
ссылки на работы, в которых описывается несколько других типов ограничений (MVD,
JD и IND); для них также существуют подобные наборы правил вывода. Однако в данной
книге другие существующие типы ограничений столь же подробно и полно, как функ-
циональные зависимости, не рассматриваются.
Упражнения
10.1. Пусть R является переменной-отношением степени п. Каково максимальное коли-
чество функциональных зависимостей (как тривиальных, так и нетривиальных),
которые могут выполняться для переменной-отношения R?
10.2. Что конкретно имеется в виду, когда говорится, что правила Армстронга полны и
исчерпывающи?
10.3. Докажите правила рефлексивности, дополнения и транзитивности, используя
только определение функциональной зависимости.
10.4. Докажите, что три предыдущих правила подразумевают правила самоопределения,
деко.мпозиции, объединения и композиции.
10.5. Докажите общую теорему объединения, предложенную Дарвеном. Какие из пере-
численных выше правил потребуются для этого? Какие правила можно вывести в
виде особых случаев этой теоремы?
10.6. Дайте определение для а) замыкания множества функциональных зависимостей;
б) замыкания множества атрибутов для заданного множества функциональных за-
висимостей.
10.7. Перечислите множество всех функциональных зависимостей, которые всегда вы-
полняются для переменной-отношения поставок SP.
10.8. Ниже приведено множество функциональных зависимостей, имеющих место для
переменной-отношения R{A,B,C,D,E,F,G}.
А -э В
ВС -> DE
AEF -> G
Вычислите замыкание {А,С}+ для данного множества функциональных зависимо-
стей. Подразумевается ли зависимость ACF -» DG одной из функциональных зави-
симостей этого множества?
10.9. Что означает понятие эквивалентности двух множеств функциональных зависимо-
стей S1 и S2?
Глава 10. Функциональные зависимости
413
10.10. Что означает понятие неприводимости множества функциональных зависимостей?
10.11. Определите, эквивалентны ли два приведенных ниже множества функциональных
зависимостей, установленных для переменной-отношения R{A,B,C,D,E}.
1. А В
АВ С
D —Э АС
D —» Е
2. А —э ВС D —> АЕ
10.12.Найдите неприводимое покрытие приведенного ниже множества функциональных
зависимостей, заданных для переменной-отношения R{A,B,C,D,E,F}.
АВ —Э С
С Ч А
ВС D
ACD -э В
BE —э С
СЕ FA
CF BD
D —> EF
10.13.В переменной-отношении TIMETABLE определены перечисленные ниже атрибуты.
D День недели (1-5)
Р Период времени в течение дня (1-8)
С Номер класса
Т Имя учителя
L Название урока
Кортеж {D:d, Р:р, С:с, T:t, L:l} является элементом этой переменной-
отношения тогда и только тогда, когда урок 1 проводится учителем t в классе с в
момент {D:d, Р:р}. Предположим, что длительность всех уроков равна одному
периоду времени и, кроме того, каждый урок имеет название, уникальное по отно-
шению ко всем урокам этой недели. Какие функциональные зависимости выпол-
няются для этой переменной-отношения? Какие потенциальные ключи существуют
для этой переменной-отношения?
10.14. Пусть задана переменная-отношение NADDR с атрибутами NAME (уникальное имя),
STREET (улица), CITY (город), STATE (штат) и ZIP (индекс), где каждому индексу со-
ответствует только один город и штат, а каждой улице, городу и штату соответст-
вует только один индекс. Найдите неприводимое множество функциональных за-
висимостей для этой переменной-отношения. Какие потенциальные ключи суще-
ствуют для этой переменной-отношения?
10.15.Пусть дана переменная-отношение R с атрибутами {А,В,С,D,Е,F,G,Н,I,J},
для которой выполняется приведенное ниже множество функциональных зави-
симостей.
ABD -э Е
АВ —> G
В —> F
414
Часть III. Проектирование базы данных
С -» J
CJ -» I
G -» H
Является ли это множество неприводимым? Какие потенциальные ключи сущест-
вуют для данной переменной-отношения?
Список литературы
10.1. Armstrong W. W. Dependency Structures of Data Base Relationships П Proc. IFIP
Congress. — Stockholm, Sweden, 1974.
Здесь впервые изложена формальная теория функциональных зависимостей (т.е.
эта работа является первоисточником аксиом Армстронга), а также приведена точ-
ная характеристика потенциальных ключей.
10.2. Casanova М.А., Fagin R., Papadimitriou C.H. Inclusion Dependencies and Their
Interaction with Functional Dependencies // Proc. 1st ACM SIGACT-SIGMOD
Symposium on Principles of Database Systems. — Los Angeles, Calif, March, 1982.
Зависимости включения (inclusion dependencies — INDs) являются обобщением
концепции ограничений целостности. Например, зависимость включения типа
SP.S# --> S.S#
(здесь символическая запись содержит несколько более длинную стрелку, подчер-
кивающую, что это зависимость другого типа) означает, что множество значений
атрибута SP.S# должно быть подмножеством (необязательно собственным под-
множеством) множества значений атрибута S.S#, Это, конечно, частный случай
ограничения целостности, в общем же случае для зависимости включения не суще-
ствует никаких ограничений на то, что левая часть является внешним ключом, а
правая — потенциальным.
Замечание. Зависимости включения имеют некоторое сходство с функциональны-
ми зависимостями, поскольку оба эти типа зависимостей представляют связь
“многие к одному”. Однако зависимости включения обычно покрывают перемен-
ные-отношения, тогда как функциональные зависимости не покрывают.
Предложено исчерпывающее и полное множество правил вывода для зависимостей
включения, которые могут быть (в несколько нестрогой форме) представлены в
следующем виде.
1. А----> А.
2. Если АВ --> CD, то А---> С и В ---> D.
3. Если А ---> В и В -> С, то А---> С.
10.3. Casey R.G., Delobel С. Decomposition of a Data Base and the Theory of Boolean
Switching Functions // IBM J. R&D. — September, 1973. — 17, № 5.
В работе показано, что для данной переменной-отношения множество функцио-
нальных зависимостей (которые в этой статье называются функциональными
связями) может быть представлено как “булева переключательная функция”.
Кроме того, отмечено, что эта функция в некотором смысле уникальна, посколь-
Глава 10. Функциональные зависимости
415
ку исходные функциональные зависимости могут быть заданы многими совер-
шенно различными (но эквивалентными) способами, каждый из которых в об-
щем приводит к возникновению существенно разных булевых функций, но все
такие функции могут быть сведены к одной той же канонической форме с помо-
щью законов булевой алгебры. Показано, что проблема декомпозиции исходной
переменной-отношения (т.е. декомпозиция без потерь; подробности приводятся
в главе 11) логически эквивалентна хорошо известной в булевой алгебре про-
блеме поиска “покрывающего множества из простых импликантов” для булевой
функции, соответствующей этой переменной-отношению вместе с ее функцио-
нальными зависимостями. Следовательно, исходная проблема может быть пере-
формулирована в эквивалентную проблему в булевой алгебре, а для ее решения
могут применяться хорошо известные методы.
Эта одна из первых работ, посвященных применению теории зависимостей для
широкого круга других дисциплин. Этому также посвящена публикация [10.8] и
несколько работ, упомянутых в списках литературы в главе 12.
10.4. Codd E.F. Further Normalization of the Data Base Relational Model // Data Base
Systems, Courant Computer Science Symposia Series 6. — Englewood Cliffs, N.J.:
Prentice-Hall, 1972.
Впервые представлена концепция функциональной зависимости (не считая бо-
лее раннего упоминания в одном из внутренних документов фирмы IBM). По-
нятие “дальнейшая нормализация” (Further Normalization), приведенное в заго-
ловке, относится к некоторому типу специализированного макета базы
данных, обсуждаемого в главе 11 (назначение этой статьи заключалось в де-
монстрации возможности использования идеи функциональной зависимости
для решения проблем проектирования базы данных). Действительно, функцио-
нальные зависимости представляют собой одну из первых попыток разреше-
ния этой проблемы. Однако идея ФЗ с тех пор доказала свою полезность и для
более широкого практического применения.
10.5. Codd E.F. Normalized Data Base Structure: A Brief Tutorial // Proc. 1971 ACM
SIGFIDET Workshop on Data Description, Access, and Control. — San Diego, Calif.,
November, 1971.
Вводное изложение идей, представленных в [10.4].
10.6. Darwen Н. The Role of Functional Dependence in Query Decomposition 11 C.J. Date and
H. Darwen. Relational Database Writings 1989-1991.— Reading, Mass.:
Addison-Wesley, 1992.
Представлен набор правил наследования для функциональных зависимостей, с по-
мощью которых может быть выведена выполнимость функциональных зависимо-
стей для данной произвольной переменной-отношения на основе выполнимости
этих зависимостей в переменной-отношении (или нескольких переменных-
отношениях), из которой выведена данная переменная-отношение. Выведенное та-
ким образом множество ФЗ может использоваться для определения потенциаль-
ных ключей для некоторой выведенной переменной-отношения. В результате
можно получить правила наследования для потенциальных ключей, кратко упомя-
нутые в главах 8 и 9 как “наиболее желательные”. В статье показано, как эти пра-
вила наследования для функциональных зависимостей и потенциальных ключей
416
Часть III. Проектирование базы данных
могут использоваться для значительного повышения производительности СУБД,
ее функциональности и удобства пользования.
10.7. Darwen Н. ©Observations of a Relational Bigot И Presentation to BCS Special Interest
Group on Format Aspects of Computing Science. — London, UK, December, 1990.
10.8. Fagin R. Functional Dependencies in a Relational Database and Propositional Logic H
IBM J.R&D. — November, 1977. — 21, № 6.
Показано, что аксиомы Армстронга [10.1] строго эквивалентны системе имплика-
ционных утверждений в логике высказываний. Иначе говоря, задается отображе-
ние между функциональными зависимостями и утверждениями в логике высказы-
ваний, а затем показывается, что данная зависимость f является последовательно-
стью заданного множества зависимостей S тогда и только тогда, когда высказыва-
ние, соответствующее f, является логическим следствием множества высказыва-
ний, соответствующих множеству S.
10.9. Lucchesi C.L., Osborn S.L. Candidate Keys for Relations // J. Comp, and Sys.
Sciences. — 1978. — 17, № 2.
Представлен алгоритм поиска всех потенциальных ключей, а также функциональ-
ных зависимостей, выполняющихся для заданной переменной-отношения.
Ответы к некоторым упражнениям
10.1. Функциональная зависимость— это утверждение типа А —> В, где А и В являются
подмножествами множества атрибутов переменной-отношения R. Поскольку мно-
жество из п элементов образует 2П возможных подмножеств, каждое из множеств А
и В может содержать по 2П возможных значений. Следовательно, общее число воз-
можных функциональных зависимостей равно 2_п.
10.5.
1. А —> В (дано)
2. С -) D (дано)
3. А -э В А С (зависимость соединения, 1)
4. С - В —» С - В (самоопределение)
5. А и ( С - В ) -»(ВпС)и(С-В) (композиция, 3, 4)
6. А и ( С - В ) -) С (упрощение, 5)
7. А и ( С • В ) -) D (транзитивность, 6, 2)
8. Au(C-B)-)BuD (композиция, 1,7)
Доказательство завершено. |
Использованные для доказательства правила указаны в скобках. Среди них есть
правила, которые являются особыми случаями теоремы Дарвена: объединение,
транзитивность, композиция и дополнение. Таким же особым случаем теоремы
Дарвена является следующее полезное правило.
Если А —» В и АВ —» С, то А —» С.
Глава 10. Функциональные зависимости
417
10.7 . Ниже приведен полный набор функциональных зависимостей (т.е. замыкание) для
переменной-отношения SP.
{ S#, Р#, QTY } —» { S#, Р#, QTY }
{ S#, Р#, QTY } —> { S#, P# }
{ S#, Р#, QTY } -> { Р#, QTY }
{ S#, Р#, QTY } -> { S#, QTY }
{ S#, Р#, QTY } -» { S# }
{ S#, P#, QTY } —> { P# }
{ S#, Р#, QTY } —> { QTY }
{ S#, Р#, QTY } —> { }
{ S#, P# } -» '{ S#, Р#, QTY }
{ S#, P# } —> { S#, P# }
{ S#, P# } -> { Р#, QTY }
{ S#, P# } —» { S#, QTY }
{ S#, P# } —> { S# }
{ S#, P# } —> { P# }
{ S#, P# } -> { QTY }
{ S#, P# } —э { }
{ Р#, QTY } -> { Р#, QTY }
{ Р#, QTY } -> { P# }
{ P#, QTY } —> { QTY }
{ Р#, QTY } —> { }
{ S#, QTY } -» { S#, QTY }
{ S#, QTY } -> { S# }
{ S#, QTY } -> { QTY }
{ S#, QTY } —> { }
{ S# } -> { S# }
{ S# } -» { }
{ P# } -> { P# }
{ ₽# } -> { }
{ QTY# } -» { QTY# }
{ QTY# } -» { }
{}->{}
10.8 . {А,С}+ = {А, В, С, D, Е}. На вторую часть вопроса следует дать утвердительный ответ.
10.11.Они эквивалентны. Пронумеруем функциональные зависимости из первого множе-
ства следующим образом.
1. А —» В
2. АВ —» С
418
Часть III. Проектирование базы данных
3. D -ч AC
4. D -ч E
Тогда строка 3 может быть заменена следующей строкой.
3. D ч А и D ч С
Затем с помощью строки 1 можно придать строке 2 такой вид.
2. А ч С
Но поскольку теперь D ч А и А ч С, по транзитивности это подразумевает
D -ч С, а в результате для строки 3 можно получить следующее выражение.
3. D -) А
Таким образом, первое множество функциональных зависимостей эквивалентно
следующему неприводимому множеству.
А ч В
Ач С
D ч А
D -ч Е
Приведенное ниже второе множество функциональных зависимостей, очевидно,
эквивалентно данному неприводимому множеству.
А -ч ВС
D -ч АЕ
Таким образом, эти множества эквивалентны. |
10.12.Прежде всего, следует переписать данное множество так, чтобы каждая функцио-
нальная зависимость имела одноэлементную правую часть.
1. АВ -ч С
2. С ~ч А
3. ВС -ч D
4. ACD -Ч В
5. BE -Ч С
6. СЕ -ч А
7. СЕ -ч F
8. CF —> В
9. CF -ч D
10. D -ч Е
11. D -Ч F
Тогда получаем следующее.
Строка 2 подразумевает строку 6, поэтому строку 6 можно опустить.
Строка 8 подразумевает функциональную зависимость CF -ч ВС (по правилу до-
полнения), которая вместе со строкой 3 подразумевает функциональную зависи-
мость CF -ч D (по правилу транзитивности), так что строку 9 можно опустить.
Глава 10. Функциональные зависимости
419
Строка 8 подразумевает функциональную зависимость ACF —> АВ (по дополне-
нию), а строка 11 — функциональную зависимость ACD —» ACF (по дополнению).
Тогда можно записать, что ACD -ч АВ (по правилу транзитивности) и ACD -ч В
(по правилу декомпозиции). Таким образом, строку 4 можно опустить.
На этом все операции вывода завершаются и множество становится неприводимым.
АВ -ч С
С ч А
ВС -ч D
BE -ч С
СЕ -ч F
CF -ч В
D -ч Е
D -ч F
Вывод можно осуществить иначе.
Строка? подразумевает функциональную зависимость CD -ч ACD (по правилу
композиции), которая со строкой 4 подразумевает функциональную зависимость
CD —> В (по правилу транзитивности), так что строку 4 можно заменить зависи-
мостью CD -ч В.
Строка 2 подразумевает строку 6, так что строку 6 можно опустить (как и прежде).
Строки 2 и 9 подразумевают функциональную зависимость CF -ч AD (по правилу
композиции), которая подразумевает функциональную зависимость CF —» ADC
(по правилу дополнения), которая вместе со строкой 4 подразумевает функцио-
нальную зависимость CF -ч В (по правилу транзитивности). Таким образом,
строку 8 можно опустить.
На этом все операции вывода завершаются и множество становится неприводимым.
АВ -ч С
С —> А
ВС -ч D
CD -ч В
BE -ч С
СЕ -ч F
CF -ч D
D -ч Е
D -ч F
Обратите внимание, что тем самым получено два разных неприводимых покрытия
для исходного множества функциональных зависимостей.
10.13. Потенциальными ключами являются L, DPC и DPT.
10.14. Используя сокращенную запись N, R, С, Т и Z для атрибутов NAME, STREET, CITY, STATE
и ZIP соответственно, можно получить следующие функциональные зависимости.
N —Ч RCT RCT -ч Z Z -Ч СТ
420
Часть III. Проектирование базы данных
Очевидно, что эквивалентным неприводимым множеством является следующее.
N ч R N ч С N -) Т RCT —> Z Z С Z -э Т
Единственным потенциальным ключом является атрибут N.
10.15. Ответ к этому упражнению будет дан не полностью, хотя некоторые рассуждения
здесь все же будут изложены. Во-первых, множество, очевидно, не является не-
приводимым, так как функциональные зависимости С —э J и CJ —э I совместно
подразумевают зависимость С —» I. Во-вторых, очевидным суперключом является
множество {A,B,C,D,G,J} (т.е. множество всех атрибутов, упомянутых в левых
частях заданных функциональных зависимостей). Из этого множества можно ис-
ключить атрибут J, поскольку существует зависимость С -» J, а также исключить
атрибут G, поскольку существует зависимость АВ -» G. Так как ни один из атрибу-
тов А, В, С, D не находится в правой части любой заданной функциональной зави-
симости, множество {А,В,С,D} является потенциальным ключом.
Глава 10. Функциональные зависимости
421
Глава
Дальнейшая нормализация:
формы 1НФ, 2НФ,
ЗНФ и НФБК
11.1. Введение
До сих пор в этой книге в качестве примера рассматривалась база данных поставщи-
ков и деталей с приведенной ниже логической структурой.
S { S#, SNAME, STATUS, CITY }
PRIMARY KEY { S# }
P { P#, PNAME, COLOR, WEIGHT, CITY }
PRIMARY KEY { P# }
SP { S#, P#, QTY }
PRIMARY KEY { S#, P# }
FOREIGN KEY { S# } REFERENCES S
FOREIGN KEY { P# } REFERENCES P
Теперь структура этой базы данных стала нам понятней. Очевидно, что в ней присутст-
вуют три переменные-отношения (S, Р и SP), в которых определены те или иные атрибуты.
Например, атрибут CITY для города поставщика определен в переменной-отношении S, ат-
рибут COLOR для цвета детали — в переменной-отношении Р, атрибут QTY для количества
деталей — в переменной-отношении SP и т.д. Но откуда нам это известно? Кое-что можно
понять, определенным образом изменив макет базы данных. Предположим, например, что
атрибут CITY удален из переменной-отношения поставщиков S и добавлен в переменную-
отношение поставок SP. (Однако интуитивно это действие можно охарактеризовать как
ошибочное, поскольку понятие “город поставщика” очевидным образом связано с постав-
щиками, а не с поставками.) На рис. 11.1 представлен пример содержания переменной-
отношения поставок, измененной подобным образом.
Замечание. Чтобы избежать путаницы, связанной с исходной переменной-
отношением SP, которой мы оперировали ранее, эта измененная переменная-отношение
будет далее обозначаться SCP, как и в главе 10.
На рис. 11.1 легко заметить один недостаток, свойственный организации переменной-
отношения SCP, а именно— ее избыточность. Говоря конкретнее, в каждом кортеже пере-
менной-отношения SCP для поставщика с номером ' S1' содержится информация о том, что
этот поставщик находится в Лондоне; в каждом кортеже переменной-отношения SCP для по-
422
Часть III. Проектирование базы данных
ставщика с номером ' S2' содержится информация о том, что этот поставщик находится в Па-
риже, и т.д. Иначе говоря, сведения о городе, в котором находится конкретный поставщик,
повторяются в отношении столько раз, сколько данный поставщик выполняет поставок. Эта
избыточность, в свою очередь, приводит к некоторым проблемам. Например, после обновле-
ния данных в качестве местонахождения поставщика с номером 'S1' в одном из кортежей
может быть указан Лондон, а в другом — Амстердам1. Таким образом, для создания хороше-
го макета следует придерживаться принципа “по одному факту в одном месте” (т.е. следует
избегать избыточности данных). Предметом нормализации, в сущности, является всего лишь
формализация подобных простых идей, однако это должна быть формализация, которая дей-
ствительно будет иметь большое практическое значение при проектировании базы данных.
S# CITY P# QTY
S1 London Pl 300
S1 London P2 200
S1 London P3 400
S1 London P4 200
S1 London P5 100
S1 London P6 100
S2 Paris Pl 300
S2 Paris P2 400
S3 Paris P2 200
S4 London P2 200
S4 London P4 300
S4 London P5 400
Рис. 11.1. Пример значений данных в переменной-отношении SCP
Конечно, как уже упоминалось в главе 5, отношения в реляционной модели всегда
нормализованы. Можно сказать, что переменная-отношение также нормализована, по-
скольку ее допустимыми значениями являются нормализованные отношения. Следова-
тельно, в контексте реляционной модели переменная-отношение также всегда нормали-
зована. Аналогично можно сказать, что переменные-отношения (и отношения) всегда
находятся в первой нормальной форме, или 1НФ. Иначе говоря, понятия “нормализо-
ванная переменная-отношение” и “переменная-отношение в 1НФ” означают в точности
одно и то же, хотя следует иметь в виду, что понятие “нормализованная переменная-
отношение” может также относиться к нормализации более высоких уровней (обычно
для обозначения третьей нормальной формы, или ЗНФ). Последний вариант использо-
вания этого термина не совсем точен, но достаточно широко распространен. *
/ Далее в этой и последующих главах нужно сделать (достаточно правдоподобное!) предположе-
ние о том, что контроль предикатов переменных-отношений поддерживается не в полном объеме.
Это необходимо, поскольку в противном случае описанные выше проблемы просто не могли бы возник-
нуть (было бы невозможно обновить данные о городе поставщика с номером JS1' только в некото-
рых кортежах). В действительности нормализацию целесообразно понимать следующим образом: она
помогает спроектировать базу данных таким образом, чтобы сделать более логически приемлемыми
операции обновления отдельных кортежей, что в противном случае (т.е. когда макет базы данных не
нормализован) может оказаться затруднительным. Эта цель достигается благодаря тому, что в
полностью нормализованном макете предикаты переменных-отношений имеют более простой вид.
Глава И. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 423
Однако некоторая переменная-отношение может быть нормализованной в указанном
смысле и все еще обладать определенными нежелательными свойствами. Примером мо-
жет служить переменная-отношение SCP, показанная на рис. 1.1. Принципы дальнейшей
нормализации позволяют распознать подобные случаи и привести такие переменные-
отношения к более приемлемой форме. В случае переменной-отношения SCP эти прин-
ципы позволили бы точно установить ее недостатки и указать на необходимость ее раз-
биения на две “более приемлемые” переменные-отношения: одну с заголовком
{S#, CITY} и другую с заголовком {S#, P#, QTY}.
Нормальные формы
Процесс дальнейшей нормализации, который ниже будет упоминаться просто как
нормализация, основывается на концепции нормальных форм. Говорят, что перемен-
ная-отношение находится в определенной нормальной форме, если она удовлетворяет
заданному набору условий. Например, переменная-отношение находится во второй
нормальной форме (или в 2НФ) тогда и только тогда, когда она находится в 1НФ и
удовлетворяет дополнительному условию, приведенному в разделе 11.3.
На рис. 11.2 показано несколько нормальных форм, которые определены к настоящему
времени. Первые три (1НФ, 2НФ и ЗНФ) были определены Коддом (Codd) [10.4]. Как вид-
но из рис. 11.2, все нормализованные переменные-отношения находятся в 1НФ, некоторые
переменные-отношения в 1НФ также находятся в 2НФ и некоторые переменные-
отношения в 2НФ также находятся в ЗНФ. Мотивом введения дополнительных определе-
ний было то, что вторая нормальная форма “более желательна” (в смысле, который будет
разъяснен ниже), чем первая, а третья, в свою очередь, “более желательна”, чем вторая. Та-
ким образом, в общем случае при проектировании базы данных целесообразно использо-
вать переменные-отношения в третьей нормальной форме, а не в первой или второй.
Переменные-отношения в 1НФ (нормализованные)
Переменные-отношения в 2НФ
Переменные-отношения в ЗНФ
Переменные-отношения в НФБК
Переменные-отношения в 4НФ
Переменные-отношения
в 5НФ
Рис. 11.2. Уровни нормализации
В [10.4] также приводится описание процедуры нормализации, с помощью которой
переменная-отношение в некоторой нормальной форме, например в 2НФ, может быть
преобразована в несколько переменных-отношений в другой, более желательной нор-
мальной форме, например в ЗНФ. (В исходном варианте эта процедура определена толь-
ко до третьей формы, но, как будет показано в следующей главе, она может быть после-
довательно расширена вплоть до пятой нормальной формы.) Такую процедуру можно
охарактеризовать как последовательное приведение данного набора переменных-
отношений к некоторой более желательной форме. Следует отметить, что эта процеду-
424
Часть III. Проектирование базы данных
ра обратима, т.е. всегда можно использовать ее результат (например, множество пере-
менных-отношений, находящихся в ЗНФ) для обратного преобразования (в исходную
переменную-отношение, находящуюся в 2НФ). Возможность выполнения обратного
преобразования является весьма важной характеристикой, поскольку это означает, что в
процессе нормализации информация не утрачивается.
Возвращаясь к рассмотрению собственно нормальных форм, заметим, что, как будет
показано в разделе 11.5, оригинальное определение Кодда для ЗНФ [10.4] приводит к не-
которой неадекватности. Переработанное и более точное понятие, данное Бойсом
(Воусе) и Коддом в [11.2], является более строгим в том смысле, что любая переменная-
отношение в ЗНФ по новому определению является таковой и по старому определению,
но не всякая переменная-отношение в ЗНФ по старому определению может являться та-
ковой по новому определению. Для того чтобы эти определения можно было различать,
переменную-отношение в ЗНФ по новому определению обычно называют нормальной
формой Бойса-Кодда — НФБК.
Впоследствии Фейгином (Fagin) в [11.8] была определена новая, четвертая нор-
мальная форма (4НФ), которая стала четвертой по счету, поскольку в момент ее соз-
дания нормальная форма Бойса-Кодда считалась третьей. Совсем недавно Фейгин в
[11.9] дал определение еще одной нормальной формы, которую назвал проектив-
но-соединительной нормальной формой (ПСНФ); ее еще называют пятой нор-
мальной формой, или 5НФ. Как показано на рис. 11.2, некоторые переменные-
отношения в НФБК также находятся в 4НФ и некоторые переменные-отношения в
4НФ также находятся в 5НФ.
Возникает вопрос, нельзя ли продлить эту операцию для получения шестой, седьмой
нормальной форм и так до бесконечности. Пока мы еще не готовы дать подробный ответ
на этот замечательный вопрос. Но мы вернемся к нему в главе 12. Пока следует
заметить, что действительно существуют дополнительные нормальные формы, которые
не показаны на рис. 11.2, однако 5НФ можно рассматривать как “окончательную” нор-
мальную форму в некотором (и очень важном) смысле.
Структура этой главы
Назначение данной главы — предоставить описание концепции дальнейшей норма-
лизации до уровня нормальной формы Бойса-Кодда включительно. Оставшиеся две
формы будут рассмотрены в главе 12. В целом, материал будет излагаться по следующе-
му плану. После несколько затянувшегося введения в разделе 11.2 описывается фунда-
ментальная концепция декомпозиции без потерь и демонстрируется важное значение
понятия функциональной зависимости (ФЗ) в этой концепции. (Действительно, поня-
тие функциональной зависимости является основой выделения трех нормальных форм
Кодда и нормальной формы Бойса-Кодда.) Далее, в разделе 11.3, подробно описываются
три начальные нормальные формы и на примере некоторой переменной-отношения де-
монстрируется, как выполняется нормализация вплоть до достижения ЗНФ. В разде-
ле 11.4 делается небольшое отступление с целью обсуждения вопроса альтернативных
декомпозиций, т.е. проблемы выбора “наилучшей декомпозиции” для конкретной пере-
менной-отношения, если, конечно, такой выбор возможен. В разделе 11.5 обсуждается
НФБК, а в разделе 11.6 рассматриваются особенности работы с атрибутами, принимаю-
щими в качестве значений отношения. И наконец в разделе 11.7 приводится краткое ре-
зюме и дается несколько заключительных замечаний.
Глава И. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 425
Важно отметить, что далее изложение ведется не столь строго, как раньше, и в рас-
суждениях автор, в основном, полагается на интуицию. Подобный подход может быть
оправдан тем, что такие понятия, как “декомпозиция без потерь”, “нормальная форма
Бойса-Кодда” и другие, несмотря на их таинственные и загадочные названия, по сути
весьма просты и общедоступны. Во многих работах, на которые имеются ссылки, этот
материал излагается в более строгой форме.
Кроме того, следует сделать еще два предварительных замечания.
1. Как уже отмечалось, общая идея нормализации заключается в том, что при проек-
тировании базы данных предполагается более целесообразным определять пере-
менные-отношения в “окончательной” нормальной форме (т.е. в пятой). Однако эту
рекомендацию не следует толковать, как обязательное правило, поскольку возмож-
ны (довольно часто) ситуации, когда принципами нормализации приходится пре-
небрегать (об этом упоминается в упр. 11.7). Действительно, здесь необходимо
подчеркнуть, что проектирование базы данных может представлять собой чрезвы-
чайно сложную задачу (по крайне мере, в “достаточно большой базе данных”, по-
скольку макеты “малых” баз данных обычно очень просты). Нормализация значи-
тельно упрощает этот процесс, но не является панацеей. Хотя разработчику проек-
та базы данных рекомендуется знать основные принципы нормализации, это не
значит, что проект обязательно должен быть создан на основе исключительно этих
принципов. В главе 13 обсуждается несколько других аспектов проектирования ба-
зы данных, которые имеют весьма отдаленное отношение к нормализации как та-
ковой или совсем не имеют к ней отношения.
2. Как упоминалось выше, процедура нормализации будет использована в качестве
основы при описании различных нормальных форм. Однако это не значит, что на
практике создание проекта базы данных будет выполняться с помощью этой про-
цедуры. На самом деле, вероятнее всего, для этого будет использована описанная в
главе 13 схема типа “сверху вниз”. Идеи нормализации можно использовать на по-
следующих этапах для проверки того, что полученный в результате проект не на-
рушает случайным образом каких-либо ее принципов. Как бы там ни было, проце-
дура нормализации является удобным способом описания этих принципов. Для уп-
рощения изложения в данной главе будет сделано полезное допущение о том, что
проектирование выполняется с помощью процедуры нормализации.
11.2. Декомпозиция без потерь
и функциональные зависимости
Прежде чем приступить к рассмотрению подробностей процедуры нормализа-
ции, следует обсудить один существенный аспект этой процедуры, а именно —
концепцию декомпозиции без потерь. Как уже упоминалось, процедура нормали-
зации включает разбиение, или декомпозицию, данной переменной-отношения на
другие переменные-отношения, причем декомпозиция должна быть обратимой,
т.е. выполняться без потерь информации. Иначе говоря, интерес представляют
только те операции, которые выполняются без потерь информации. Вопрос о том,
происходит ли утрата информации при декомпозиции, тесно связан с концепцией
функциональной зависимости.
426
Часть III. Проектирование базы данных
В качестве примера рассмотрим уже знакомую переменную-отношение поставщиков
S с заголовком {S#, STATUS, CITY} (для упрощения задачи атрибут SNAME в данном слу-
чае игнорируется). На рис. 11.3 показан пример значений данных в этой переменной-
отношении и указаны два возможных варианта ее декомпозиции: а и б.
Рис. 11.3. Переменная-отношение S и два возможных варианта ее декомпозиции
Внимательно ознакомившись с предложенными вариантами декомпозиции, можно
заметить две особенности.
1. В случае а информация не утрачивается, поскольку переменные-отношения SST и
SC все еще содержат данные о том, что поставщик с номером 'S3' имеет статус 30
и находится в Париже ('Paris'), а поставщик с номером 'S5' имеет статус 30 и
находится в Афинах ('Athens'). Иначе говоря, первая декомпозиция действительно
является декомпозицией без потерь.
2. В случае б, наоборот, некоторая информация утрачивается, поскольку оба поставщи-
ка имеют статус 30, но при этом нельзя сказать, какой из них в каком городе находит-
ся. Иначе говоря, вторая декомпозиция не является декомпозицией без потерь.
Почему же получилось так, что одна декомпозиция была проведена без потери, а
другая — с потерей информации? Прежде всего следует отметить, что процесс, который до
сих пор назывался декомпозицией, на самом деле является операцией проекции, т.е. каж-
дая из показанных на рис. 11.3 переменных-отношений — SST, SC и STC — в действитель-
ности является проекцией исходной переменной-отношения S. Таким образом, оператор
декомпозиции в процедуре нормализации фактически является оператором проекции.
Замечание. Как и в части II этой книги, высказывание вида “SST является проекцией
переменной-отношения S” используется вместо более точного высказывания вида “SST
является переменной-отношением, значение которой в определенное время является
проекцией значения переменной-отношения S, которое она имеет в это же время”. Наде-
емся, что такое сокращение не собьет читателя с толку.
Обратите внимание, что в случае а сохранение информации в полном объеме означа-
ет, что при обратном соединении переменных-отношений SST и SC будет получена ис-
ходная переменная-отношение S. В случае б ситуация противоположная, поскольку при
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК ATL1
обратном соединении переменных-отношений SST и SC исходная переменная-отношение
S получена не будет, а это значит, что некоторая информация будет утрачена2. Иначе го-
воря, “обратимость” означает, что исходная переменная-отношение равна соединению ее
проекций. Если оператором декомпозиции в процедуре нормализации является операция
проекции, то обратной операцией должна быть операция соединения.
Исходя из сказанного выше, можно задать следующий вопрос. Пусть R1 и R2 явля-
ются проекциями некоторой переменной-отношения R, содержащими все атрибуты пе-
ременной-отношения R. Какие условия должны быть соблюдены для того, чтобы при
обратном соединении проекций R1 и R2 гарантировать получение исходной перемен-
ной-отношения R? Цменно для получения ответа на этот вопрос необходимо обратить-
ся к функциональным зависимостям. В рассматриваемом примере переменная-
отношение S удовлетворяет представленному ни>це неприводимому множеству функ-
циональных зависимостей.
S# -> STATUS
S# -> CITY
При условии, что данная переменная-отношение удовлетворяет приведенным функ-
циональным зависимостям, можно предположить, что переменная-отношение S равна
соединению ее проекций {S#, STATUS} и {S#, CITY}. И это действительно так, что под-
тверждается теоремой Хита (Heath) [11.4].
Теорема Хита. Пусть R{A, В, С} является переменной-отношением, где А, В и
С — множества атрибутов этой переменной-отношения. Если R удовлетворяет
функциональной зависимости А —> В, то R равна соединению ее проекций
{А, В} и{А, С}.
Если принять, что А— это атрибут S#, В— это атрибут STATUS, а С— это атрибут
CITY, то данная теорема подтверждает, как отмечалось выше, что переменная-отношение
S может быть разбита с помощью операции декомпозиции на проекции {S#, STATUS} и
{S#, CITY} без потери информации.
В то же время уже известно, что переменная-отношение S не может быть разбита без
потери информации на проекции {S#, STATUS} и {STATUS, CITY}. Теорема Хита не дает
объяснения, почему так происходит3. Однако интуитивно можно предположить, что при
такой декомпозиции утрачивается одна из функциональных зависимостей, т.е. зависи-
мость S# —» STATUS будет присутствовать (благодаря проекции {S#, STATUS}), а зави-
симость S# —> CITY будет утрачена.
2 Точнее, в исходной переменной-отношении S вместе со всеми кортежами будут содер-
жаться "ложные” кортежи, поскольку при обратной операции никогда нельзя получить пере-
менную-отношение, которая была бы меньше исходной переменной-отношения S {Упражнение
Попробуйте доказать это утверждение) Поскольку не существует общего метода различения
ложных и подлинных кортежей, информация в этом случае действительно будет утеряна
3 Дело в том, что она формулируется в выражениях "если , то ”, а не "тогда и только тогда,
когда ” Об этом также идет речь в упр 111 Более строгая формулировка теоремы Хита будет
представлена в следующей главе (в разделе 12 2)
428
Часть III. Проектирование базы данных
Еще о функциональных зависимостях
В завершение перечислим некоторые дополнительные замечания, касающиеся функ-
циональных зависимостей.
1. Неприводимые слева ФЗ. Вспомним из главы 10, что функциональная зависи-
мость называется неприводимой слева, если ее левая часть “не очень велика”. Рас-
смотрим, например, переменную-отношение SCP, приведенную в разделе 11.1, ко-
торая удовлетворяет следующей функциональной зависимости.
{ S#, P# } —> CITY
Однако атрибут P# в левой части этой функциональной зависимости является избы-
точным и она может быть переписана в следующем виде.
S# -» CITY
(Иначе говоря, атрибут CITY функционально зависит от S#.) Эта последняя функ-
циональная зависимость является неприводимой слева, а предыдущая— нет. Та-
ким образом, можно сказать, что атрибут CITY неприводимо зависим от атрибута
S#, но не неприводимо зависим от множества атрибутов {S#, Р#}4.
Неприводимые слева ФЗ и неприводимые зависимости играют важную роль при опре-
делении второй и третьей нормальной форм (подробности приводятся в разделе 11.3).
2. Диаграммы ФЗ. Пусть дана переменная-отношение R и пусть к ней применимо не-
которое неприводимое множество функциональных зависимостей I (более подроб-
ные сведения о неприводимых множествах ФЗ приводятся в главе 10). Удобнее всего
представить это множество ФД в виде диаграммы функциональных зависимостей
(диаграммы ФЗ). Например, на рис. 11.4 показаны вполне очевидные по смыслу диа-
граммы функциональных зависимостей для переменных-отношений S, SP и Р соот-
ветственно. Такие диаграммы будут часто использоваться далее в этой главе.
Рис. 11.4. Диаграмма функциональных зависимостей для пере-
менных-отношений S, SP и Р
Как можно видеть, на рис. 11.4 каждая стрелка начинается с потенциального
ключа (на самом деле — с первичного ключа) соответствующей переменной-
отношения. По определению стрелки должны начинаться с каждого потенциально-
4 Здесь термины “неприводимая слева ФЗ ” и “неприводимо зависим ” используются вместо
терминов “полная ФЗ” и “полностью зависим”, которые часто можно встретить в литера-
туре и прежних изданиях этой книги. Хотя последние термины отличаются краткостью, они
менее информативны и потому не очень удобны.
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 429
го ключа5, поскольку одному значению такого ключа всегда соответствует еще по
крайней мере одно какое-либо значение. Некоторые из существующих стрелок в
определенных случаях необходимо будет исключить ввиду того, что они вызыва-
ют определенные затруднения, однако стрелки, начинающиеся с потенциальных
ключей, никогда не могут быть исключены. Таким образом, процедуру нормализа-
ции можно неформально охарактеризовать как процедуру исключения стрелок, ко-
торые не начинаются с потенциальных ключей.
3. ФЗ как семантическое понятие. Конечно, функциональные зависимости— это
особый вид ограничений целостности, а потому они, несомненно, являются поня-
тием семантическим. Распознавание функциональных зависимостей представляет
собой часть процесса выяснения смысла тех или иных данных. Тот факт, что пере-
менная-отношение S удовлетворяет зависимости S# —> CITY, по сути, означает, что
каждый поставщик находится точно в одном городе. Иначе эту ситуацию можно
охарактеризовать следующим образом.
В реальном мире существует некоторое ограничение, представленное в этой ба-
зе данных, а именно: каждый поставщик находится точно в одном городе.
Поскольку это ограничение является частью семантического описания предмет-
ной области, оно должно быть каким-то образом представлено в базе данных.
Для этого ограничение необходимо описать в определении базы данных таким
образом, чтобы оно могло быть приведено в действие средствами СУБД.
Способ описания ограничения в определении базы данных состоит в объявлении
соответствующей функциональной зависимости.
Как будет показано ниже, концепции нормализации позволяют использовать весьма
простые способы объявления ФЗ.
11.3. Первая, вторая и третья
нормальные формы
Предостережение. В этом разделе для простоты изложения предполагается, что
каждая переменная-отношение имеет в точности один потенциальный ключ, который
является первичным ключом. Подобное допущение нашло отражение в приведенных
ниже доказательствах, которые (как уже отмечалось) являются не очень строгими.
Далее, в разделе 11.5, будет рассмотрен случай, когда переменная-отношение имеет
два или более потенциальных ключей.
Прежде чем перейти к подробному описанию трех нормальных форм, исходно пред-
ложенных Коддом, следует дать предварительное и весьма неформальное определение
третьей нормальной формы для того, чтобы в общих чертах обрисовать основную цель
изложения. Затем будет рассмотрена процедура приведения произвольной переменной-
отношения к эквивалентному набору переменных-отношений в ЗНФ. Попутно будут да-
ны более точные определения первых трех нормальных форм. Однако в качестве отступ-
ления следует отметить, что формы 1НФ, 2НФ и ЗНФ сами по себе не имеют особого
значения и должны рассматриваться лишь как промежуточные этапы на пути построения
формы НФБК (и форм более высокого уровня).
5 Точнее, стрелки должны начинаться с суперключей. Но если множество ФЗ является не-
приводимым, все функциональные зависимости (или "стрелки”) будут неприводимы слева.
430
Часть III. Проектирование базы данных
Итак, ниже дается предварительное определение ЗНФ.
Третья нормальная форма (очень неформальное определение). Переменная-
отношение находится,в ЗНФ тогда и только тогда, когда ее неключевые атрибуты
(если они вообще есть) являются:
а) взаимно независимыми;
б) неприводимо зависимыми от первичного ключа.
Понятия “неключевые атрибуты” и “взаимно независимые атрибуты” поясняют-
ся ниже.
Неключевой атрибут — это атрибут, который не входит в состав первичного
ключа рассматриваемой переменной-отношения.
Два или более атрибутов называются взаимно независимыми, если ни один из них
функционально не зависит от какой-либо комбинации остальных атрибутов. По-
добная независимость подразумевает, что каждый такой атрибут может обнов-
ляться независимо от значений остальных атрибутов.
Например, согласно приведенному ниже определению переменная-отношение Р
(переменная-отношение деталей) находится в ЗНФ, а именно: атрибуты PNAME (название
детали), COLOR (цвет), WEIGHT (вес) и CITY (город) независимы (т.е. цвета деталей можно
менять, не изменяя их вес и т.д.) и неприводимо зависимы по отношению к первичному
ключу {Р#} (номер детали).
Такое неформальное определение ЗНФ может быть интерпретировано следующим,
еще более неформальным образом.
Третья нормальная форма (еще более неформальное определение). Переменная-
отношение находится в ЗНФ тогда и только тогда, когда каждый кортеж состоит
из значения первичного ключа, идентифицирующего некоторую сущность, и на-
бора из нуля или более взаимно независимых атрибутов, некоторым образом опи-
сывающих эту сущность.
К переменной-отношению Р применимо и это определение, поскольку каждый кор-
теж переменной-отношения Р состоит из значения первичного ключа (номер детали),
идентифицирующего некоторую деталь в реальном мире, и четырех дополнительных
взаимно независимых значений (название, цвет, вес детали и город, в котором она нахо-
дится), описывающих отдельные свойства детали.
Теперь можно вернуться к описанию процедуры нормализации и дать определение
первой нормальной формы.
Первая нормальная форма. Переменная-отношение находится в 1НФ тогда и
только тогда, когда в любом допустимом значении этой переменной-отношения
каждый ее кортеж содержит только одно значение для каждого из атрибутов.
Фактически в этом определении всего лишь утверждается, что все переменные-
отношения всегда находятся в 1НФ, что, несомненно, верно. Однако переменная-
отношение, которая находится только в 1НФ (т.е. не находится ни во второй, ни в треть-
ей нормальной форме), обладает структурой, не совсем желательной по некоторым при-
чинам. Для иллюстрации этого факта допустим, что информация о поставщиках и по-
ставках содержится не в двух переменных-отношениях S и SP, а в одной, имеющей
следующую структуру.
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 431
CITY
S#
QTY
P#
STATUS
FIRST { S#, STATUS, CITY, P#, QTY }
PRIMARY KEY { S#, P# }
Это расширенная версия переменной-отношения SCP, приведенной выше, в разде-
ле 11.1. Ее атрибуты имеют тот же смысл, что и ранее, за исключением следующего до-
полнительного ограничения, специально введенного в этом примере.
CITY -> STATUS
(Иными словами, атрибут STATUS функционально зависим от атрибута CITY; и смысл этого
ограничения состоит в том, что статус поставщика определяется его местонахождением, на-
пример все поставщики из Лондона должны иметь статус 20.) Кроме того, для упрощения ат-
рибут SNAME далее будет игнорироваться. Первичным ключом переменной-отношения FIRST
является комбинация атрибутов {S#, Р#}, а диаграмма ее функциональных зависимостей бу-
дет иметь вид, представленный на рис. 11.5.
Обратите внимание, что эта диаграмма
функциональных зависимостей “сложнее” ана-
логичной диаграммы для переменной-
отношения в ЗНФ. Как было сказано в преды-
дущем разделе, на диаграмме ФЗ для перемен-
ной-отношения в ЗНФ стрелки всегда выходят
только из потенциальных ключей, тогда как
на диаграмме ФЗ для переменной-отношения,
которая не находится в ЗНФ (например, на
Рис 115 Функциональные зависимости диаграмме ФЗ для переменной-отношения
в переменной-отношении FIRST FIRST), есть стрелки, начинающиеся с потен-
циальных ключей, и дополнительные стрелки, усложняющие всю картину. Фактиче-
ски в переменной-отношении FIRST нарушаются оба условия, указанные в приведен-
ном выше определении ЗНФ. не все неключевые атрибуты взаимно независимы, по-
скольку атрибут STATUS зависит от атрибута CITY (одна дополнительная стрелка), и не
все неключевые атрибуты неприводимо зависимы от первичного ключа, поскольку ат-
рибуты STATUS и CITY, каждый в отдельности, зависимы от атрибута S# (еще две до-
полнительные стрелки).
Для иллюстрации некоторых трудностей, порождаемых этими дополнительными
стрелками, на рис. 11.6 приведен пример данных в переменной-отношении FIRST. Это
тот же набор значений, который обычно используется нами в примерах, но значение 30
статуса поставщика с номером 'S3' заменено значением 10 в соответствии с новым ог-
раничением, согласно которому значение атрибута CITY определяет значение атрибута
STATUS. Возникшая в результате избыточность данных вполне очевидна, поскольку в ка-
ждом кортеже для поставщика с номером 'S1' атрибут CITY имеет значение 'London' и,
кроме того, в каждом кортеже со значением 'London' в атрибуте CITY указано значение
20 для атрибута STATUS.
Избыточность в переменной-отношении FIRST приводит к разным аномалиям об-
новления, получившим такое название по историческим причинам. Под этим
понимаются определенные трудности, появляющиеся при выполнении операций об-
новления INSERT, DELETE и UPDATE. Для начала рассмотрим избыточность вида
432
Часть III. Проектирование базы данных
“поставщик-город”, соответствующую функциональной зависимости S# —> CITY. Ни-
же поясняются проблемы, которые возникнут при выполнении каждой из указанных
операций обновления.
S# STATUS CITY P# QTY
S1 20 London Pl 300
S1 20 London P2 200
S1 20 London P3 400
S1 20 London P4 200
S1 20 London P5 100
S1 20 London P6 100
S2 10 Paris Pl 300
S2 10 Paris P2 400
S3 10 Paris P2 200
S4 20 London P2 200
S4 20 London P4 300
S4 20 London P5 400
Рис. 11.6. Пример данных в переменной-отношении FIRST
Операция INSERT. Нельзя поместить в переменную-отношение FIRST информа-
цию о том, что некоторый поставщик находится в определенном городе, не ука-
зав сведения хотя бы об одной детали, поставляемой этим поставщиком. Дейст-
вительно, в таблице на рис. 11.6 нет сведений о поставщике с номером 'S5' из
Афин, поскольку до тех пор, пока этот поставщик не начнет поставку какой-
либо детали, для него невозможно будет сформировать значение первичного
ключа. (Как и в разделе 9.4, в этой главе предполагается (достаточно обосно-
ванно), что атрибуты первичных ключей не могут иметь значений, принимае-
мых по умолчанию.)
Операция DELETE. Если из переменной-отношения FIRST удалить кортеж, кото-
рый является единственным для некоторого поставщика, будет удалена не только
информация о поставке поставщиком некоторой детали, но также информация о
том, что этот поставщик находится в определенном городе. Например, если из пе-
ременной-отношения FIRST удалить кортеж со значением 'S3' в атрибуте S# и
значением 'Р2' в атрибуте Р#, будет утрачена информация о том, что поставщик с
номером 'S3' находится в Париже. (По сути, проблемы удаления и вставки явля-
ют собой две стороны одной медали.)
Замечание. В действительности проблема заключается в том, что в переменной-
отношении FIRST содержится слишком много собранной в одном месте инфор-
мации, поэтому при удалении некоторого кортежа теряется слишком много
информации. Точнее говоря, переменная-отношение FIRST одновременно со-
держит информацию и о поставках, и о поставщиках. В результате удаление
информации о поставке вызывает также удаление информации о поставщике.
Для решения этой проблемы необходимо разделить информацию на несколько
частей, т.е. собрать сведения о поставках в одной переменной-отношении, а о
поставщиках — в другой (именно это и будет сделано чуть ниже). Следователь-
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 433
но, процедуру нормализации иначе можно неформально охарактеризовать как
процедуру разбиения логически несвязанной информации на отдельные пере-
менные-отношения.
Операция UPDATE. Название города для каждого поставщика повторяется в пере-
менной-отношении FIRST несколько раз, и эта избыточность приводит к возник-
новению проблем при обновлении. Например, если поставщик с номером ' S1' пе-
реместится из Лондона в Амстердам, то необходимо будет отыскать в переменной-
отношении FIRST все кортежи, в которых значения 'S1' и 'London' связаны меж-
ду собой (для внесения соответствующих изменений), иначе база данных окажется
в противоречивом состоянии (в одних кортежах городом поставщика с номером
' S1' будет Лондон, а в других — Амстердам).
Для решения всех этих проблем, как предлагалось выше, необходимо заменить пере-
менную-отношение FIRST двумя следующими переменными-отношениями.
SECOND { S#, STATUS, CITY }
SP { S#, P#, QTY }
Диаграммы функциональных зависимостей для этих двух переменных-отношений пока-
заны на рис. 11.7, а наборы данных— на рис. 11.8. Обратите внимание, что теперь в них
имеется и информация о поставщике с номером ' S5' (в переменной-отношении SECOND, но
не в переменной-отношении SP), а содержимое переменной-отношения SP теперь в точно-
сти совпадает с содержимым нашей обычной переменной-отношения поставок.
Рис. 11.7. Функциональные зависимости в пе-
ременных-отношениях SECOND и SP
Легко убедиться, что измененная подобным образом структура данных позволяет
преодолеть все перечисленные выше проблемы, связанные с выполнением операций об-
новления.
Операция INSERT. Теперь информацию о том, что поставщик с номером 'S5' на-
ходится в Афинах, можно поместить в базу данных, вставив соответствующий
кортеж в переменную-отношение SECOND, причем даже в том случае, если он в на-
стоящее время не поставляет никаких деталей.
Операция DELETE. Теперь уже можно исключить информацию о поставке, в которой
соединены сведения о поставщике с номером ' S3' ио детали с номером ' Р2'. Доста-
точно удалить соответствующий кортеж из переменной-отношения SP, причем инфор-
мация о том, что поставщик с номером ' S3' находится в Париже, не утрачивается.
434
Часть III. Проектирование базы данных
SECOND S# STATUS CITY SP S# P# QTY
SI 20 London SI Pl 300
S2 10 Paris SI P2 200
S3 10 Paris SI P3 400
S4 20 London SI P4 200
S5 30 Athens SI P5 100
SI P6 100
S2 Pl 300
S2 P2 400
S3 P2 200
S4 P2 200
S4 P4 300
|S4 |P5 400
Рис. 11.8. Пример данных в переменных-отношениях SECOND и SP
Операция UPDATE. В переработанной структуре название города для каждого по-
ставщика указывается всего один раз, поскольку существует только один кортеж
для данного поставщика в переменной-отношении SECOND (атрибут S# является
первичным ключом этой переменной-отношения). Иначе говоря, избыточность
данных S#-CITY устранена. Благодаря этому теперь можно изменить название го-
рода Лондон для поставщика с номером 'S1' на Амстердам, не рискуя привести
базу данных в несогласованное состояние, поскольку достаточно изменить назва-
ние города в единственном кортеже переменной-отношения SECOND.
Сравнивая рис. 11.7 и 11.5, можно заметить, что суть разбиения переменной-отношения
FIRST на переменные-отношения SECOND и SP состояла в исключении зависимостей, кото-
рые не являлись неприводимыми. Именно благодаря этому в новом варианте удается избе-
жать упомянутых ранее трудностей. Интуитивно понятно, что в переменной-отношении
FIRST атрибут CITY описывал не сущность, которая идентифицируется первичным ключом
(поставка), а поставщика, выполнявшего эту поставку (аналогичное утверждение можно
сделать и об атрибуте STATUS). Смешивание этих двух типов информации в одной перемен-
ной-отношении и стало причиной возникновения описанных выше проблем.
Теперь пришло время дать определение второй нормальной формы6.
Вторая нормальная форма (в определении предполагается наличие только од-
ного потенциального ключа, который и является первичным ключом отношения).
Переменная-отношение находится во второй нормальной форме тогда и только
тогда, когда она находится в первой нормальной форме и каждый неключевой ат-
рибут неприводимо зависит от ее первичного ключа.
Обе переменные-отношения (и SECOND, и SP) находятся во второй нормальной форме (их
первичные ключи— {S#} и {S#, Р#} соответственно), тогда как переменная-отношение
FIRST не находится в этой форме. Всякую переменную-отношение, которая находится в пер-
6 Строго говоря, 2НФ может быть определена только по отношению к заданному множе-
ству зависимостей, но в неформальном контексте эта особенность обычно игнорируется. Ана-
логичные замечания приложимы также ко всем нормальным формам (кроме, конечно же, первой
нормальной формы).
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 435
вой нормальной форме, но не находится во второй, всегда можно свести к эквивалентному
множеству переменных-отношений, находящихся в 2НФ. Этот процесс заключается в замене
переменной-отношения в 1 НФ подходящим набором проекций, эквивалентных исходной пе-
ременной-отношению в том смысле, что ее при необходимости можно будет восстановить с
помощью обратной операции соединения данных проекций. В нашем примере переменные-
отношения SECOND и SP — это проекции переменной-отношения FIRST, которая является со-
единением переменных-отношений SECOND и SP по атрибуту S#7.
Таким образом, первый этап процедуры нормализации состоит в создании проекций,
которые позволяют исключить функциональные зависимости, не являющиеся неприво-
димыми. Пусть дана переменная-отношение R, имеющая следующий вид.
R { А, В, С, D }
PRIMARY KEY { А, В }
/* Предполагается наличие функциональной зависимости А —> D */
Процедура нормализации предусматривает замену этой переменной-отношения сле-
дующими двумя проекциями R1 и R2.
Rl { A, D }
PRIMARY KEY { А }
R2 { А, В, С }
PRIMARY KEY { А, В }
FOREIGN KEY { А } REFERENCES Rl
Переменная-отношение R всегда может быть восстановлена посредством соединения
переменных-отношений R1 и R2 по внешнему и соответствующему ему первичному клю-
чам этих переменных-отношений.
Вернемся к нашему примеру. Следует отметить, что выбранная структура перемен-
ных-отношений SECOND и SP все еще может вызвать некоторые проблемы. Структура пе-
ременной-отношения SP вполне удовлетворительна, поскольку она фактически находит-
ся в ЗНФ. Поэтому мы больше не будем уделять ей внимание до конца данного раздела.
Однако в переменной-отношении SECOND неключевые атрибуты все еще не являются вза-
имно независимыми. Диаграмма функциональных зависимостей для нее по-прежнему
имеет вид более сложный, чем это требуется для диаграммы ФЗ переменной-отношения,
находящейся в ЗНФ. В частности, зависимость атрибута STATUS от атрибута S# хотя и яв-
ляется функциональной и действительно неприводимой, одновременно является тран-
зитивной (через атрибут CITY). Это означает, что каждое значение атрибута S# опреде-
ляет значение атрибута CITY, а значение атрибута CITY, в свою очередь, определяет зна-
чение атрибута STATUS. В общем случае, как уже объяснялось в главе 10, если имеют ме-
сто две функциональные зависимости А —> В и В —> С, то имеет место и транзитивная
функциональная зависимость А —> С. Однако наличие транзитивных зависимостей мо-
7 За исключением того факта, что переменная-отношение SECOND может содержать дополни-
тельные кортежи (например, кортеж для поставщика с номером 'S5'), которые не будут иметь
аналога в переменной-отношении FIRST (см. рис. 11.8). Иначе говоря, новая структура может содер-
жать информацию, которую невозможно будет представить в исходной структуре. В этом смысле
новую структуру можно рассматривать как более корректное представление реального мира.
436
Часть III. Проектирование базы данных
жет привести к возникновению описанных ниже аномалий обновления. (В данном случае
основное внимание будет сосредоточено на избыточности данных типа “город —
статус”, отвечающей функциональной зависимости CITY —> STATUS.)
Операция INSERT. Нельзя поместить в базу данных сведения об определенном
городе, обладающем некоторым статусом (например, нельзя указать, что все по-
ставщики из Рима должны обладать статусом 50), до тех пор, пока в этом городе
не появится конкретный поставщик.
Операция DELETE. При удалении из переменной-отношения SECOND кортежа для не-
которого города, представленного в ней этим единственным кортежем, будут удале-
ны не только сведения о поставщике из данного города, но и информация о том, ка-
ким статусом обладал сам город. Например, при удалении из переменной-
отношения SECOND кортежа для поставщика с номером ' S5' будет утрачена инфор-
мация о том, что для Афин был установлен статус 30. (И в этом случае операции
вставки и удаления фактически являются двумя сторонами одной и той же медали.)
Замечание. И вновь причиной подобных неприятностей является смешивание ин-
формации: переменная-отношение SECOND содержит информацию о поставщиках
и вместе с ней информацию о городах. Для выхода из этой ситуации следует по-
ступить так же, как и раньше, т.е. разделить смешанную информацию и перенести
одну ее часть в переменную-отношение со сведениями о поставщиках, а
другую — в переменную-отношение со сведениями о городах.
Операция UPDATE. В переменной-отношении SECOND значение статуса для каждого
города повторяется несколько раз (поэтому она все еще обладает некоторой избы-
точностью). Следовательно, при необходимости изменить для Лондона значение
статуса 20 на 30 потребуется отыскать в переменной-отношении SECOND все кортежи,
в которых значения 'London' и 20 связаны между собой (для внесения соответст-
вующих изменений). В противном случае база данных окажется в противоречивом
состоянии (в одних кортежах статус для Лондона будет равен 20, а в других — 30).
И вновь для решения этой проблемы следует заменить исходную переменную-
отношение SECOND двумя следующими проекциями.
SC { S#, CITY }
CS { CITY, STATUS }
Диаграммы функциональных зависимостей для этих переменных-отношений показа-
ны на рис. 11.9, а их содержимое — на рис. И. 10. Обратите внимание, что информация о
статусе Рима (Rome) включена только в переменную-отношение CS. Данное преобразова-
ние обратимо, поскольку переменная-отношение SECOND может быть получена посредст-
вом соединения переменных-отношений SC и CS по атрибуту CITY.
S#------• CITY CITY -----► STATUS
Рис. 11.9. Функциональные зависимости в переменных-
отношениях SC и CS
Глава 11. Дальнейшая нормализация: формы ШФ, 2НФ, ЗНФ и НФБК 437
SC S# CITY CS CITY STATUS
SI London Athens 30
S2 Paris London 20
S3 Paris Paris 10
S4 London Rome 50
S5 Athens
Рис. 11.10. Данные в переменных-отношениях SC и CS
И на этот раз вполне очевидно, что подобное изменение структуры переменных-
отношений позволяет устранить все описанные выше проблемы в операциях обновления.
Читателю предлагается самостоятельно разобраться в подробностях решения этих про-
блем. Сравнивая рис. 11.9 и 11.7, можно заметить, что благодаря дальнейшей декомпо-
зиции удалось исключить транзитивную зависимость атрибута STATUS от атрибута S#.
Это позволило избавиться ото всех существовавших трудностей. Интуитивно понятное
объяснение состоит в том, что в переменной-отношении SECOND атрибут STATUS описы-
вал сущность, отличную от сущности, которая идентифицировалась первичным ключом
отношения (т.е. номером поставщика), т.е. город поставщика. Именно смешивание этих
двух типов информации в одной переменной-отношении приводило к возникновению
описанных выше проблем.
Теперь можно дать определение третьей нормальной формы.
Третья нормальная форма (в определении предполагается наличие только од-
ного потенциального ключа, который и явля&тся первичным ключом отношения).
Переменная-отношение находится в третьей нормальной форме тогда и только то-
гда, когда она находится во второй нормальной форме и каждый неключевой ат-
рибут нетранзитивно зависит от ее первичного ключа. Замечание. Под нетранзи-
тивной зависимостью подразумевается отсутствие какой-либо взаимной зависимо-
сти в изложенном выше смысле.
Переменные-отношения SC и CS находятся в третьей нормальной форме, причем пер-
вичными ключами в них являются атрибуты {S#} и {CITY} соответственно. Переменная-
отношение SECOND не находится в третьей нормальной форме. Переменная-отношение,
которая находится в 2НФ, но не находится в ЗНФ, всегда может быть преобразована в
эквивалентный набор переменных-отношений в ЗНФ. Как говорилось ранее, этот про-
цесс обратим и, следовательно, никакая информация при подобном преобразовании не
утрачивается. Однако результирующий набор отношений в ЗНФ способен содержать та-
кую информацию, которая не могла быть представлена в исходной переменной-
отношении в 2НФ (например, сведения о том, что статус Рима равен 50)8.
Подводя итог сказанному, можно отметить, что второй этап нормализации состоит в
создании проекций для исключения транзитивных зависимостей. Иначе говоря, пусть
дана переменная-отношение R, имеющая следующий вид.
8 Отсюда следует, что как комбинация переменных-отношений "SECOND— SP” может рас-
сматриваться в качестве более корректного представления реального мира по сравнению с перемен-
ной-отношением FIRST, так и комбинация переменных-отношений “SC— CS” корректнее перемен-
ной-отношения SECOND, находящейся в 2НФ.
438
Часть III. Проектирование базы данных
R { А, В, С }
PRIMARY KEY { A }
/* Предполагается наличие функциональной зависимости В —> С */
Процедура нормализации предусматривает замену этой переменной-отношения сле-
дующими двумя проекциями R1 и R2.
R1 { В, С }
PRIMARY KEY { В }
R2 { А, В }
PRIMARY KEY { А }
FOREIGN KEY { В } REFERENCES R1
Переменная-отношение R всегда может быть восстановлена посредством соединения
переменных-отношений R1 и R2 по внешнему и соответствующему ему первичному клю-
чам этих переменных-отношений.
В заключение следует подчеркнуть, что уровень нормализации переменной-
отношения определяется семантикой данных, а не их конкретными значениями в
некоторое время. Нельзя с первого взгляда на набор данных некоторой перемен-
ной-отношения однозначно определить, находится ли она, например, в ЗНФ. Для
этого также необходимо представлять себе сущность этих данных, т.е. сущест-
вующие между ними зависимости. Следует также отметить, что, даже зная о зави-
симостях в некоторой переменной-отношении, нельзя на основании конкретного
набора ее данных доказать, что &на находится в ЗНФ. Самое лучшее, чего можно
достичь в подобном случае, — это лишь показать, что рассматриваемые данные не
нарушают никаких зависимостей, и, если это так, высказать предположение о том,
что этот набор данных не противоречат гипотезе о принадлежности перемен-
ной-отношения к ЗНФ. Однако данное утверждение не гарантирует, что предло-
женная гипотеза верна.
11.4. Сохранение зависимостей
।-------► CITY
S#]
L-------STATUS
В процессе нормализации часто возникает ситуация, когда переменная-отношение
может быть подвергнута декомпозиции без потерь несколькими разными способами.
Вновь обратимся к приведенной выше переменной-отношению SECOND с функциональ-
ными зависимостями S# —> CITY и CITY —> STATUS и, сле-
довательно, с еще одной транзитивной зависимостью
S# —> STATUS (на рис. 11.11 эта транзитивная зависимость
показана пунктирной стрелкой).
В разделе 11.3 отмечалось, что аномалии обновления,
сопровождающие переменную-отношение SECOND, можно
преодолеть посредством ее декомпозиции с последующей
заменой двумя проекциями в ЗНФ. Рис- Н.П. Функциональные
зависимости в пере-
SC { S#, CITY } менной-отношении
CS { CITY, STATUS } SECOND
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 439
Назовем эту декомпозицию просто “декомпозиция А”, имея в виду, что существует
альтернативный вариант декомпозиции (декомпозиция В).
SC { S#, CITY }
SS { Sfl, STATUS }
При этом проекции SC одинаковы и для варианта А, и для варианта В. Декомпозиция В
также выполняется без потери информации, и обе ее проекции находятся в ЗНФ. Однако
по некоторым причинам декомпозиция В менее желательна, чем декомпозиция А. На-
пример, после выполнения декомпозиции В по-прежнему будет невозможно ввести ин-
формацию о том, что некоторый город имеет определенный статус, не указав конкретно-
го поставщика из этого города.
Рассмотрим этот пример подробнее. Прежде всего заметим, что зависимости, исполь-
зованные для создания проекций в декомпозиции А, соответствуют сплошными стрелкам
(см. рис. 11.11), тогда как одна из зависимостей, использованная для создания проекций
в декомпозиции В, отмечена пунктирной стрелкой. В декомпозиции А обе проекции не-
зависимы одна от другой в том смысле, что обновления в каждой из них могут выпол-
няться совершенно независимо9. Если гарантируется, что выполняемые обновления бу-
дут допустимы в контексте данной проекции (т.е. уникальность ее первичного ключа не
нарушается), то соединение этих двух проекций после обновления всегда будет иметь
результатом допустимое значение переменной-отношения SECOND. Это следует пони-
мать так, что при соединении не будут нарушаться ограничения, наложенные на функ-
циональные зависимости в переменной-отношении SECOND. Однако в случае декомпози-
ции В вносимые в любую из двух проекций обновления должны тщательно контролиро-
ваться, чтобы исключить возможные нарушения функциональной зависимости
CITY —> STATUS. (Нарушения могут иметь место, если два и более поставщиков находят-
ся в одном и том же городе; в этом случае они должны иметь один статус. В качестве
примера разберите случай, когда в декомпозиции В поставщик с номером 'S1' переме-
щается из Лондона в Париж.) Иначе говоря, две проекции декомпозиции В не являются
независимыми одна от другой.
Основная проблема заключается в том, что в декомпозиции В функциональная зави-
симость CITY —> STATUS превращается (в соответствии с терминологией главы 8) в огра-
ничение базы данных, охватывающее две переменные-отношения. (Следует отметить,
что во многих современных программных продуктах подобные ограничения поддержи-
ваются с помощью собственных пользовательских процедур.) В противоположность
этому в декомпозиции А ограничением базы данных является транзитивная зависимость
S# —> STATUS, которая автоматически выполняется в случае выполнения двух ограниче-
ний переменных-отношений'. S# —> STATUS и CITY —> STATUS. Реализовать эти ограни-
чения очень просто, поскольку по сути они представляют собой требования поддержки
уникальности значений первичных ключей в соответствующих переменных-отношениях.
Таким образом, концепция независимых проекций предоставляет критерий выбора
одного из возможных вариантов декомпозиции. В частности, вариант декомпозиции,
обеспечивающий независимость проекций в приведенном выше смысле, в общем случае
9 Конечно, за исключением соблюдения ограничения целостности, установленного для перемен-
ных-отношений SC и CS
440
Часть III. Проектирование базы данных
предпочтительнее вариантов, в которых проекции будут зависимы. Риссанен (Rissanen)
[11.6] показал, что проекции R1 и R2 переменной-отношения R будут независимы в упо-
мянутом выше смысле тогда и только тогда, когда:
каждая функциональная зависимость в переменной-отношении R является логиче-
ским следствием функциональных зависимостей в ее проекциях R1 и R2;
общие атрибуты проекций R1 и R2 образуют потенциальный ключ по крайней мере
для одной из этих проекций.
Рассмотрим заданные выше декомпозиции А и В. В декомпозиции А обе проекции не-
зависимы, поскольку их общий атрибут CITY является первичным ключом для перемен-
ной-отношения CS и каждая функциональная зависимость переменной-отношения SECOND
либо представлена в одной из проекций, либо является логическим следствием других
имеющихся в них ФЗ. В декомпозиции В, наоборот, две составляющие ее проекции не
являются независимыми, поскольку функциональная зависимость CITY —> STATUS не
может быть выведена из ФЗ, существующих в этих проекциях, даже несмотря на то, что
их общий атрибут S# является потенциальным ключом для обеих проекций.
Замечание. Третий вариант декомпозиции с заменой переменной-отношения
SECOND проекциями {S#, STATUS} и {CITY, STATUS} не является допустимой деком-
позицией, поскольку сопровождается потерей информации. (Упражнение. Докажите
это утверждение.)
Переменная-отношение, которая не может быть подвергнута декомпозиции с получе-
нием независимых проекций, называется атомарной [11.6]. Однако это вовсе не означа-
ет, что каждую неатомарную (в указанном смысле) переменную-отношение следует не-
пременно разбить на атомарные компоненты. Например, переменные-отношения S и Р из
упоминавшейся выше базы данных поставщиков и деталей не являются атомарными, од-
нако дальнейшая их декомпозиция имела бы мало смысла. Переменная-отношение SP,
наоборот, является атомарной.
Идея о том, что нормализация всегда должна предусматривать декомпозицию пере-
менных-отношений на независимые проекции (в определенном Риссаненом смысле) по-
лучила название требования сохранения зависимостей. В заключение приведем не-
сколько более строгих замечаний по поводу этой концепции.
1. Пусть дана переменная-отношение R, которая после выполнения всех этапов нор-
мализации заменяется множеством переменных-отношений Rl, R2, ..., Rn
(конечно, все они являются проекциями переменной-отношения R).
2. Пусть также задано множество функциональных зависимостей S, имеющих место в
исходной переменной-отношении R, и множество функциональных зависимостей
Si, S2, ..., Sn, выполняющихся в переменных-отношенияхRl, R2, ..., Rn.
3. Каждая функциональная зависимость в множестве Si будет иметь отношение толь-
ко к атрибутам проекции Ri (где i=l, 2, 3, ..., п). В результате реализация огра-
ничений (устанавливаемых существующими ФЗ) для любого данного множества Si
представляется достаточно простой задачей. Однако в действительности необхо-
димо реализовать все ограничения, определяемые исходным множеством функ-
циональных зависимостей S. Следовательно, целесообразно выбрать такой вариант
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 441
декомпозиции исходной переменной-отношения на проекции Rl, R2, ..., Rn, при
котором совместный эффект от реализации ограничений для отдельных множеств
SI, S2, Sn будет эквивалентен реализации всех ограничений для исходного
множества функциональных зависимостей S. Иначе говоря, декомпозиция должна
выполняться с сохранением зависимостей.
4. Пусть S' является объединением множеств зависимостей SI, S2, Sn. Обратите
внимание на то, что в общем случае равенство S'=S не выполняется. Для декомпо-
зиции с сохранением зависимостей достаточно, чтобы были равны замыкания
множеств S и S' (понятие замыкания множества функциональных зависимостей
рассматривалось в разделе 10.4).
5. В общем случае не существует эффективного метода вычисления замыкания S+ для
заданного множества функциональных зависимостей, поэтому на практике вычис-
ление и сравнение двух необходимых замыканий осуществить сложно. Тем не ме-
нее существует эффективный метод проверки, будет ли декомпозиция выполняться
с сохранением зависимостей. Описание подробностей этого алгоритма выходит за
рамки данной книги, однако заинтересованный читатель сможет найти его в книге
Ульмана (Ullman) [7.13].
Замечание. В ответе к упр. 11.3 приведен алгоритм выполнения декомпозиции без
потерь (и с сохранением существующих функциональных зависимостей) для произ-
вольной переменной-отношения, позволяющий разбить ее на некоторое множество
проекций в ЗНФ.
11.5. Нормальная форма Бойса-Кодда
В этом разделе отбрасывается применявшееся выше допущение о том, что каждая пе-
ременная-отношение имеет только один потенциальный ключ (а именно — первичный
ключ), и рассматривается более общий случай. Дело в том, что первоначальное опреде-
ление, данное Коддом для ЗНФ [10.4], не во всех случаях оказывается удовлетворитель-
ным. В частности, оно неадекватно при выполнении следующих условий.
1. Переменная-отношение имеет два (или более) потенциальных ключа.
2. Эти потенциальные ключи являются составными.
3. Два или более потенциальных ключей перекрываются (т.е. имеют по крайней мере
один общий атрибут).
Поэтому впоследствии исходное определение ЗНФ было заменено более строгим оп-
ределением Бойса-Кодда (Boyce/Codd) [11.2], для которого было установлено собствен-
ное название — нормальная форма Бойса-Кодда (или НФБК)10.
Замечание. Комбинация условий 1-3 на практике встречается нечасто, а ЗНФ и
НФБК полностью эквивалентны для любой переменной-отношения, в которой эти три
условия не выполняются.
Ю На самом деле строгое определение "третьей” нормальной формы, эквивалентное опреде-
лению нормальной формы Бойса-Кодда, впервые было дано Хитом (Heath) в 1971 году [11.4] и
эту форму следовало бы назвать "нормальная форма Хита ”.
442
Часть III. Проектирование базы данных
Для объяснения концепции НФБК необходимо воспользоваться понятием детерми-
нанта, введенным в главе 10 для ссылок на левую часть описания некоторой функцио-
нальной зависимости, а также понятием тривиальной функциональной зависимости,
обозначающим такую ФЗ, левая часть которой является супермножеством правой части.
Дадим определение НФБК.
Переменная-отношение находится в нормальной форме Бойса-Кодда тогда и
только тогда, когда каждая ее нетривиальная и неприводимая слева функциональ-
ная зависимость имеет в качестве детерминанта некоторый потенциальный ключ.
Можно дать и другой, менее формальный вариант определения.
Переменная-отношение находится в нормальной форме Бойса-Кодда тогда и
только тогда, когда детерминанты всех ее ФЗ являются потенциальными ключами.
Иначе говоря, на диаграмме функциональных зависимостей стрелки будут начинаться
только с элементов, представляющих потенциальные ключи. Согласно данному выше
определению никакие другие стрелки не допускаются и, следовательно, никакие стрелки
не могут быть исключены с помощью описанной выше процедуры нормализации.
Замечание. Различие между двумя приведенными определениями НФБК состоит в
том, что в менее формальном из них неявно подразумевается, что детерминанты “не
слишком велики” и все ФЗ нетривиальны. Для простоты изложения далее в этой главе
будут использованы такие же допущения, за исключением особо оговоренных случаев.
Стоит также отметить, что определение НФБК концептуально проще, чем данное ранее
определение ЗНФ, поскольку в нем нет явных ссылок на первую и вторую нормальные
формы, а также не используется концепция транзитивной зависимости. Кроме того, хотя
(как отмечалось выше) определение НФБК является существенно более строгим, чем опре-
деление ЗНФ, любая переменная-отношение может быть подвергнута декомпозиции без
потерь информации на некоторый эквивалентный набор переменных-отношений в НФБК.
Прежде чем рассматривать примеры переменных-отношений с несколькими потенци-
альными ключами, убедимся, что переменные-отношения FIRST и SECOND, которые не
находятся в ЗНФ, также не находятся в НФБК. Кроме того, убедимся, что переменные-
отношения SP, SC и CS, которые находятся в ЗНФ, также находятся в НФБК. Переменная-
отношение FIRST содержит три детерминанта, а именно — S#, CITY и {S#, Р#}, из кото-
рых только {Sfl, Р#} является ее потенциальным ключом. Поэтому переменная-
отношение FIRST не находится в НФБК. Аналогичное утверждение верно для перемен-
ной-отношения SECOND, поскольку детерминант CITY не является ее потенциальным клю-
чом. С другой стороны, переменные-отношения SP, SC и CS находятся в НФБК, посколь-
ку в каждом случае единственный потенциальный ключ является единственным детер-
минантом для данной переменной-отношения.
Теперь рассмотрим пример, содержащий два неперекрывающихся потенциальных
ключа. Допустим, что в переменной-отношении поставщиков S с атрибутами {S#, SNAME,
STATUS, CITY} атрибуты S# и SNAME являются ее потенциальными ключами (т.е. в этом
случае каждый поставщик имеет уникальный номер и уникальное имя). Также предпо-
ложим (как, впрочем, и всюду в этой книге), что атрибуты STATUS и CITY являются неза-
висимыми, т.е. введенная выше для некоторых частных целей функциональная зависи-
мость CITY —> STATUS больше не имеет места. Тогда диаграмма функциональных зави-
симостей будет иметь вид, представленный на рис. 11.12.
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 443
s#
SNAME
STATUS
CITY
Рис. 11.12. Диаграмма функциональных за-
висимостей в переменной-отношении
S для случая, когда атрибут SNAME яв-
ляется ее потенциальным ключом (и
зависимость CITY —> STATUS не вы-
полняется)
Данная переменная-отношение S нахо-
дится в НФБК. Хотя ее диаграмма ФЗ су-
щественно “сложнее” диаграммы ФЗ для
переменной-отношения в ЗНФ, в этом слу-
чае все детерминанты являются потенци-
альными ключами, а все стрелки начина-
ются с потенциальных ключей. Таким об-
разом, из данного примера можно сделать
вывод, что наличие нескольких потенци-
альных ключей не так уж и плохо. (Однако
весьма желательно, чтобы атрибут SNAME
был описан как потенциальный ключ еще
при определении базы данных, что позво-
лит СУБД обеспечить строгую уникаль-
ность его значений.)
Теперь рассмотрим несколько примеров, в которых потенциальные ключи перекры-
ваются. Потенциальные ключи перекрываются, если они содержат по два или более ат-
рибутов и имеют хотя бы один общий атрибут.
Замечание. В соответствии с доводами, которые приводились в главе 8, в примерах
этой главы из имеющихся потенциальных ключей первичный ключ выбираться не будет.
Поэтому в представленных ниже таблицах никакие столбцы не будут выделяться с по-
мощью двойной линии.
В первом примере рассмотрим переменную-отношение, в которой предполагается,
что имена поставщиков уникальны.
SSP { S#, SNAME, Р#, QTY }
Потенциальными ключами в ней являются пары атрибутов {S#, Р#} и {SNAME, Р#}.
Однако эта переменная-отношение не находится в НФБК, так как она содержит два де-
терминанта, S# и SNAME, которые не являются ее потенциальными ключами (S# и
SNAME — детерминанты, поскольку они определяют друг друга). Пример значений дан-
ных для переменной-отношения SSP показан на рис. 11.13.
SSP S# SNAME P# QTY
S1 Smith Pl 300
S1 Smith P2 200
S1 Smith P3 400
S1 Smith P4 200
Рис. 11.13. Часть примера набора данных для переменной-отношения SSP
Как можно видеть, переменной-отношению SSP свойственна некоторая доля избы-
точности, присутствовавшей в переменной-отношении SCP (см. раздел 11.3) и в перемен-
ных-отношениях FIRST и SECOND (см. раздел 11.1), поэтому она характеризуется такими
же аномалиями обновления. Например, изменение имени поставщика с номером 'S1'
либо потребует найти все относящиеся к нему кортежи, либо приведет к переходу базы
444
Часть III Проектирование базы данных
данных в противоречивое состояние. Тем не менее переменная-отношение SSP находится
в ЗНФ, поскольку согласно старому определению не требуется, чтобы атрибут был не-
приводимо зависим от каждого потенциального ключа, если он сам является компонен-
том некоторого потенциального ключа данной переменной-отношения. В результате тот
факт, что атрибут SNAME приводимо зависим от атрибутов {S#, Р#}> данным определени-
ем игнорируется.
Замечание. Под термином “ЗНФ” здесь подразумевается определение, данное Коддом
в [10.4], а не упрощенное определение, данное нами в разделе 11.3.
Для решения указанной проблемы переменную-отношение SSP следует разбить на две
проекции.
SS { S#, SNAME }
SP { S#, Р#, QTY }
Однако можно выбрать и альтернативный вариант разбиения.
SS { S#, SNAME }
SP { SNAME, Р#, QTY }
Обратите внимание, что в этом примере существует два варианта декомпозиции, причем в
одинаковой мере допустимых, поскольку все входящие в них проекции находятся в НФБК.
Здесь следует сделать небольшое отступление и пояснить, что же происходит “в дей-
ствительности”. Ясно, что исходный вариант, состоящий из одной переменной-
отношения SSP, неудачен и возникающие в связи с этим проблемы вполне очевидны.
Маловероятно, чтобы подобный проект предложил более или менее опытный разработ-
чик баз данных, даже если он совершенно не знаком с концепцией НФБК (и т.д.). Про-
стой здравый смысл подскажет нам, что вариант с двумя переменными-отношениями SS
и SP, несомненно, лучше. Однако что в данном случае подразумевается под “здравым
смыслом” и в соответствии с какими принципами разработчику следует отдать предпоч-
тение варианту с переменными-отношениями SS и SP вместо варианта с переменной-
отношением SSP?
Безусловно, ответ заключается в том, что это именно принципы функциональной зави-
симости и нормальная форма Бойса-Кодда. Иначе говоря, рассматриваемые нами концеп-
ции (ФЗ, НФБК и все прочие формальные идеи, изложенные в этой и следующей главах)
являются не более и не менее чем соображениями здравого смысла, записанными в фор-
мальном виде. Сутью излагаемой здесь теории является поиск и формулирование этих
принципов здравого смысла, что, конечно же, является весьма непростой задачей. Однако,
если такая задача будет нами решена, найденные принципы могут быть положены в основу
решений автоматизации, т.е. можно будет написать программу, позволяющую выполнять
проектирование с помощью компьютера. Критики методов нормализации обычно упуска-
ют этот момент из виду, совершенно справедливо заявляя, что данные идеи, в основном,
представляют собой всего лишь соображения здравого смысла. Однако при этом не прини-
мается во внимание, что возможность формальной и строгой формулировки “соображений
здравого смысла” уже сама по себе является значительным достижением.
Теперь вернемся к основной теме данного раздела и рассмотрим второй пример с пе-
рекрывающимися потенциальными ключами. Обратимся к переменной-отношению SJT с
атрибутами S, J и Т, которые представляют студента, изучаемый предмет и преподавате-
ля соответственно (следует предупредить, что это всего лишь пример, к тому же доста-
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 445
точно экзотический). Смысл каждого кортежа {S:s, J: j, T:t} переменной-отношения
SJT состоит в том, что некоторый студент s изучает некоторый предмет j у некоторого
преподавателя t. При этом на информацию накладываются следующие два ограничения.
Каждый студент изучает определенный предмет только у одного преподавателя.
Каждый преподаватель ведет только один предмет, однако каждый предмет может
преподаваться несколькими преподавателями.
На рис. 11.14 показан пример данных в переменной-отношении SJT.
SJT
S J T
Smith Math Prof. White
Smith Physics Prof. Green
Jones Math Prof. White
Jones Physics Prof. Brown
Рис. 11.14. Пример данных в переменной-отношении SJT
Какие функциональные зависимости существуют в этой переменной-отношении? Из пер-
вого ограничения следует зависимость атрибута Т от комбинации атрибутов {S, J}, а из вто-
рого — зависимость атрибута J от атрибута Т. Следовательно, диаграмма функциональных
зависимостей переменной-отношении SJT будет иметь вид, представленный на рис. 11.15.
Рис. 11.15. Диаграмма функциональных зави-
симостей в переменной-отношении SJT
И вновь в рассматриваемом примере присутствуют два перекрывающихся потенци-
альных ключа, а именно: комбинация {S, J} и комбинация {S, Т}. Как и в первом при-
мере, исходная переменная-отношение SJT находится в ЗНФ, но не в НФБК, в связи с
чем для нее будут характерны некоторые аномалии обновления. Например, если потре-
буется удалить сведения о том, что студент Джонс ('Jones') изучает физику, этого нель-
зя будет сделать, не утратив одновременно информацию о том, что профессор Браун
('Prof. Brown') преподает этот предмет. Подобные трудности вызваны тем, что атрибут
Т является детерминантом, но не является потенциальным ключом. И вновь для решения
указанной проблемы исходную переменную-отношение SJT следует разбить на две про-
екции, каждая из которых будет находиться в НФБК.
ST { S, Т }
TJ { Т, J }
446
Часть III Проектирование базы данных
В качестве упражнения читателю предлагается составить таблицы с данными этих
двух переменных-отношений (исходя из набора данных, представленных на рис. 11.14), а
также нарисовать соответствующую диаграмму ФЗ для проверки, действительно ли две
созданные проекции находятся в НФБК (какие атрибуты являются их потенциальными
ключами?). Кроме того, читателю рекомендуется проверить тот факт, что данная деком-
позиция позволяет устранить все существовавшие ранее аномалии обновления.
Однако следует отметить, что все еще существует иная проблема. Суть ее в том, что
декомпозиция исходного отношения на проекции ST и TJ позволила исключить одни
аномалии, однако привела к появлению других. Причиной является тот факт, что проек-
ции ST и TJ не являются независимыми в смысле Риссанена (подробности приводятся
выше в данной главе). Точнее говоря, функциональная зависимость {S, J} —» Т не мо-
жет быть выведена из той единственной функциональной зависимости, которая присут-
ствует в двух данных проекциях (Т —> J).
В результате две полученные проекции не могут обновляться независимо. Напри-
мер, попытка вставить в переменную-отношение ST кортеж для студента Смита
('Smith') и профессора Брауна ('Prof. Brown') должна быть отвергнута системой,
поскольку профессор Браун преподает физику, а Смит уже обучается физике у про-
фессора Грина ('Prof. Green'). Однако обнаружить этот факт, не проверив содержи-
мое переменной-отношения TJ, система не может. Таким образом, мы пришли к не-
приятному выводу о том, что попытка достижения двух целей, а именно — декомпо-
зиции исходной переменной-отношения на переменные-отношения, находящиеся в
НФБК, и декомпозиции исходной переменной-отношения на независимые
компоненты, в некоторых случаях может привести к конфликтной ситуации. Поэтому
достичь обе цели одновременно не всегда возможно.
Замечание. В действительности переменная-отношение SJT является атомарной
(см. раздел 11.4) даже несмотря на то, что она не находится в НФБК. Однако тот факт,
что атомарная переменная-отношение не может быть подвергнута декомпозиции на
независимые компоненты, отнюдь не означает, что она вообще не может быть под-
вергнута декомпозиции (здесь под “декомпозицией” понимается декомпозиция без по-
терь). “Атомарная переменная-отношение” — не совсем подходящий термин для дан-
ной концепции, по крайней мере с интуитивной точки зрения, поскольку подобная
атомарность не является ни необходимым, ни достаточным условием создания хоро-
шего проекта базы данных.
В качестве третьего и последнего примера переменной-отношения с перекры-
вающимися потенциальными ключами рассмотрим переменную-отношение EXAM с
атрибутами S (студент), J (предмет) и Р (позиция). Каждый кортеж {S:s, J: j, Р:р}
переменной-отношения EXAM отражает сведения о том, что некоторый студент s эк-
заменуется по определенному предмету j и занимает определенную позицию р в
списке экзаменующихся. Дополнительно условимся, что в нашем примере имеет ме-
сто следующее ограничение.
Никакие два студента не могут занимать одну и ту же позицию в списке экзаме-
нующихся по одному и тому же предмету.
В этом случае диаграмма функциональных зависимостей будет иметь вид, представ-
ленный на рис. 11.16.
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 447
Рис. 11.16. Диаграмма функциональных зависимостей в переменной-отно-
шении EXAM
В этом примере вновь присутствуют два перекрывающихся потенциальных ключа,
{S, J} и {J, Р}, поскольку для каждого студента и предмета существует точно одна за-
нимаемая позиция в соответствующем списке, а в каждом списке экзаменующихся по
некоторому предмету каждую позицию занимает только один соответствующий студент.
Однако такая переменная-отношение находится в НФБК, поскольку указанные потенци-
альные ключи являются ее единственными детерминантами. Поэтому для данной пере-
менной-отношения не характерны какие-либо аномалии обновления, подобные упоми-
навшимся ранее в настоящей главе. (Упражнение. Проверьте правильность этого утвер-
ждения.) Таким образом, наличие перекрывающихся потенциальных ключей не всегда
приводит к появлению проблем подобного рода.
В заключение следует подчеркнуть, что концепция НФБК позволяет избавиться от
проблем, которые присущи формам, соответствующим старому определению ЗНФ. Бо-
лее того, новое определение концептуально проще старого, так как в нем не используют-
ся понятия 1 НФ, 2НФ, первичного ключа или транзитивной зависимости. Дополнитель-
но понятие потенциального ключа может быть заменено ссылкой на более фундамен-
тальное понятие функциональной зависимости (в определении, данном в [11.2], имеет
место именно такая замена). С другой стороны, концепции первичного ключа, транзи-
тивной зависимости и т.д. весьма полезны на практике, поскольку позволяют сформули-
ровать идею некоторого пошагового процесса, выполняемого разработчиком для приве-
дения произвольной переменной-отношения к эквивалентному набору переменных-
отношений в НФБК.
Наконец заметим, что в ответе к упр. 11.3 приведен алгоритм, по которому произ-
вольная переменная-отношение может быть подвергнута декомпозиции без потерь ин-
формации с ее преобразованием в набор проекций, находящихся в НФБК.
11.6. Замечание по поводу атрибутов,
содержащих в качестве значений
отношения
Как было показано в главе 5, отношение может содержать атрибут, значения которо-
го также являются некоторыми отношениями (рис. 11.17). Конечно, следствием этого
является тот факт, что переменная-отношение, в свою очередь, также может содержать
атрибуты, значениями которых являются некоторые переменные-отношения. Однако с
точки зрения процедуры проектирования базы данных использовать подобные перемен-
448
Часть III. Проектирование базы данных
ные-отношения обычно не рекомендуется, поскольку для них характерна асимметрич-
ность]] (не говоря уже о том, что их предикаты, как правило, весьма сложны) и эта
асимметричность способна вызвать разные проблемы практического характера. Напри-
мер, для случая, показанного на рис. 11.17, сведения о поставщиках и деталях представ-
лены асимметрично. Рассмотрим два приведенных ниже симметричных запроса.
1. Получить список номеров поставщиков (S#) детали с номером ' Р1'.
2. Получить список деталей (Р#), поставляемых поставщиком с номером ' S1'.
Из-за асимметричности переменной-отношения SPQ их формулировки оказываются
совершенно различными
1. ( SPQ WHERE P# ( 'Pl' ) IN PQ { P# } ) { S# }.
2. ( ( SPQ WHERE S# = S# ( 'Si' ) ) { PQ } ) { P# }.
В данном примере предполагается, что SPQ — это переменная-отношение, допусти-
мыми значениями которой являются отношения, аналогичные показанному на рис. 11.17.
Рис II 17 Переменная-отношение SPQ с атрибутом, содержащим в качестве значений
другое отношение
Еще хуже обстоит дело с операциями обновления. Рассмотрим следующие две опера-
ции обновления.
1. Ввести сведения о новой поставке 500 деталей типа 'Р5' поставщиком с номером 'S6'.
2. Ввести сведения о новой поставке 500 деталей типа 'Р5' поставщиком с номером 'S2'.
И Фактически подобные переменные-отношения ранее даже не были узаконены и назывались
ненормализованными, т е такими, которые не находятся даже в первой нормальной форме
[10 4] (см также главу 5)
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 449
При работе с обычной переменной-отношением SP между двумя подобными обнов-
лениями нет никакой принципиальной разницы, так как в обоих случаях речь идет о
вставке в переменную-отношение единственного кортежа. В противоположность этому
при работе с переменной-отношением SPQ выполняемые обновления будут существенно
отличаться (не говоря уже о том, что в данной ситуации обе эти операции будут намного
сложнее, чем при работе с переменной-отношением SP).
1. INSERT INTO SPQ RELATION
{ TUPLE { S# S# ( 'S6' ),
PQ RELATION { TUPLE { P# ( 'P5' ),
QTY QTY ( 500 ) } } } };
2. UPDATE SPQ WHERE S# = S# ( 'S2' )
INSERT INTO PQ RELATION {TUPLE { P# ( 'P5' ),
QTY QTY ( 500 ) } };
Переменные-отношения (по крайней мере, базовые переменные-отношения) пред-
почтительнее создавать без использования подобных атрибутов, принимающих в качест-
ве значений другие отношения, так как в этом случае они обладают более простой логи-
ческой структурой, что существенно упрощает выполнение с ними различных операций.
Однако это замечание следует воспринимать лишь как рекомендацию, но не как обяза-
тельное правило. На практике вполне могут существовать такие ситуации, когда имеет
смысл использовать атрибут со значениями-отношениями в некоторой переменной-
отношении и даже в базовой переменной-отношении. Например, на рис. 11.18 показано
(частично) возможное содержимое переменной-отношения каталога RVK, в которой хра-
нятся сведения о переменных-отношениях некоторой базы данных с указанием их по-
тенциальных ключей. Атрибут СК в этой переменной-отношении содержит значения-
отношения. Причем он одновременно является компонентом единственного потенциаль-
ного ключа переменной-отношения RVK! Определение этой переменной-отношения мо-
жет выглядеть так, как показано ниже.
VAR RVK BASE RELATION
{ RVNAME NAME, CK RELATION { ATTRNAME NAME } }
KEY { RVNAME, CK };
Замечание. В ответе к упр. 11.3 показано, как можно исключить атрибуты со значе-
ниями-отношениями, если такое исключение является желательным (что обычно имеет
место на практике)12. См. также обсуждение оператора UNGROUP в главе 6 (раздел 6.8).
11.7. Резюме
На этом заканчивается первая из двух глав, посвященных дальнейшей нормализации.
В ней обсуждались концепции первой, второй и третьей нормальных форм, а также
нормальной формы Бойса-Кодда. Разные нормальные формы (включая четвертую и
пятую нормальные формы, речь о которых пойдет в следующей главе) образуют общее
12 Это действительно возможно! Следует отметить, что это невозможно в случае пере-
менной-отношения RVK, по крайней мере непосредственно (т.е. без введения некоторой разно-
видности атрибута CKNAME, предназначенного для указания ‘‘имени потенциального ключа”).
450
Часть III. Проектирование базы данных
упорядочение в том смысле, что каждая переменная-отношение на некотором уровне
нормализации автоматически находится на всех более низких уровнях нормализации, то-
гда как обратное утверждение неверно, т.е. на каждом уровне нормализации могут быть
переменные-отношения, которые не находятся на всех более высоких уровнях нормали-
зации. Более того, всегда можно выполнить приведение к НФБК (а на самом деле к
5НФ), т.е. любую заданную переменную-отношение всегда можно заменить эквивалент-
ным набором переменных-отношений, которые находятся в НФБК (или же в 5НФ). Та-
кое приведение используется для того, чтобы избежать избыточности и, следовательно,
возникновения некоторых аномалий обновления.
Рис. II. 18. Переменная-отношение RVK, входящая в каталог некоторой базы данных
Процесс приведения (декомпозиции) заключается в замене данной переменной-
отношения некоторым набором ее проекций, составленным таким образом, чтобы об-
ратное соединение этих проекций позволяло вновь получить исходную переменную-
отношение. Иначе говоря, этот процесс является обратимым (или декомпозиция всегда
выполняется без потерь информации). Также было показано, что решающую роль в
этом процессе играют функциональные зависимости. Теорема Хита прямо утвержда-
ет, что если некоторая декомпозиция выполняется в соответствии с определенной ФЗ, то
она будет выполнена без потерь. Такое положение дел может рассматриваться как еще
одно подтверждение сделанного в главе 10 заявления о том, что понятие ФЗ является ес-
ли и “не совсем фундаментальным, то весьма близким к этому”.
В данной главе также обсуждалась концепция Риссанена о независимых проекциях и
было сделано предположение о том, что в тех случаях, когда существует возможность вы-
бора, исходную переменную-отношение предпочтительнее разбивать именно на независи-
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 451
мые проекции, а не на проекции, зависимые одна от другой. Декомпозицию на независи-
мые проекции принято называть декомпозицией с сохранением зависимостей. К сожале-
нию, следует отметить, что стремление к достижению двух указанных выше целей, а имен-
но — к декомпозиции без потерь с приведением к НФБК и к декомпозиции с сохранением
зависимостей, в некоторых случаях может привести к конфликтной ситуации.
В заключение данной главы вашему вниманию предлагается весьма элегантное (и аб-
солютно точное) определение ЗНФ и НФБК, данное Заниоло (Zaniolo) [11.7]. Сначала
приведем определение ЗНФ.
Пусть дана переменная-отношение R, X является некоторым подмножеством атри-
бутов этой переменной-отношения R и А является некоторым отдельным атрибу-
том переменной-отношения R. Переменная-отношение R находится в третьей
нормальной форме тогда и только тогда, когда для каждой функциональной за-
висимости X —> А в переменной-отношении R истинно по крайней мере одно из
следующих утверждений.
1. Подмножество X включает атрибут А (т.е. данная ФЗ тривиальна).
2. Подмножество X является суперключом переменной-отношения R.
3. Атрибут А входит в состав некоторого потенциального ключа переменной-
отношения R.
Определение НФБК можно получить из приведенного выше определения ЗНФ, про-
сто опустив третье утверждение (из чего следует, что НФБК является более строгим ог-
раничением по сравнению с ЗНФ). Именно третье утверждение является причиной той
“неадекватности” исходного определения Кодда для ЗНФ [10.4], о которой упоминалось
во введении к этой главе.
Упражнения
11.1. Докажите теорему Хита. Будет ли верной обратная теорема?
11.2. Существует мнение, что каждая бинарная переменная-отношение обязательно на-
ходится в НФБК. Верно ли это утверждение?
11.3. На рис. 11.19 показана структура информации о персонале компании, которая
должна быть помещена в базу данных. Она представлена в том виде, который ис-
пользуется при работе с иерархической СУБД, подобной продукту Information
Management System (IMS) фирмы IBM (см. главу 1). Эта структура удовлетворяет
следующим правилам.
В компании имеется несколько отделов.
В каждом отделе (Department) есть некоторое количество сотрудников
(Employee), занятых в нескольких проектах (Project) и размещающихся в не-
скольких офисах (Office).
Каждый сотрудник имеет план работы (Job), т.е. несколько заданий, которые он
должен выполнить. Для каждого такого задания существует ведомость (Salary
history), содержащая перечень денежных сумм, полученных сотрудником за
выполнение данного задания.
В каждом офисе установлено несколько телефонов (Phone).
452
Часть III. Проектирование базы данных
DEPARTMENT
Рис. 11.19. Иерархическое представление структуры информации о персонале
компании, которая должна храниться в базе данных
В базе данных должна храниться следующая информация.
Для каждого отдела: номер отдела (уникальный), его бюджет и личный номер
сотрудника, возглавляющего отдел (уникальный).
Для каждого сотрудника: личный номер сотрудника (уникальный), номер теку-
щего проекта, номер офиса, номер телефона, а также название выполняемого за-
дания вместе с датой и размером всех выплат, проведенных в качестве оплаты за
выполнение данного задания.
Для каждого проекта: номер проекта (уникальный) и его бюджет.
Для каждого офиса: номер офиса (уникальный), площадь в квадратных футах,
номера (уникальные) всех установленных в нем телефонов.
Составьте соответствующее множество переменных-отношений, необходимое для
представления этой информации. Обоснуйте любые предположения, которые будут
сделаны вами в отношении существующих в них функциональных зависимостей.
11.4. В базе данных системы учета заказов содержится информация о клиентах, деталях
и заказах в соответствии с приведенным ниже описанием.
Для каждого клиента:
номер клиента (уникальный);
адрес доставки (возможно, несколько для одного клиента);
балансовый счет (сумма к оплате);
максимальный размер кредита;
скидка.
Для каждого заказа:
информация в заголовке: номер клиента,
адрес доставки,
дата выполнения заказа;
детальные строки (несколько на один заказ): номер детали,
заказанное количество.
Глава И. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 453
Для каждой детали:
номер детали (уникальный);
заводы-изготовители;
запас деталей на каждом заводе;
минимальное количество деталей на складе для каждого завода;
описание детали.
Для внутреннего учета также вводится величина “оставшееся количество”, связан-
ная с каждой детальной строкой каждого заказа. Исходно эта величина устанавли-
вается равной заказанной количеству данной детали и последовательно уменьша-
ется до нуля по мере частичного выполнения данной поставки. Составьте проект
соответствующей базы данных и, как и в предыдущем упражнении, обоснуйте лю-
бые сделанные предположения о существующих функциональных зависимостях.
11.5. Предположим, что в упр. 11.4 лишь очень незначительная часть клиентов, напри-
мер один процент или даже меньше, имеет более одного адреса доставки. (Это
обычная ситуация в реальной жизни, когда лишь незначительное число исключе-
ний— но достаточно важных— может не вписываться в предлагаемую общую
структуру.) Можете ли вы в этом случае указать на какие-либо недостатки
решения, которое было предложено вами для упр. 11.4? Какие усовершенствова-
ния целесообразно было бы внести для их устранения?
11.6. {Модифицированная версия упр. 10.13.) Переменная-отношение TIMETABLE вклю-
чает следующие атрибуты.
D День недели (1-5)
Р Время в течение дня (1-8)
С Номер аудитории
Т Имя преподавателя
S Имя студента
L Название лекции
Кортеж {D:d, Р:р, С:с, T:t, L:l} будет допустимым для этой переменной-
отношения тогда и только тогда, когда в момент {D:d, Р:р} некоторый студент s по-
сещает лекцию 1, которая читается преподавателем t в аудитории с. Можно предпо-
ложить, что каждая лекция продолжается только один академический час и имеет на-
звание, уникальное по отношению ко всем другим лекциям, читаемым на данной не-
деле. Сделайте структуру переменной-отношения TIMETABLE более приемлемой.
11.7. {Модифицированная версия упр. 10.14.) Дана переменная-отношение NADDR с атри-
бутами NAME (уникальное имя), STREET, CITY, STATE и ZIP. Причем каждому почто-
вому индексу соответствует только один город и штат, а каждой улице, городу и
штату— только один почтовый индекс. Находится ли переменная-отношение
NADDR в НФБК, ЗНФ, 2НФ? Можно ли предложить улучшенный вариант этой пе-
ременной-отношения?
454
Часть III. Проектирование базы данных
Список литературы
Помимо приведенного здесь списка литературы, следует также обратить внимание на
ссылки к главе 10, особенно [10.4, 10.5] (т.е. ссылки на оригинальные статьи Кодда о
1НФ, 2НФиЗНФ).
11.1. Bernstein Р.А. Synthesizing Third Normal Form Relations from Functional
Dependencies // ACM TODS. — December, 1976. — 1, № 4.
В этой главе обсуждались методы декомпозиции больших переменных-отношений в
меньшие. В статье Бернштейна рассматривается обратная задача создания больших
переменных-отношений на основе меньших, сформулированная в несколько иной
форме. В ней поставлена проблема синтеза переменных-отношений, которые нахо-
дятся в ЗНФ, на основе заданных множеств атрибутов и соответствующих наборов
ФЗ. Однако поскольку атрибуты и функциональные зависимости не имеют смысла
вне контекста некоторой переменной-отношения, точнее и строже было бы предста-
вить примитивные конструкции как бинарные переменные-отношения, включающее
ФЗ, а не просто как пару атрибутов и функциональную зависимость между ними.
Замечание. Точно так можно было бы рассмотреть заданное множество атрибутов
и ФЗ как универсальную переменную-отношение [12.9], удовлетворяющую за-
данному множеству зависимостей. В этом случае процесс “синтеза” можно заме-
нить процессом декомпозиции этой универсальной переменной-отношения на про-
екции в ЗНФ. Однако далее в нашем обсуждении будет использоваться интерпре-
тация на основе синтеза.
В такой ситуации процесс синтеза представляет собой процедуру создания п-арных
переменных-отношений на основе бинарных переменных-отношений с заданным
множеством ФЗ, связанных с этими переменными-отношениями, с учетом обяза-
тельного требования, чтобы все вновь созданные переменные-отношения находи-
лись в ЗНФ. (Эта статья была опубликована еще до появления понятия НФБК.) В
данной статье также представлены алгоритмы выполнения этой задачи.
Одним из возражений относительно такого подхода (принятым Бернштейном), яв-
ляется то, что выполняемые на основании предложенного алгоритма синтеза ма-
нипуляции являются чисто синтаксическими и не имеют никакого отношения к се-
мантике. Например, третья из приведенных ниже функциональных зависимостей
может быть, а может и не быть избыточной (т.е. может подразумеваться первой и
второй из них) в зависимости от смысла переменных-отношений R, S и Т.
А -> В (в R{A,B})
В —> С (в 5{В,С})
А —> С (в Т{А,С})
В качестве примера, в котором избыточность отсутствует, допустим, что атрибут А
описывает личный номер сотрудника, атрибут В — номер офиса, атрибут С — но-
мер отдела, отношение R содержит сведения об офисах, в которых работают со-
трудники, отношение S — об отделах, которым принадлежат офисы, а отношение
Т — об отделах, в которых работают сотрудники. Рассмотрим случай, когда неко-
торый сотрудник работает в офисе не своего отдела. Согласно алгоритму синтеза
два атрибута С всегда представляют одно и то же (при этом имена переменных-
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 455
отношений фактически вообще не рассматриваются). Таким образом, предполага-
ется наличие некоторого внешнего механизма (т.е. вмешательство человека), по-
зволяющего предотвратить семантически неверные манипуляции. В нашем приме-
ре следовало бы еще при определении исходных ФЗ использовать для атрибутов из
переменных-отношений S и Т различные имена, например С1 и С2.
11.2. Codd E.F. Recent Investigations into Relational Data Base Systems // Proc. IFIP
Congress. — Stockholm, Sweden, 1974.
Здесь приводится обзор других работ на данную тему, в частности дается
“улучшенное определение третьей нормальной формы”, под которой фактически
подразумевается нормальная форма Бойса-Кодда. Среди других тем можно найти
обсуждение представлений и обновления представлений, подъязыков данных, об-
мена данными и исследований необходимости (по состоянию на 1974 год).
11.3. Date C.J. A Normalization Problem // The Relational J. — 1992. — 4, № 2.
В этой статье рассматривается простая задача нормализации, которая используется
для представления некоторых идей в области составления проекта базы данных и
явного объявления ограничений целостности. Задача сформулирована на основе
простой базы данных некоторой авиакомпании с перечисленными ниже ФЗ, где
приняты следующие обозначения: FLIGHT — название авиарейса, DESTINATION —
место назначения, HOUR — время отправления в часах, DAY — день недели, GATE —
выход для посадки на самолет, PILOT — пилот.
{ FLIGHT } -> DESTINATION
{ FLIGHT } -> HOUR
{ DAY, FLIGHT } -> GATE
{ DAY, FLIGHT } -> PILOT
{ DAY, HOUR, GATE } -> DESTINATION
{ DAY, HOUR, GATE } -> FLIGHT
{ DAY, HOUR, GATE } -> PILOT
{ DAY, HOUR, PILOT } -> DESTINATION
{ DAY, HOUR, PILOT } -> FLIGHT
{ DAY, HOUR, PILOT } -> GATE
Помимо всего прочего, этот пример — прекрасная иллюстрация того, что
“приемлемый” проект базы данных вряд ли может быть создан только на основе
принципов нормализации.
11.4. Heath I.J. Unacceptable File Operations in a Relational Database // Proc. 1971 ACM
SIGFIDET Workshop on Data Description, Access, and Control. — San Diego, Calif.,
November, 1971.
В работе дается определение ЗНФ, которое на самом деле является первым опуб-
ликованным определением НФБК. В ней также приводится доказательство теоре-
мы, которая в разделе 11.2 была названа теоремой Хита. Следует отметить, что
упомянутые в настоящей главе три этапа процедуры нормализации представляют
собой практические воплощения этой теоремы.
11.5. Kent W. A Simple Guide to Five Normal Forms in Relational Database Theory //
CACM. — February, 1983. — 26, № 2.
456
Часть III. Проектирование базы данных
Эта публикация является первоисточником следующей весьма притягательной и
несколько перефразированной характеристики ЗНФ (точнее, НФБК): каждый ат-
рибут должен представлять некоторый факт о ключе, о ключе целиком и ни
о чем более, кроме ключа.
11.6. Rissanen J. Independent Components of Relations // ACM TODS.— December,
1977. —2, №4.
11.7. Zaniolo C. A New Normal Form for the Design of Relational Database Schemata //
Ibid. — September, 1982. — 7, № 3.
Первоисточник элегантных определений ЗНФ и НФБК, упомянутых в этой главе.
Основное назначение статьи — определение новой нормальной формы, нормаль-
ной формы с элементарными ключами (НФЭК), которая занимает промежуточное
положение между ЗНФ и НФБК и “содержит все преимущества обеих этих форм”,
но лишена всех их недостатков (например, ЗНФ является “очень нестрогой”, а
НФБК “склонна к вычислительной сложности”). В статье также показано, что ал-
горитм Бернштейна [11.1] приводит к генерации переменных-отношений, которые
находятся в НФЭК, но не в ЗНФ.
Ответы к упражнениям
11.1. Теорема Хита утверждает, что если переменная-отношение R{A, В, С} удовле-
творяет функциональной зависимости А —> В (где А, В и С являются множества-
ми атрибутов), то R равносильна соединению ее проекций R1 с атрибутами
{А, В} и R2 с атрибутами {А, С}. Далее в этом доказательстве будет использо-
ван сокращенный неформальный вариант записи вида (а, Ь, с) для представ-
ления кортежа {А: а, В:Ь, С:с}.
Сначала следует показать, что ни один кортеж переменной-отношения R не утра-
чивается при разбиении на проекции и обратном соединении этих проекций.
Пусть (а, Ь, с) е R, тогда (а, Ь) 6 R1 и (а, с) 6 R2, а значит, (а, Ь,
с) е Rl JOIN R2. |
Затем следует показать, что каждый кортеж этого соединения действительно явля-
ется кортежем переменной-отношения R (т.е. при соединении не было получено
никаких “побочных” и нежелательных кортежей). Пусть (a, b, с) е Rl JOIN R2.
Тогда для генерации кортежа соединения должны выполняться зависимости (а,
b) е R1 и (а, с) е R2. Следовательно, для генерации кортежа (а, с) 6 R2 для
некоторого атрибута Ь* должен существовать кортеж (a, b*, с) е R. Тогда дол-
жен также существовать кортеж (a, b*) G R1. Теперь у нас есть (a, b) G R1 и
(a, b*) g R1, а поскольку А —> В, значит, b=b*. Отсюда (a, b, с) € R. |
Теорема, обратная теореме Хита, утверждает, что если переменная-отношение
R{A, В, С} равносильна соединению ее проекций R1 с атрибутами {А, В} и R2 с
атрибутами {А, С}, то R удовлетворяет зависимости А —> В. Это утверждение не-
верно. В качестве примера переменной-отношения, которая равняется соединению
двух ее проекций и вовсе не удовлетворяет никакой нетривиальной ФЗ, можно
предложить переменную-отношение СТХ, которая показана на рис. 12.2.
Глава И. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 457
11.2. Это утверждение почти (но не совсем) верно. Приведенный ниже экзотический пример
обратной ситуации взят из [5.5]. Рассмотрим переменную-отношение USA {COUNTRY,
STATE}, которая интерпретируется как “STATE (штат) является членом COUNTRY (стра-
ны)”, где под страной в каждом кортеже подразумеваются Соединенные Штаты Аме-
рики. Тогда в данной переменной-отношении будет выполняться приведенная ниже ФЗ.
{ } -> COUNTRY
А поскольку пустое множество { } не является потенциальным ключом, перемен-
ная-отношение USA не находится в НФБК (она может быть декомпозирована без
потерь на две унарные проекции, хотя остается спорным утверждение о том, что
она может быть подвергнута дальнейшей нормализации).
Попутно следует заметить, что в общем случае вполне возможно существование
потенциального ключа, который является пустым множеством! Подробности
можно найти в ответе к упр. 8.7 из главы 8.
11.3. На рис. 11.20 показаны все наиболее важные функциональные зависимости: как те,
которые подразумевались в упражнении, так и те, которые соответствуют разум-
ным семантическим утверждениям (они перечислены ниже). Атрибутам присвоены
имена, поясняющие их значения.
Семантические утверждения
Ни один сотрудник не является руководителем одновременно нескольких отделов.
Ни один сотрудник не работает одновременно более чем в одном отделе.
Ни один сотрудник не работает одновременно более чем с одним проектом.
Ни один сотрудник не имеет одновременно более одного офиса.
Ни один сотрудник не имеет одновременно более одного телефона.
Ни один сотрудник не имеет одновременно более одного задания.
Ни один проект не выполняется одновременно более чем одним отделом.
Ни один офис не принадлежит одновременно более чем одному отделу.
Этап 0. Определение структуры исходной переменной-отношения
Прежде всего отметим, что исходную иерархическую структуру можно рассматри-
вать как ненормализованную переменную-отношение DEPTO с атрибутами, содер-
жащими значения типа отношений.
458
Часть III. Проектирование базы данных
DEPTO { DEPT#, DBUDGET, MGR EMP#, XEMPO, XPROJO, XOFFICEO }
KEY { DEPT# }
KEY { MGR_EMP# }
Здесь смысл атрибутов DEPT# (номер отдела), DBUDGET (бюджет) и MGR_EMP#
(личный номер руководителя отдела) ясен из их названий, а домены, соответст-
вующие атрибутам ХЕМРО (сотрудник), XPROJO (проект) и XOFFICEO (офис), состо-
ят из значений, представляющих собой отношения, и нуждаются в дополнитель-
ных разъяснениях.
Значение атрибута XPROJO в составе каждого кортежа переменной-отношения
DEPT0 представляет собой отношение с атрибутами PROJ# и PBUDGET.
Аналогично значение атрибута XOFFICEO в составе каждого кортежа переменной-
отношения DEPT0 представляет собой отношение с атрибутами OFF#, AREA и, ска-
жем, XPHONEO, где атрибут XPHONEO, в свою очередь, имеет значения, представ-
ляющие собой отношения. Отношения, являющиеся значениями атрибута
XPHONEO, имеют только один атрибут PHONE#.
Наконец, значение атрибута ХЕМРО в составе каждого кортежа переменной-
отношения DEPT0 представляет собой отношение с атрибутами ЕМР#, PROJ#,
OFF#, PHONE# и, скажем, XJOBO, где атрибут XJOBO, в свою очередь, имеет зна-
чения, представляющие собой отношения. Отношения, являющиеся значения-
ми атрибута XJOBO, имеют атрибуты JOBTITLE и, скажем, XSALHISTO, где атри-
бут XSALHISTO, опять же, имеет значения, представляющие собой отношения.
Отношения, являющиеся значениями атрибута XSALHISTO, содержат атрибуты
DATE и SALARY.
Таким образом, вся иерархия может быть представлена следующей вложенной
структурой.
DEPTO { DEPT#, DBUDGET, MGR ЕМР#,
XEMPO { EMP#, PROJ#? OFF#, PHONE#,
XJOBO { JOBTITLE,
XSALHISTO { DATE, SALARY } } },
XPROJO { PROJ#, PBUDGET },
XOFFICEO { OFF#, AREA, XPHONEO { PHONE# } } }
Замечание. Вместо описания потенциальных ключей здесь использовано выде-
ление курсивом для обозначения тех атрибутов, которые по крайней мере
“уникальны внутри родителя” (на самом деле атрибуты DEPT#, ЕМР#, PROJ#,
OFF# и PHONE# являются глобально уникальными согласно утверждениям, сде-
ланным выше).
Этап 1. Исключение атрибутов, содержащих значения-отношения
Для простоты предположим, что каждая переменная-отношение имеет первичный
ключ, т.е. всегда на каком-то основании (не важно, на каком) можно выбрать один
из потенциальных ключей в качестве первичного. В частности, для переменной-
отношения DEPTO в качестве первичного ключа выберем атрибут DEPT# (таким об-
разом, атрибут MGR EMP# становится альтернативным ключом).
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 459
Теперь можно приступить к исключению из переменной-отношения DEPT0 атрибу-
тов, содержащих значения-отношения, поскольку (как отмечалось в разделе 11.6)
они являются нежелательными13.
Для каждого атрибута переменной-отношения DEPT0, значениями которого являют-
ся отношения (т.е. для атрибутов ХЕМРО, XPROJO и XOFFICEO), создадим новую пере-
менную-отношение с атрибутами, состоящими из атрибутов соответствующего от-
ношения плюс атрибут первичного ключа переменной-отношения DEPT0. Первич-
ным ключом каждой из вновь созданных расширенных переменных-отношений бу-
дет комбинация того атрибута, который в исходном отношении являлся
“уникальным внутри родителя”, и первичного ключа переменной-отношения DEPT0.
(Обратите внимание, что многие из созданных “первичных ключей” содержат атри-
буты, которые являются избыточными для уникальной идентификации кортежей;
впоследствии они будут исключены.) Удаляем атрибуты ХЕМРО, XPROJO и XOFFICEO
из переменной-отношения DEPT0.
Если какая-либо переменная-отношение R все еще имеет какие-либо атрибуты, зна-
чениями которых являются отношения, то описанную последовательность действий
для этой переменной-отношения R необходимо повторить.
После выполнения указанных действий будет получен приведенный ниже набор
переменных-отношений, из которых исключены все атрибуты, содержащие зна-
чения-отношения. Обратите внимание на то, что полученные переменные-
отношения, безусловно, находятся в 1НФ, но необязательно в какой-то более вы-
сокой нормальной форме.
DEPT1 { DEPT#, DBUDGET, MGR EMP# }
PRIMARY KEY { DEPT#
ALTERNATE KEY { MGR_EMP# }
EMP1 { DEPT#, EMP#, PROJ#, OFF#, PHONE# }
PRIMARY KEY { DEPT#, EMP# }
JOB1 { DEPT#, EMP#, JOBTITLE }
PRIMARY KEY { DEPT#, EMP#, JOBTITLE }
SALHISTI { DEPT#, EMP#, JOBTITLE, DATE, SALARY }
PRIMARY KEY { DEPT#, EMP#, JOBTITLE, DATE }
PROJI { DEPT#, PROJ#, PBUDGET }
PRIMARY KEY { DEPT#, PROJ# }
13 Заметим, что представленная здесь процедура исключения атрибутов, значениями кото-
рых являются отношения, предусматривает многократное выполнение оператора UNGROUP (см.
главу 6, раздел 1.6), повторяющееся до тех пор, пока необходимый результат не будет достиг-
нут. В этой связи описанная процедура гарантирует, что одновременно исключаются все те
многозначные зависимости, которые не являются функциональными. Поэтому полученные в ре-
зультате выполнения предложенной процедуры переменные-отношения на самом деле находятся
в 4НФ, а не в НФБК (см. главу 12).
460
Часть III Проектирование базы данных
0FFICE1 { DEPT#, OFF#, AREA }
PRIMARY KEY { DEPT#, OFF# }
PHONE1 { DEPT#, OFF#, PHONE# }
PRIMARY KEY { DEPT#, OFF#, PHONE# }
Этап 2. Приведение отношений к 2НФ
Теперь переменные-отношения, находящиеся в 1НФ, можно привести к эквива-
лентной совокупности переменных-отношений в 2НФ, исключив те функциональ-
ные зависимости, которые не являются неприводимыми. Ниже все такие перемен-
ные-отношения рассматриваются последовательно одна за другой.
DEPT1 Эта переменная-отношение уже находится в 2НФ.
ЕМР1 Прежде всего следует отметить, что атрибут DEPT# является избыточным
компонентом первичного ключа данной переменной-отношения. В каче-
стве первичного ключа здесь можно принять атрибут ЕМР#, причем в та-
ком виде данная переменная-отношение уже будет находиться в 2НФ.
JOB1 Опять отметим, что необязательно использовать атрибут DEPT# в качест-
ве компонента первичного ключа. Поскольку атрибут DEPT# функцио-
нально зависит от атрибута ЕМР#, имеется неключевой атрибут (DEPT#),
зависимость которого от первичного ключа (комбинации атрибутов
{ЕМР#, JOBTITLE}) не является неприводимой и, следовательно, пере-
менная-отношение JOB1 не находится во 2НФ. Эту переменную-
отношение можно заменить двумя другими.
JOB2A { ЕМР#, JOBTITLE }
PRIMARY KEY { ЕМР#, JOBTITLE }
JOB2B { ЕМР#, DEPT# }
PRIMARY KEY { EMP# }
Однако переменная-отношение JOB 2 А является проекцией переменной-
отношения SALHIST2 (ниже это описано подробнее), а переменная-
отношение JOB2B— проекцией переменной-отношения ЕМР1 (ниже она
будет переименована в ЕМР 2). Следовательно, обе вновь созданные пере-
менные-отношения могут быть просто удалены.
SALHIST1 Так же, как и в случае переменной-отношения JOB1, атрибут DEPT#
можно полностью удалить. Более того, как компонент первичного
ключа атрибут JOBTITLE не требуется. В качестве первичного ключа
достаточно использовать комбинацию атрибутов {ЕМР#, DATE}. В ре-
зультате будет получена следующая переменная-отношение, находя-
щаяся в 2НФ.
SALHIST2 { ЕМР#, DATE, JOBTITLE, SALARY }
PRIMARY KEY { EMP#, DATE }
PRO Л Так же, как и в случае с переменной-отношением ЕМР1, можно рассмат-
ривать атрибут DEPT# как неключевой, причем данная переменная-
отношение будет находиться в 2НФ.
OFFICE1 Здесь можно применить аналогичное рассуждение.
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 461
PH0NE1 Атрибут DEPT# можно удалить совсем, поскольку переменная-отношение
(DEPT#, OFF#) является проекцией переменной-отношения OFFICE1
(переименованной далее в OFFICE2). Кроме того, атрибут OFF# функцио-
нально зависит от атрибута PHONE#, поэтому в качестве первичного клю-
ча достаточно принять только атрибут PHONE#, в результате чего будет
получена приведенная ниже переменная-отношение в 2НФ.
PHONE2 { PHONE#, OFF# }
PRIMARY KEY { PHONE# }
Обратите внимание, что эта переменная-отношение необязательно яв-
ляется проекцией переменной-отношения ЕМР2 (телефоны и офисы мо-
гут существовать и без их соотнесения с конкретными сотрудниками),
поэтому ее нельзя удалить.
Таким образом, мы получили следующий набор переменных-отношений в 2НФ.
DEPT2 { DEPT#, DBUDGET, MGR_EMP# }
PRIMARY KEY { DEPT# }”
ALTERNATE KEY { MGRJEMP# }
EMP2 { EMP#, DEPT#, PROJ#, OFF#, PHONE# }
PRIMARY KEY { EMP# }
SALHIST2 { EMP#, DATE, JOBTITLE, SALARY }
PRIMARY KEY { EMP#, DATE }
PROJ2 { PROJ#, DEPT#, PBUDGET }
PRIMARY KEY { PROJ# }
OFFICE2 { OFF#, DEPT#, AREA }
PRIMARY KEY { OFF# }
PHONE2 { PHONE#, OFF# }
PRIMARY KEY { PHONE# }
Этап 3. Приведение к ЗНФ
Теперь можно привести переменные-отношения, находящиеся в 2НФ, к эквивалент-
ному набору переменных-отношений в ЗНФ, для чего необходимо исключить тран-
зитивные зависимости. Единственной переменной-отношением, которая находится в
2НФ и не находится в ЗНФ, является переменная-отношение ЕМР2, в которой атрибу-
ты OFF# и DEPT# транзитивно зависят от первичного ключа ЕМР#: атрибут OFF# через
атрибут PHONE#, а атрибут DEPT# — через атрибут PROJ#, а также через атрибут OFF#
(следовательно, и через атрибут PHONE#). Таким образом, переменной-отношению
ЕМР2 соответствует следующий набор переменных-отношений (проекций) в ЗНФ.
ЕМРЗ { ЕМР#, PROJ#, PHONE# }
PRIMARY KEY { EMP# }
X { PHONE#, OFF# }
PRIMARY KEY { PHONE# }
462
Часть III. Проектирование базы данных
Y { PROJ#, DEPT# }
PRIMARY KEY { PROJ# }
Z { OFF#, DEPT# }
PRIMARY KEY { OFF# }
Однако переменная-отношение X — это аналог переменной-отношения PHONE2, пе-
ременная-отношение Y — это проекция переменной-отношения PROJ2, а перемен-
ная-отношение Z — это проекция переменной-отношения OFFICE2. Следовательно,
окончательная совокупность переменных-отношений в ЗНФ будет выглядеть сле-
дующим образом.
DEPT3 { DEPT#, DBUDGET, MGR_EMP# }
PRIMARY KEY { DEPT# }
ALTERNATE KEY { MGR_EMP# }
EMP3 { EMP#, PROJ#, PHONE# }
PRIMARY KEY { EMP# }
SALHIST3 { EMP#, DATE, JOBTITLE, SALARY }
PRIMARY KEY { EMP#, DATE }
PROJ3 { PROJ#, DEPT#, PBUDGET }
PRIMARY KEY { PROJ# }
OFFICE3 { OFF#, DEPT#, AREA }
PRIMARY KEY { OFF# }
PHONE3 { PHONE#, OFF# }
PRIMARY KEY { PHONE# }
Наконец, отметим, что каждая из этих переменных-отношений в ЗНФ уже находит-
ся в НФБК. |
Следует указать на то, что при учете некоторых (разумных) дополнительных семан-
тических ограничений этот набор переменных-отношений становится сильно избы-
точным [5.1], так как проекция переменной-отношения PROJ3 по атрибутам
{PROJ#, DEPT#} практически всегда эквивалентна проекции, выполненной для ре-
зультата соединения переменных-отношений ЕМРЗ, PHONE3 и OFFICE3.
В заключение отметим, что полученный набор переменных-отношений в НФБК
можно было “выделить” непосредственно на диаграмме ФЗ. (Вопрос. Как именно
это можно сделать?)
Замечание. Это не значит, что “выделить” результирующий набор переменных-
отношений в НФБК можно всегда', на самом деле определить результаты декомпо-
зиции подобным образом можно лишь в некоторых конкретных случаях. Точнее
говоря, для данной переменной-отношения R, удовлетворяющей множеству функ-
циональных зависимостей S, представленный ниже алгоритм (этапы 0-8) гаранти-
рует декомпозицию D переменной-отношения R на переменные-отношения в ЗНФ
(но не НФБК), которая выполняется одновременно без потерь информации и с со-
хранением зависимостей.
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 463
0. В качестве начального значения для декомпозиции D зададим пустое множество.
1. Пусть множество I является неприводимым покрытием для множества функ-
циональных зависимостей S.
2. Пусть X является множеством атрибутов в левой части некоторой зависимости
X —> Y, входящей в множество I.
3. Пусть полное множество ФЗ в I с левой частью, равной множеству атрибутов X,
состоит из зависимостей X —» Yl, X —» Y2,X —» Yn.
4. Пусть Z является объединением множеств атрибутов Yl, Y2,..., Yn.
5. Заменим декомпозицию D объединением текущего значения D с проекцией пе-
ременной-отношения R по атрибутам X и Z.
6. Повторим пп. 3-5 для каждого атрибута из множества X.
7. Пусть Al, А2,..., Ап являются неучтенными до сих пор атрибутами переменной-
отношения R (т.е. такими, которые еще не включены в какую-либо из перемен-
ных-отношений в множестве D). Заменим декомпозицию D объединением теку-
щего значения D с проекцией переменной-отношения R по атрибутам
Al, А2,..., Ап.
8. Если ни одна из переменных-отношений в декомпозиции D не содержит потенци-
ального ключа R, заменим декомпозицию D объединением текущего значения D с
проекцией переменной-отношения R по ее некоторому потенциальному ключу.
В приведенном ниже алгоритме гарантируется получение декомпозиции D пере-
менной-отношения R на переменные-отношения в НФБК, которая выполняется без
потерь информации, но необязательно с сохранением зависимостей.
0. Зададим в качестве начального значения для декомпозиции D переменную-
отношение R.
1. Для каждой переменной-отношения Т (которая не находится в НФБК) из соста-
ва декомпозиции D выполним действия, перечисленные в пп. 2 и 3.
2. Пусть X —» Y является функциональной зависимостью в переменной-отношении
Т, в которой нарушаются некоторые требования НФБК.
3. Заменим переменную-отношение Т в декомпозиции D двумя проекциями, а имен-
но: одной по атрибутам X и Y, а другой — по всем атрибутам, за исключением Y.
Возвращаясь к примеру с персоналом компании, можно предложить читателю еще
одно упражнение, которое относится не только к самой процедуре нормализации, но
и к проектированию базы данных в целом. Попробуйте расширить описанный выше
макет базы данных, включив в него все необходимые определения внешних ключей.
11.4. На рис. 11.21 показаны наиболее важные функциональные зависимости, а соответ-
ствующие семантические допущения приведены ниже.
Никакие два клиента не имеют одинаковых адресов доставки.
Каждый заказ имеет уникальный номер.
Каждая детальная строка заказа характеризуется номером строки, уникальным
для данного заказа.
464
Часть III. Проектирование базы данных
Рис. 11.21. Диаграмма зависимостей для у пр. 11.4
Соответствующий набор переменных-отношений в НФБК будет выглядеть прибли-
зительно так.
CUST { CUST#, BAL, CREDLIM, DISCOUNT }
PRIMARY KEY { CUST# }
SHIPTO { ADDRESS, CUST# }
PRIMARY KEY ( ADDRESS )
ORDHEAD { ORD#, ADDRESS, DATE }
PRIMARY KEY { ORD# }
ORDLINE { ORD#, LINE#, ITEM#, QTYORD, QTYOUT }
PRIMARY KEY { ORD#, LINE# }
ITEM { ITEM#, DESCN }
PRIMARY KEY { ITEM# }
IP { ITEM#, PLANT#, QTYOH, DANGER }
PRIMARY KEY { ITEM#, PLANT# }
11.5. Рассмотрим процесс обработки заказов, который должен выполняться про-
граммой учета заказов. Предположим, что в поступившем заказе указан номер
клиента, адрес доставки и характеристики заказанной детали (номер детали и
ее количество).
RETRIEVE CUST WHERE CUST# = input.CUST# ;
< проверка остатка на счету, установленного размера кредита и т.д.> ;
RETRIEVE SHIPTO WHERE ADDRESS = input.ADDRESS ;
AND CUST# = input.CUST#
Глава И. Дальнейшая нормализация: формы ШФ, 2НФ, ЗНФ и НФБК 465
/* проверка адреса доставки */ ;
IF <все в порядке>, THEN <продолжить обработку заказов> ; END IF;
Если 99% клиентов имеют только один адрес доставки, было бы весьма неэф-
фективно помещать адрес в какую-либо другую переменную-отношение, кроме
CUST (если рассматривать только эти 99%, то ADDRESS функционально зависит от
CUST#). Исправить ситуацию можно следующим образом. Для каждого клиента
укажем один адрес доставки в качестве первичного адреса, который для 99%
клиентов будет единственным. Любые другие адреса будут рассматриваться как
вторичные. Тогда переменную-отношение CUST можно переопределить следую-
щим образом.
CUST { CUST#, ADDRESS, BAL, CREDLIM, DISCOUNT }
KEY { CUST# }
А переменную-отношение SHIPTO можно заменить такой переменной-отношением.
SECOND { ADDRESS, CUST# }
KEY { ADDRESS }
Здесь переменная-отношение CUST содержит первичные адреса, а переменная-
отношение SECOND— вторичные адреса (и соответствующие номера клиентов).
Обе переменные-отношения находятся в НФБК. Программа обработки заказов в
этом случае будет выглядеть следующим образом.
RETRIEVE CUST WHERE CUST# = input.CUST# ;
<проверка остатка на счету, установленного размера кредита и т.д.> ;
IF CUST.ADDRESS # input.ADDRESS THEN
RETRIEVE SECOND WHERE ADDRESS = input.ADDRESS ;
AND CUST# = input.CUST#
/* проверка адреса доставки */ ;
END IF;
IF <все в порядке>, THEN <продолжить обработку заказов> ; END IF;
Ниже перечислены некоторые преимущества такого подхода.
Для 99% клиентов обработка заказов становится проще и эффективнее.
Если в поступающем заказе опущен адрес доставки, то по умолчанию будет ис-
пользован первичный адрес.
Предположим, что клиент имеет различные скидки для разных адресов достав-
ки. При первом подходе (показанном в виде ответа к предыдущему упражне-
нию) атрибут DISCOUNT должен быть помещен в переменную-отношение
SHIPTO, что приводит к значительному усложнению обработки заказов. Однако
при усовершенствованном подходе первичная скидка (соответствующая пер-
вичному адресу) может быть представлена посредством введения атрибута
DISCOUNT в переменную-отношение CUST, а вторичная скидка— путем введе-
ния атрибута DISCOUNT в переменную-отношение SECOND. При этом обе пере-
менные-отношения все еще остаются в НФБК, а обработка заказов упрощается
для 99% клиентов.
466
Часть III. Проектирование базы данных
В заключение следует отметить, что выделение исключительных случаев является,
вероятно, хорошим методом использования лучших свойств обоих подходов, т.е.
сочетания преимуществ НФБК с упрощением операций выборки данных, которые
могут возникнуть при нарушении ограничений НФБК.
11.6. На рис. 11.22 показаны наиболее важные функциональные зависимости; возмож-
ный набор переменных-отношений приведен ниже.
Рис. 11.22. Диаграмма функциональных зависимостей для упр. 11.6
SCHED { L, Т, С, D, Р }
KEY { L }
KEY { Т, D, Р }
KEY { С, D, Р }
STUDY { S, L }
KEY { S, L }
11.7. Переменная-отношение NADDR находится в 2НФ, но не в ЗНФ (и, следовательно, не
в НФБК). Усовершенствованный вариант может иметь следующий вид.
NSZ { NAME, STREET, ZIP }
KEY { NAME }
ZCS { ZIP, CITY, STATE }
KEY { ZIP }
Обе переменные-отношения находятся в НФБК, однако следует принять во внима-
ние перечисленные ниже замечания.
Поскольку атрибуты STREET (улица), CITY (город) и STATE (штат) почти всегда
используются совместно (например, при создании списка рассылки), а почтовые
индексы меняются не очень часто, приведенная выше декомпозиция вряд ли по-
требуется. (Иначе говоря, нормализацию следует выполнять по отношению к
подходящ им для этого зависимостям, а не ко всем без исключения.)
В частности, при извлечении полного адреса для заданного в атрибуте NAME
имени потребуется выполнить соединение (хотя явное выполнение этого со-
единения можно заменить определением переменной-отношения NADDR как
представления на базе переменных-отношений NSZ и ZCS). Иначе говоря, нор-
Глава 11. Дальнейшая нормализация: формы 1НФ, 2НФ, ЗНФ и НФБК 467
мализация до уровня НФБК хороша для обновления, но плоха для извлечения
данных, поскольку избыточность, которая имеет место при отсутствии полной
нормализации, способна вызвать проблемы, связанные с обновлением, но мо-
жет оказаться весьма полезной при извлечении данных14. Трудности вызыва-
ются лишь неконтролируемой избыточностью, тогда как контролируемая из-
быточность (т.е. избыточность, которая известна и контролируется СУБД) в
некоторых ситуациях может быть вполне приемлемой.
Функциональная зависимость { STREET, CITY, STATE } —> ZIP явно не пред-
ставлена в этом макете, а поддерживается отдельно: либо декларативно (если в
СУБД поддерживается декларативный язык указания ограничений целостно-
сти, аналогичный языку, кратко описанному в главе 8), либо процедурно. На
самом деле переменные-отношения NSZ и ZCS не являются независимыми в
смысле определения Риссанена [11.6].
14 С другой стороны, такая избыточность может значительно усложнить некоторые вари-
анты выборки данных (т е привести к замедлению выполнения соответствующих запросов),
что будет показано в разделе 12 5 в следующей главе.
468
Часть III Проектирование базы данных
Глава
Дальнейшая нормализация:
более высокие нормальные
формы
12.1. Введение
В предыдущей главе были описаны основные идеи дальнейшей нормализации вплоть
до нормальной формы Бойса-Кодда (НФБК) включительно (т.е. до формы, которой можно
достичь, используя понятие функциональной зависимости). В этой главе обсуждение во-
проса дальнейшей нормализации завершается рассмотрением четвертой и пятой нор-
мальных форм (4НФ и 5НФ). Как будет показано ниже, для определения 4НФ необходимо
ввести понятие многозначной зависимости (МЗЗ), которое является обобщением понятия
функциональной зависимости. Аналогично для определения понятия 5НФ необходимо вве-
сти новый тип зависимости, которая называется зависимостью соединения (ЗС). Она яв-
ляется обобщением понятия многозначной зависимости подобно тому, как многозначная
зависимость является обобщением понятия функциональной зависимости. В разделе 12.2
будут рассмотрены понятия многозначной зависимости и 4НФ, в разделе 12.3 — понятия
зависимости соединения и 5НФ; также будет разъяснено, почему 5НФ в некотором смысле
можно считать окончательной нормальной формой. Сразу же следует отметить, что описа-
ния многозначной зависимости и зависимости соединения будут менее формальными и
полными, чем описание функциональных зависимостей, данное в главе 10. Более подроб-
ную информацию заинтересованный читатель может найти в работах, представленных в
списке рекомендуемой литературы в конце этой главы.
После описания основных понятий в разделе 12.4 дается обзор процедуры нормализации в
целом с дополнительными комментариями. Затем в разделе 12.5 кратко обсуждается понятие
денормализации. В разделе 12.6 описывается еще один важный принцип проектирования —
ортогональное проектирование (orthogonal design). Наконец, в разделе 12.7 коротко обсуж-
даются некоторые возможные направления будущих исследований в области нормализации, а
заключительный раздел 12.8 представляет собой краткое резюме всей главы.
12.2. Многозначные зависимости и четвертая
нормальная форма
Пусть дана переменная-отношение НСТХ (где Н обозначает “иерархическая” (hierarchic)),
содержащая информацию о курсах обучения, преподавателях и учебниках. В этой перемен-
ной-отношении атрибуты, описывающие преподавателей и учебники, принимают в качестве
значений отношения (рис. 12.1). Каждый кортеж переменной-отношения НСТХ состоит из ат-
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 469
рибутов названия курса (COURSE), а также атрибута-отношения с именами преподавателей
(TEACHERS) и атрибута-отношения с названиями учебников (TEXTS) (на рис. 12.1 показаны два
таких кортежа). Смысл каждого кортежа состоит в том, что соответствующий курс может
преподаваться любым из указанных преподавателей с использованием всех указанных учеб-
ников. Предположим, что для заданного курса может быть определено произвольное количе-
ство соответствующих преподавателей и учебников. Более того, допустим, хотя это и не со-
всем реалистичное допущение, что преподаватели и рекомендуемые учебники совершенно
независимы друг от друга. Это значит, что независимо от того, кто преподает данный курс,
всегда используется один и тот же набор учебников. Наконец, допустим, что определенный
преподаватель или определенный учебник может быть связан с любым количеством курсов.
COURSE TEACHERS TEXTS
Physics TEACHER TEXT
Prof. Green Basic Mechanics
Prof. Brown Principles of Optics
Math TEACHER TEXT
Prof. Green Basic Mechanics
Vector Analysis
Trigonometry
Рис. 12.1. Пример значений данных в переменной-отношении НСТХ
Пусть необходимо (как в разделе 11.6 предыдущей главы) исключить атрибуты, прини-
мающие в качестве значений отношения. Один из способов (но не тот, который описан в от-
вете к упр. 11.3; к нему мы вернемся в конце этого раздела) заключается в простой замене пе-
ременной-отношения НСТХ переменной-отношением СТХ с тремя скалярными атрибутами,
COURSE, TEACHER и TEXT, как показано на рис. 12.2. Как видно из этого рисунка, каждый кортеж
исходной переменной-отношения НСТХ порождает т *п кортежей в переменной-отношении
СТХ, где т и п являются значениями кардинальности для отношений TEACHERS и TEXTS в дан-
ном кортеже переменной-отношения НСТХ. Обратите внимание, что все атрибуты результи-
рующей переменной-отношения СТХ входят в состав ее ключа (в отличие от переменной-
отношения НСТХ, потенциальный ключ которой {COURSE} состоял из единственного атрибута).
СТХ
COURSE TEACHER TEXT
Physics Prof. Green Basic Mechanics
Physics Prof. Green Principles of Optics
Physics Prof. Brown Basic Mechanics
Physics Prof. Brown Principles of Optics
Math Prof. Green Basic Mechanics
Math Prof. Green Vector Analysis
Math Prof. Green Trigonometry
Рис. 12.2. Набор значений данных в переменной-отношении СТХ, эквивалентный приве-
денному выше примеру значений данных в переменной-отношении НСТХ
470
Часть III. Проектирование базы данных
Данные, помещаемые в переменную-отношение СТХ, имеют следующий смысл: кор-
теж {COURSE:с, TEACHER:t, ТЕХТ:х} появляется в переменной-отношении СТХ тогда и
только тогда, когда курс с читается преподавателем t с использованием учебника х. То-
гда, принимая во внимание, что для каждого курса указаны все возможные комбинации
имени преподавателей и названий учебников, можно утверждать, что для переменной-
отношения СТХ верно следующее ограничение.
ЕСЛИ кортежи (c,tl,xl) и (c,t2 ,х2) присутствуют одновременно,
ТО кортежи (с, 11, х2) и (с, 12, х 1) также присутствуют одновременно.
(В данном случае для представления кортежей вновь использована сокращенная за-
пись без указания имен атрибутов.)
Очевидно, что переменная-отношение СТХ характеризуется значительной избыточно-
стью, вследствие чего возникнут аномалии обновления. Например, для добавления ин-
формации о том, что курс физики может читаться новым преподавателем, необходимо соз-
дать два новых кортежа, по одному для каждого используемого учебника. Как можно из-
бежать появления таких проблем? Здесь нетрудно заметить две следующие особенности.
1. Рассматриваемые проблемы возникают в результате того, что преподаватели и
учебники совершенно не зависят друг от друга.
2. Ситуацию можно существенно улучшить, если выполнить декомпозицию перемен-
ной-отношения СТХ на две проекции (например, с именами СТ и СХ) с атрибутами
{COURSE, TEACHER} и {COURSE, TEXT} соответственно (рис. 12.3).
СТ СХ
COURSE TEACHER
Physics Prof. Green
Physics Prof. Brown
Math Prof. Green
COURSE TEXT
Physics Physics Math Math Math Basic Mechanics Principles of Optics Basic Mechanics Vector Analysis Trigonometry
Рис. 12.3. Значения данных в проекциях СТ и СХ, которые соответствуют содержанию
переменной-отношения СТХ, показанному на рис. 12.2
В этом случае для добавления новой информации о том, что курс физики будет чи-
таться новым преподавателем, достаточно вставить единственный кортеж в перемен-
ную-отношение СТ. (Отметим также, что переменная-отношение СТХ может быть вос-
становлена за счет обратного соединения проекций СТ и СХ, и потому данная декомпо-
зиция была выполнена без потерь.) Таким образом, вполне разумно было бы предпо-
ложить, что для переменных-отношений, подобных СТХ, существует некий способ
“дальнейшей нормализации”.
Замечание. Здесь читатель может возразить, что избыточность данных в переменной-
отношении СТХ вовсе не была необходимой по определению, а потому соответствующие
ей аномалии обновления также совершенно необязательно были неизбежны. Точнее го-
воря, можно предположить, что для описания некоторого курса в переменную-отно-
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 471
шение СТХ необязательно включать все возможные комбинации “преподаватель — учеб-
ник”. Например, двух кортежей вполне достаточно, чтобы показать, что курс физики
преподается двумя преподавателями с использованием двух учебников. Проблема за-
ключается в том, какие именно два кортежа следует выбрать? Любой вариант выбора
приводит к переменной-отношению с совершенно неочевидной интерпретацией и до-
вольно странным характером обновления. (Попробуйте подобрать предикат для такой
переменной-отношения, т.е. задать критерии приемлемости для данной переменной-
отношения операции обновления того или иного типа.)
С неформальной точки зрения очевидно, что переменная-отношение СТХ спроекти-
рована плохо и ее декомпозиция на проекции СТ и СХ является более удачным решени-
ем. Но проблема в данном случае заключается в том, что с формальной точки зрения
это совсем неочевидно. Заметим, в частности, что переменная-отношение СТХ вообще
не имеет функциональных зависимостей (за исключением таких тривиальных, как
COURSE —> COURSE). Фактически переменная-отношение СТХ находится в НФБК, по-
скольку, как отмечалось ранее, все ее атрибуты входят в состав ее ключа, а любая по-
добная переменная-отношение обязательно находится в НФБК. (Обратите внимание на
то, что и проекции СТ и СХ являются полностью ключевыми, а потому также находятся
в НФБК.) Следовательно, изложенные в предыдущей главе идеи никак не могут по-
мочь в разрешении этой проблемы.
Существование “проблем”, которые связаны с переменными-отношениями в НФБК,
подобными переменной-отношению СТХ, было замечено достаточно давно, и способы их
разрешения также вскоре были определены, по крайней мере интуитивно. Однако только
в 1971 году эти идеи были сформулированы Фейгином (Fagin) в строгом теоретическом
виде с использованием понятия многозначной зависимости, или МЗЗ [12.13]. Много-
значную зависимость можно считать обобщением понятия функциональной зависимости
в том смысле, что каждая функциональная зависимость также является многозначной
(однако обратное утверждение неверно, поскольку существуют многозначные зависимо-
сти, которые не являются функциональными). В переменной-отношении СТХ есть две
многозначные зависимости.
COURSE TEACHER
COURSE TEXT
Обратите внимание на двойную стрелку, которая в многозначной зависимости А —>-> В оз-
начает, что В многозначно зависит от А или А многозначно определяет В. Первая из
этих зависимостей, COURSE —н TEACHER, означает, что, хотя для каждого курса не су-
ществует одного соответствующего только ему преподавателя, т.е. не выполняется функ-
циональная зависимость COURSE —> TEACHER, каждый курс имеет вполне определенное
множество соответствующих преподавателей (в общем случае их может быть
несколько). Если говорить точнее, под понятием “вполне определенное множество” в
нашем случае подразумевается, что для данного курса с и данного учебника х множество
преподавателей t, соответствующее паре (с, х) переменной-отношения СТХ, зависит от
значения с и совершенно не зависит от значения х. Вторая многозначная зависимость
имеет аналогичную интерпретацию.
Исходя из изложенного, можно привести формальное определение многозначной
зависимости.
472
Часть III Проектирование базы данных
Пусть А, В и С являются произвольными подмножествами множества атрибутов
переменной-отношения R. Тогда подмножество В многозначно зависит от под-
множества А, что символически выражается записью
А В
(читается как “А многозначно определяет В” или “А двойная стрелка В”), тогда и
только тогда, когда множество значений В, соответствующее заданной паре
(значение А, значение С) переменной-отношения R, зависит от А, но не зависит от С.
Нетрудно показать (это обсуждается в работе Фейгина [12.13]), что для данной пере-
менной-отношения R{А, В, С} многозначная зависимость А —» В выполняется тогда и
только тогда, когда также выполняется многозначная зависимость А -» С. Таким обра-
зом, многозначные зависимости всегда образуют связанные пары, поэтому обычно их
представляют вместе в символическом виде.
А -в В | С
Для рассматриваемого примера такая запись будет иметь следующий вид.
COURSE -» TEACHER | TEXT
Ранее уже утверждалось, что многозначные зависимости являются обобщениями
функциональных зависимостей в том смысле, что всякая функциональная зависимость
является многозначной. Точнее говоря, функциональная зависимость— это многознач-
ная зависимость, в которой множество зависимых значений, соответствующее заданному
значению детерминанта, всегда является одноэлементным множеством. Таким образом,
если А —> В, то А —» В.
Теперь, возвращаясь к исходной задаче с переменной-отношением СТХ, можно отме-
тить следующее: описанная ранее проблема с переменными-отношениями этого типа
возникает из-за того, что они содержат многозначные зависимости, которые не являются
функциональными. (Следует отметить совсем неочевидный факт, что именно наличие
таких МЗЗ требует вставки двух кортежей, когда необходимо добавить сведения о новом
преподавателе физики. Данные два кортежа необходимы для поддержания ограничения
целостности, представленного этой МЗЗ.) Проекции СТ и СХ не содержат многозначных
зависимостей, а потому они действительно представляют собой некоторое усовершенст-
вование исходной структуры. Поэтому было бы желательно заменить исходную пере-
менную-отношение СТХ двумя рассматриваемыми проекциями. Это действие будет пра-
вомочным в соответствии с теоремой Фейгина [12.13], которая приведена ниже.
Теорема Фейгина. Пусть А, В и С являются множествами атрибутов переменной-
отношения R{A, В, С}. Переменная-отношение R будет равна соединению ее про-
екций {А, В} и {А, С} тогда и только тогда, когда для переменной-отношения R
выполняется многозначная зависимость А —» В | С.
(Обратите внимание, что эта теорема является более строгой версией теоремы Хита,
описанной в главе 11.) Теперь, следуя работе Фейгина [12.13], можно дать определение
четвертой нормальной формы. (Эта нормальная форма получила такое название потому,
что в момент ее появления НФБК все еще считалась третьей нормальной формой.)
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 473
Переменная-отношение R находится в четвертой нормальной форме (4НФ) то-
гда и только тогда, когда в случае существования таких подмножеств А и В атри-
бутов этой переменной-отношения R, для которых выполняется нетривиальная1
многозначная зависимость А —» В, все атрибуты переменной-отношения R также
функционально зависят от атрибута А.
Иначе говоря, в переменной-отношении R могут находиться только нетривиальные
зависимости (функциональные или многозначные) вида К —> X (т.е. некоторый атрибут X
функционально зависит от суперключа К). Это можно также сформулировать в следую-
щей эквивалентной форме: переменная-отношение R находится в 4НФ, если она нахо-
дится в НФБК и все многозначные зависимости в переменной-отношении R фактически
представляют собой функциональные зависимости от ее ключей. Обратите внимание,
что, исходя из этого определения, нахождение в 4НФ предполагает обязательное нахож-
дение в НФБК.
Переменная-отношение СТХ не находится в 4НФ, поскольку содержит многозначную
зависимость, которая не является функциональной, не говоря уже о том, что последняя
должна быть еще и функциональной зависимостью от ключа. Однако обе ее проекции, СТ
и СХ, находятся в 4НФ. Следовательно, 4НФ обеспечивает лучшую структуру данных по
сравнению с НФБК, поскольку позволяет исключить некоторые нежелательные зависи-
мости. Кроме того, в [12.13] Фейгин показал, что 4НФ всегда является достижимой, т.е.
любая переменная-отношение может быть подвергнута декомпозиции без потерь в экви-
валентный набор переменных-отношений в 4НФ. Однако, как показано в разделе 11.5 на
примере переменной-отношения SJT, такая декомпозиция (или даже декомпозиция до
НФБК) не всегда оказывается полезной и нужной.
Замечание. Следует отметить, что хотя идеи Риссанена, изложенные в посвященной
независимым проекциям работе [11.6], сформулированы с использованием функцио-
нальных зависимостей, они также справедливы в отношении многозначных зависимо-
стей. Напомним, что в соответствии с этими идеями переменную-отношение R{А, В, С},
удовлетворяющую функциональным зависимостям А —» В и В —> С, необходимо разби-
вать на проекции {А, В} и {В, С}, а не на проекции {А, В} и {А, С}. Это утверждение
также будет верно, если вместо функциональных зависимостей использовать многознач-
ные зависимости А —>-> В и В —>-> С.
В заключение вернемся, как было обещано, к вопросу об исключении атрибутов,
принимающих в качестве значений отношения, или АО (атрибутов-отношений) для
краткости. В частности, рассмотрим процедуру такого исключения, описанную в от-
вете к упр. 11.3 из предыдущей главы. Суть в том, что на практике для достижения
4НФ достаточно учитывать следующее: если мы имеем дело с переменной-
отношением с двумя или более независимыми АО, то прежде всего следует разде-
лить эти АО. Данное правило имеет не только интуитивно понятный смысл. Это
именно то, что было сделано в ответе к упр. 11.3! Например, в случае переменной-
отношения НСТХ прежде всего следует заменить исходную переменную-отношение
двумя ее проекциями HCT{COURSE, TEACHERS} и HCX{COURSE, TEXTS}, где перемен- *
МЗЗ А —» В называется тривиальной, если либо А является супермножеством В, либо
объединение А и В образует весь заголовок отношения.
474
Часть III. Проектирование базы данных
ные-отношения TEACHERS и TEXTS все еще сохраняют АО. Далее эти АО можно будет
исключить из двух полученных проекций (с приведением их к НФБК) обычным спо-
собом, и тогда “проблема”, свойственная находящейся в НФБК переменной-
отношению СТХ, просто никогда не возникнет. Как видите, понятия многозначных
зависимостей и 4НФ предоставляют формальное обоснование тех правил, которые в
противном случае остались бы чисто эмпирическими.
12.3. Зависимости соединения и пятая
нормальная форма
До сих пор в настоящей главе и на протяжении всей предыдущей главы предполага-
лось, что единственной необходимой или допустимой операцией в процессе нормализа-
ции является замена переменной-отношения по правилам декомпозиции без потерь
только двумя ее проекциями. Такое допущение нас вполне устраивало вплоть до дости-
жения 4НФ. Однако, хотя это может показаться удивительным, существуют переменные-
отношения, для которых нельзя выполнить декомпозицию без потерь на две проекции,
но которые можно подвергнуть декомпозиции без потерь на три или более проекций.
Подобные переменные-отношения обозначим не очень удачным, но достаточно удобным
термином “n-декомпозируемая переменная-отношение” (для некоторого п > 2). Это зна-
чит, что для данной переменной-отношения возможна декомпозиция без потерь на п
проекций, но не на m проекций для любого m < п. Таким образом, переменную-
отношение, для которой можно выполнить декомпозицию на две проекции, следовало
бы называть 2-декомпозируемой.
Замечание. Впервые возможность n-декомпозируемости для п > 2 была упомянута в
работе Ахо (Aho), Бери (Beeri) и Ульмана (Ullman) [12.1], а частный случай для п = 3
был описан Николасом (Nicolas) [12.25].
В качестве примера рассмотрим переменную-отношение SPJ из базы данных постав-
щиков, деталей и проектов, представленную на рис. 12.4 (в целях упрощения изложения
атрибут QTY исключен). Обратите внимание, что эта переменная-отношение состоит
только из ключевых атрибутов, не содержит нетривиальных функциональных и много-
значных зависимостей и потому находится в 4НФ. Заметим также, что на этом рисунке
показаны следующие компоненты.
1. Три бинарные проекции, SP, PJ и JS, переменной-отношения SPJ.
2. Результат соединения проекций SP и PJ по атрибуту Р#.
3. Соединение этого результата с проекцией JS по комбинации атрибутов (J#, S#).
Обратите внимание, что в результате первого соединения получается копия исходной
переменной-отношения SPJ с одним дополнительным (излишним) кортежем, а в резуль-
тате второго соединения этот лишний кортеж исключается. Иначе говоря, исходная пе-
ременная-отношение SPJ является 3-декомпозируемой.
Замечание. Независимо от того, какая пара проекций будет выбрана для первого
соединения, в итоге будет получен один результат, хотя промежуточные результаты
будут в каждом случае разными. Упражнение. Читателю предлагается проверить это
утверждение.
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 475
S# P# J#
S1 S1 S2 S1 Р1 Р2 Р1 Р1 J2 Л Л Л
Рис. 12.4. Переменная-отношение SPJ может быть получена только в резуль-
тате соединения всех трех ее бинарных проекций, но не любых двух из них
Далее, представленный на рис. 12.4 пример, безусловно, выполнен в терминах отноше-
ний, а не переменных-отношений. Однако 3-декомпозируемость переменной-отношения SPJ
может быть более фундаментальным и не зависящим от времени свойством (т.е. свойством,
которое удовлетворяется для всех допустимых значений данной переменной-отношения), ес-
ли данная переменная-отношение удовлетворяет определенному не зависящему от времени
ограничению целостности. Для того чтобы понять, каким именно должно быть это ограниче-
ние, прежде всего заметим, что утверждение “переменная-отношение SPJ равна соединению
трех своих проекций SP, PJ и JS” в точности эквивалентно следующему утверждению.
ЕСЛИ пара (si, pl) присутствует в SP
И пара (pb ji) присутствует в PJ,
И пара (jb si) присутствует в JS,
ТО тройка (si, pl, jl) присутствует в SPJ.
Это верно, поскольку очевидно, что тройка (si, pl, jl) обязательно присутствует в
соединении проекций SP, PJ и JS. (Обратное утверждение, т.е. если тройка (si, pl, jl)
присутствует в переменной-отношении SPJ, то, например, пара (si, pl) присутствует в
проекции SP, является истинным для любой переменной-отношения SPJ третьего поряд-
ка.) Так как пара (si, pl) присутствует в отношении SP тогда и только тогда, когда тройка
(si, pl, j2) присутствует в отношении SPJ для некоторого значения j2 (аналогично для
(pl, jl) и (jl, si)), приведенное выше утверждение можно переписать в виде ограни-
чения, накладываемого на переменную-отношение SPJ.
ЕСЛИ кортежи (si, pl, j2), (s2, pl, jl), (si, p2, jl) присутствуют в SPJ
TO кортеж (si, pl, jl) также присутствует в SPJ.
476
Часть III. Проектирование базы данных
Если это утверждение выполняется всегда, т.е. для всех допустимых значений пере-
менной-отношения SPJ, то будет получено не зависящее от времени (хотя и несколько
странное) ограничение для данной переменной-отношения. Обратите внимание на цик-
лическую структуру этого ограничения (“если значение si связано с pl и pl связано с
jl, a jl связано опять с si, то si, pl и jl должны находиться в одном кортеже”). Пере-
менная-отношение будет п-декомпозируемой для п>2 тогда и только тогда, когда она
удовлетворяет некоторому циклическому ограничению.
Предположим теперь, что переменная-отношение SPJ действительно удовлетворяет
этому не зависящему от времени ограничению (представленный на рис. 12.4 пример
данных соответствует такой гипотезе). Далее ограничение 3-декомпозируемое™ для
краткости будем называть ЗД-ограничением. Что означает ЗД-ограничение с практиче-
ской точки зрения? Для получения ответа на этот вопрос рассмотрим пример, в котором
под такими ограничениями подразумевается, что если в реальном мире для переменной-
отношения SPJ верны утверждения
а) Смит поставляет гаечные ключи,
б) Гаечные ключи используются в Манхэттенском проекте,
в) Смит является поставщиком для Манхэттенского проекта,
то
г) Смит поставляет гаечные ключи для Манхэттенского проекта.
Обратите внимание, что (как уже упоминалось в главе 1, раздел 1.3) из взятых в сово-
купности утверждений а, б и в обычно не следует утверждение г. Действительно, точно
такой же пример был рассмотрен в главе 1 для демонстрации “ловушки соединения”.
Однако в данном частном случае следует отметить, что никакой ловушки здесь нет, по-
скольку существует дополнительное ЗД-ограничение, имеющее место в реальном мире,
благодаря чему вывод утверждения г на основе утверждений а, б и в является вполне
правомочным.
Возвращаясь к главной теме нашего обсуждения, отметим, что, поскольку ЗД-
ограничение удовлетворяется тогда и только тогда, когда переменная-отношение равно-
сильна соединению некоторых ее проекций, такое ограничение называется зависимо-
стью соединения (ЗС). Зависимость соединения является таким же ограничением для
данной переменной-отношения, как многозначная и функциональная зависимости. Ниже
дается определение этого понятия.
Пусть R является переменной-отношением, а А, В, ..., Z— произвольными под-
множествами множества ее атрибутов. Переменная-отношение R удовлетворяет
зависимости соединения
*{А, В, ... , Z} (читается “звездочка А, В, ..., Z”)
тогда и только тогда, когда любое допустимое значение переменной-отношения R
эквивалентно соединению ее проекций по подмножествам атрибутов А, В, ..., Z.
Например, если использовать сокращенную символьную запись SP для подмножества
{S#, Р#} множества атрибутов переменной-отношения SPJ и аналогично использовать
сокращения PJ и JS для двух других подмножеств, то переменная-отношение SPJ будет
удовлетворять зависимости соединения *{SP, PJ, JS}.
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 477
Отсюда ясно, что переменная-отношение SPJ с зависимостью соединения
*{SP, PJ, JS} может быть 3-декомпозируемой. Однако вопрос состоит в том, следует
ли выполнять такую декомпозицию? По всей видимости, следует, так как в связи с нали-
чием зависимости соединения переменная-отношение SPJ характеризуется многочис-
ленными аномалиями обновления, которые можно устранить лишь с помощью 3-
декомпозиции. Некоторые примеры подобных аномалий приведены на рис. 12.5. Отве-
тить на вопрос, что произойдет после выполнения 3-декомпозиции, читателям предлага-
ется самостоятельно в качестве упражнения.
S# P# J#
S1 Р1 J2
S1 Р2 Л
SPJ S# P# J#
S1 Р1 J2
S1 Р2 Л
S2 Р1 Л
S1 Р1 Л
Если вставляется кортеж (S2,P1,J1),
то также должен быть вставлен
кортеж (S1,P1,J1)
Обратное утверждение
не является истинным
Кортеж (S2,P1,J1) может быть
удален без побочных эффектов
Если удаляется кортеж (S1,P1,J1),
то также должен быть удален
еще один кортеж (но какой?)
Рис. 12.5. Примеры аномалий обновления в переменной-отношении SPJ
Теорема Фейгина (которая рассматривалась в разделе 12.2) утверждает, что перемен-
ная-отношение R{A, В, С} может быть декомпозирована без потерь на проекции с атри-
бутами {А, В} и {А, С} тогда и только тогда, когда для переменной-отношения R вы-
полняются многозначные зависимости А —н В и А —>-> С.
Теперь теорема Фейгина может быть сформулирована иначе.
Переменная-отношение R{A, В, С} удовлетворяет зависимости соединения
*{АВ, АС} тогда и только тогда, когда она удовлетворяет многозначной зависимо-
сти А -» В | С.
Поскольку эту теорему можно использовать в качестве определения многозначной за-
висимости, то либо многозначная зависимость является частным случаем зависимости
соединения, либо (что эквивалентно) зависимость соединения является обобщением по-
нятия многозначной зависимости.
Формально получим следующее.
А В | С = *{ АВ, АС }
Замечание. Более того, из определения зависимости соединения сразу же следует, что
из всех возможных форм это наиболее общая форма зависимости (конечно, имеется в
виду, что термин “зависимость” употребляется в узком специальном смысле). Это значит,
что для переменных-отношений, которые подвергаются декомпозиции на проекции и об-
ратной композиции с соединением проекций, не существует более высокой степени зави-
478
Часть III. Проектирование базы данных
симости, по отношению к которой зависимость соединения является всего лишь частным
случаем. (Однако если ввести другие операторы декомпозиции, то возможно появление
других типов зависимости, которые будут кратко описаны в разделе 12.7.)
Возвратившись к рассматриваемому примеру, можно обнаружить следующую пробле-
му: переменная-отношение SPJ содержит зависимость соединения, которая не является ни
многозначной, ни функциональной. (Упражнение. Объясните, почему возникает эта про-
блема?) Можно также заметить, что можно (и, по всей вероятности, желательно) декомпо-
зировать такую переменную-отношение на меньшие компоненты, а именно — на
проекции, определяемые зависимостью соединения. Данный процесс декомпозиции может
повторяться до тех пор, пока все результирующие переменные-отношения не будут нахо-
диться в пятой нормальной форме. Дадим определение этой нормальной формы.
Переменная-отношение R находится в пятой нормальной форме (5НФ), которую
иногда иначе называют проекционно-соединительной нормальной формой
(ПСНФ), тогда и только тогда, когда каждая нетривиальная2 зависимость соеди-
нения в переменной-отношении R подразумевается ее потенциальными ключами.
Замечание. Понятие зависимости соединения, “подразумеваемой потенциальными
ключами”, разъясняется ниже.
Переменная-отношение SPJ не находится в 5НФ. Она удовлетворяет некоторой зави-
симости соединения, а именно — ЗД-ограничению, которое, конечно же, не подразуме-
вается ее единственным потенциальным ключом (этот ключ является комбинацией всех
ее атрибутов). Иначе говоря, переменная-отношение SPJ не находится в 5НФ, поскольку
она может быть 3-декомпозирована и возможность такой декомпозиции не подразуме-
вается тем фактом, что комбинация атрибутов {S#, Р#, J#} является ее потенциальным
ключом. Наоборот, после 3-декомпозиции проекции SP, PJ и JS находятся в 5НФ, по-
скольку в них вовсе нет нетривиальных зависимостей соединения.
Поскольку еще не было дано объяснение выражения “зависимость соединения, подра-
зумеваемая потенциальными ключами”, вероятно, пока не вполне очевиден тот факт, что
любая переменная-отношение в 5НФ автоматически находится в 4НФ. Однако это так, по-
скольку многозначная зависимость является частным случаем зависимости соединения.
Действительно, Фейгин в [12.14] показал, что любая многозначная зависимость, подразу-
меваемая потенциальным ключом, на самом деле должна быть функциональной зависимо-
стью, в которой потенциальный ключ является детерминантом. В той же работе Фейгин
показал, что любая переменная-отношение может быть подвергнута декомпозиции без по-
терь на эквивалентный набор переменных-отношений в 5НФ, т.е. 5НФ всегда достижима.
Теперь следует объяснить, что означает понятие “зависимость соединения, подразу-
меваемая потенциальными ключами”. Для начала в качестве простого примера (который
использовался в разделе 11.5 главы 11) рассмотрим переменную-отношение поставщи-
ков S с потенциальными ключами S# и SNAME. Такая переменная-отношение удовлетво-
ряет нескольким зависимостям соединения, в частности следующей зависимости.
* { { S#, SNAME, STATUS }, { S#, CITY } }
2 Зависимость соединения *{А, В, ..., Z} называется тривиальной тогда и только тогда,
когда одна из проекций А, В, ..., Z является проекцией, идентичной R (т.е. проекцией по всем
атрибутам переменной-отношения R).
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 479
Это значит, что переменная-отношение S равносильна соединению ее проекций с атрибу-
тами {S#, SNAME, STATUS} и {S#, CITY}. Поэтому она может быть подвергнута декомпози-
ции без потерь на указанные проекции. (Заметьте, что ее не следует, а лишь .можно подвер-
гать подобной декомпозиции.) Существование данной зависимости соединения предполагает-
ся на основании того факта, что атрибут {S#} является потенциальным ключом данной пере-
менной-отношения (в действительности это следует из теоремы Хита [11.4]). Аналогично пе-
ременная-отношение S удовлетворяет еще одной зависимости соединения.
* { { S#, SNAME }, { S#, STATUS }, { SNAME, CITY } }
Она следует из того, что оба атрибута, {S#} и {SNAME}, являются потенциальными
ключами.
Как следует из приведенного выше примера, заданная зависимость соединения *{А,
В, ..., Z} подразумевается потенциальными ключами тогда и только тогда, когда ка-
ждое подмножество атрибутов А, В, ..., Z фактически является суперключом для
данной переменной-отношения. Таким образом, относительно заданной переменной-
отношения R можно утверждать, что она находится в 5НФ, только при условии, что из-
вестны все ее потенциальные ключи и все зависимости соединения, существующие в
ней. Однако в отличие от функциональных и многозначных зависимостей (для которых
обычно существует вполне очевидное обоснование в реальном мире) обнаружить все за-
висимости соединения совсем непросто. Суть в том, что смысловое значение зависимо-
стей соединения, которые не являются одновременно многозначными и функциональ-
ными, далеко не всегда очевидно. Следовательно, процедура определения того, что не-
которая переменная-отношение все еще находится в 4НФ, а не в 5НФ, и, таким образом,
существует возможность ее дальнейшей выгодной декомпозиции, все еще остается не
вполне ясной. Однако, как следует из опыта, подобные переменные-отношения достаточ-
но экзотичны и чрезвычайно редко встречаются на практике.
В заключение заметим, что, как следует из определения, 5НФ является окончатель-
ной нормальной формой по отношению к операциям проекции и соединения (что от-
ражено в ее альтернативном названии — проекционно-соединительная нормальная фор-
ма). Таким образом, если переменная-отношение находится в 5НФ, то гарантируется,
что она не содержит аномалий, которые могут быть исключены посредством ее раз-
биения на проекции3. Если переменная-отношение находится в 5НФ, то единственными
в ней являются те зависимости соединения, которые подразумеваются ее потенциальны-
ми ключами, и тогда единственными допустимыми декомпозициями будут декомпози-
ции, которые основаны на этих потенциальных ключах. (Каждая проекция в подобной
декомпозиции будет состоять из одного или нескольких потенциальных ключей плюс
нуль или более дополнительных атрибутов.) Например, переменная-отношение постав-
щиков S находится в 5НФ. Как упоминалось выше, эта переменная-отношение может
быть подвергнута дальнейшей декомпозиции без потерь, причем в нескольких вариантах,
но каждая проекция в любом из этих вариантов по-прежнему будет содержать один из
исходных потенциальных ключей. Следовательно, подобная декомпозиция не даст ника-
ких дополнительных преимуществ.
3 Конечно, это не значит, что данная переменная-отношение свободна от всех возможных
аномалий. Это всего лишь означает, что она свободна от аномалий, которые могут быть ис-
ключены с помощью разбиения на проекции.
480
Часть III. Проектирование базы данных
12.4. Общая схема процедуры нормализации
До данного момента в этой (и предшествующей) главе описывалась технология де-
композиции без потерь, предназначенная для использования в процессе проектирования
базы данных. Основная идея состоит в следующем. Пусть дана некоторая переменная-
отношение R, представленная в 1НФ, в совокупности с набором определенных для нее
функциональных зависимостей, многозначных зависимостей и зависимостей
соединения. Задача заключается в систематическом разбиении исходной переменной-
отношения R на набор меньших (т.е. имеющих меньшую степень) переменных-
отношений, который в некотором заданном смысле будет эквивалентен переменной-
отношению R, но с определенной точки зрения будет более предпочтительным.
(Исходная переменная-отношение R может быть получена за счет предварительного ис-
ключения тех атрибутов, которые принимают в качестве значений отношения, как было
описано в разделе 12.2 или в ответе к упр. 11.3.) Каждый этап процесса нормализации
заключается в разбиении на проекции переменных-отношений, полученных на преды-
дущем этапе. При этом на каждом этапе нормализации существующие ограничения ис-
пользуются для выбора тех проекций, которые будут получены в этот раз. Весь процесс
можно неформально определить с помощью перечисленных ниже правил.
1. Переменную-отношение в 1НФ следует разбить на такие проекции, которые позво-
лят исключить все функциональные зависимости, не являющиеся неприводимыми.
В результате будет получен набор переменных-отношений в 2НФ.
2. Полученные переменные-отношения в 2НФ следует разбить на такие проекции, ко-
торые позволят исключить все существующие транзитивные функциональные за-
висимости. В результате будет получен набор переменных-отношений в ЗНФ.
3. Полученные переменные-отношения в ЗНФ следует разбить на проекции, позво-
ляющие исключить любые оставшиеся функциональные зависимости, в которых
детерминанты не являются потенциальными ключами. В результате такого приве-
дения будет получен набор переменных-отношений в НФБК.
Замечание. Правила 1-3 могут быть объединены в одно: “Исходную перемен-
ную-отношение следует разбить на проекции, позволяющие исключить все
функциональные зависимости, в которых детерминанты не являются потенци-
альными ключами”.
4. Полученные переменные-отношения в НФБК следует разбить на проекции, позво-
ляющие исключить любые многозначные зависимости, которые не являются функ-
циональными. В результате будет получен набор переменных-отношений в 4НФ.
Замечание. На практике такие многозначные зависимости обычно исключаются
перед выполнением этапов 1-3 (“устранение независимых МЗЗ”), как упоминалось
при рассмотрении примера с переменной-отношением СТХ в разделе 12.2.
5. Полученные переменные-отношения в 4НФ следует разбить на проекции, позво-
ляющие исключить любые зависимости соединения, которые не подразумеваются
потенциальными ключами (хотя в данном случае в определение следовало бы до-
бавить фразу “если их удастся выявить”). В результате будет получен набор пере-
менных-отношений в 5НФ.
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 481
По поводу приведенных выше правил можно сделать несколько дополнительных
замечаний.
1. Процесс разбиения на проекции на каждом этапе должен быть выполнен без потерь
и с сохранением зависимостей (там, где это возможно).
2. Обратите внимание, что (как было впервые отмечено Фейгином в [12.14]) сущест-
вует довольно привлекательный набор следующих альтернативных определений
НФБК, 4НФ и 5НФ.
Переменная-отношение R находится в НФБК тогда и только тогда, когда каждая
функциональная зависимость подразумевается ее потенциальными ключами.
Переменная-отношение R находится в 4НФ тогда и только тогда, когда каждая
многозначная зависимость подразумевается ее потенциальными ключами.
Переменная-отношение R находится в 5НФ тогда и только тогда, когда каждая
зависимость соединения подразумевается ее потенциальными ключами.
Аномалии обновления, обсуждавшиеся в главе 11 и в предыдущих разделах данной
главы, были вызваны именно теми функциональными зависимостями, многознач-
ными зависимостями или зависимостями соединения, которые не подразумевались
потенциальными ключами.
3. Общее назначение процесса нормализации заключается в следующем:
исключение некоторых типов избыточности;
устранение некоторых аномалий обновления;
разработка проекта базы данных, который является достаточно “хорошим” пред-
ставлением реального мира, интуитивно понятен и может служить хорошей ос-
новой для последующего расширения;
упрощение процедуры описания необходимых ограничений целостности.
Последний пункт данного списка следует рассмотреть отдельно. Общая идея (как
отмечалось ранее, в главах 8, 10 и др.) состоит в том, что одни ограничения цело-
стности подразумевают другие ограничения. В качестве простейшего примера
можно привести ограничение для суммы зарплаты, которая должна быть выше
$10 000, а следовательно, выше нуля. Таким образом, если ограничение А подразу-
мевает ограничение В, то после приведения в действие ограничения А будет авто-
матически задействовано также ограничение В (для этого даже не потребуется
объявлять ограничение В явным образом, за исключением случаев, когда это будет
сделано в виде комментария). Тогда приведение к 5НФ представляет собой про-
стой путь наложения некоторых важных и весьма распространенных ограничений.
Главное — обеспечить поддержку уникальности потенциальных ключей, после че-
го все зависимости соединения (а также все многозначные и функциональные зави-
симости) будут реализованы СУБД автоматически, поскольку все они подразуме-
ваются потенциальными ключами.
4. Необходимо вновь подчеркнуть тот факт, что данные рекомендации по поводу
нормализации являются всего лишь рекомендациями и, вероятно, могут сущест-
вовать соображения, по которым нормализацию не следует выполнять предло-
женным выше образом, причем “от начала и до конца”. Классическим примером
ситуации, когда полная нормализация не желательна, является переменная-
482
Часть III. Проектирование базы данных
отношение типа “имя — адрес” NADDR (из упр. 11.7 главы 11), хотя следует при-
знать, что этот пример не совсем убедителен. Как правило, нормализацию реко-
мендуется выполнять полностью.
5. Необходимо еще раз повторить сделанное в главе 11 замечание о том, что понятия зави-
симости и дальнейшей нормализации являются чисто семантическими, т.е. они связаны
со смыслом данных, тогда как реляционная алгебра и реляционное исчисление, а также
построенные на их основе языки наподобие SQL, наоборот, имеют дело со значениями
данных и не требуют (да и не могут требовать) выполнения нормализации выше перво-
го уровня. Рекомендации по выполнению дальнейшей нормализации должны рассмат-
риваться, прежде всего, как некая упорядоченность, позволяющая разработчику базы
данных (и, следовательно, ее пользователю) зафиксировать некую часть, пусть даже не-
большую, семантики реального мира в простой и понятной форме.
6. Исходя из сказанного выше, необходимо отметить, что хотя идеи нормализации
чрезвычайно полезны для проектирования баз данных, они вовсе не являются уни-
версальным средством. Ниже перечислены некоторые причины подобного положе-
ния дел [12.9].
Нормализация (как упоминалось выше, в главе 8) действительно позволяет реа-
лизовать (и в очень простой форме) определенные ограничения целостности, од-
нако на практике, помимо зависимостей соединения, функциональных и много-
значных зависимостей, существуют и другие типы ограничений.
Декомпозиция может быть неуникальной (как правило, имеется несколько спо-
собов приведения заданного набора переменных-отношений к 5НФ), однако су-
ществует очень мало критериев выбора наиболее предпочтительного варианта
декомпозиции среди нескольких альтернативных.
Как упоминалось в разделе 11.5 (пример декомпозиции переменной-отношения
SJT), преследование одновременно двух целей, т.е. приведение к НФБК и сохра-
нение зависимостей, в некоторых случаях приводит к конфликтной ситуации.
Процедура нормализации позволяет избавиться от избыточности за счет разбие-
ния на проекции, однако не всякую избыточность можно устранить таким обра-
зом (“проблема переменной-отношения CTXD”, см. аннотацию к [12.13]).
Следует также отметить, что хорошие методики нисходящего проектирования по-
зволяют тем или иным конкретным способом генерировать полностью нормализо-
ванный проект базы данных.
12.5. Денормализация
До сих пор в этой (и предыдущей) главе принималось на веру утверждение, что пол-
ную нормализацию желательно выполнять вплоть до 5НФ. На практике, однако, часто
можно слышать утверждения, что для достижения высокой производительности системы
требуется выполнить денормализацию. При этом используются аргументы, подобные
перечисленным ниже.
1. Полная нормализация означает наличие большого количества логически независи-
мых переменных-отношений (предполагается, что рассматриваемые переменные-
отношения являются базовыми).
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 483
2. Большое количество логически независимых переменных-отношений означает на-
личие большого количества физически отдельно хранимых файлов.
3. Большое количество физически отдельно хранимых файлов означает большое ко-
личество операций ввода-вывода.
Строго говоря, эти аргументы, конечно же, неверны, потому что (как многократ-
но отмечалось в данной книге) нигде в определении реляционной модели не утвер-
ждается, что базовые переменные-отношения должны находиться во взаимно одно-
значном соответствии с хранимыми файлами. Поэтому денормализацию в случае не-
обходимости следует выполнять на уровне хранимых файлов, но не на уровне базо-
вых переменных-отношений. Однако в некотором отношении эти аргументы все же
верны для современных SQL-продуктов, поскольку именно в них эти уровни не раз-
делены в требуемой степени. В данном разделе понятие “денормализация” будет
рассмотрено более подробно.
Замечание. Материал этого раздела в значительной степени основан на работе [12.6].
Что такое денормализация
Кратко говоря, нормализация переменной-отношения R означает ее замену таким
множеством проекций R1, ..., Rn для всех возможных значений г переменной-
отношения R, что результатом обратного соединения значений г 1, ..., гп проекций R1,
..., Rn обязательно будет значение г. Конечной целью нормализации является сокраще-
ние уровня избыточности данных за счет приведения проекций R1, ..., Rn к макси-
мально высокому уровню нормализации (т.е. к 5НФ).
Теперь можно перейти к определению понятия денормализации. Пусть R1, ...,
Rn является множеством переменных-отношений. Тогда денормализацией этих пе-
ременных-отношений называется такая замена переменных-отношений их соедине-
нием R, что для всех возможных значений rl, ..., гп переменных-отношений R1,
..., Rn операция проекции значения г переменной-отношения R по атрибутам Ri
обязательно снова приводит к созданию значений ri (где i = 1, ..., п). Конечной
целью денормализации является увеличение уровня избыточности данных за счет
приведения переменной-отношения R к более низкому уровню нормализации, чем
исходные переменные-отношения R1, ..., Rn. Точнее, преследуется цель сократить
количество соединений, которые потребуется выполнять во время работы приложе-
ний, за счет предварительного создания этих соединений на одном из этапов проек-
тирования базы данных.
В качестве примера рассмотрим денормализацию переменных-отношений деталей и
поставок для получения переменной-отношения PSQ, представленной на рис. 12.64. Сле-
дует отметить, что переменная-отношение PSQ находится в 1 НФ, а не в 2НФ.
4 При использовании нашего традиционного примера с переменными-отношениями поставщи-
ков и поставок в случае денормализации может возникнуть проблема, связанная с тем, что в ре-
зультате соединения будет утрачена информация о поставщике с номером 'S5'. По этой при-
чине можно предположить, что в процессе денормализации следует использовать операции
“внешних” соединений. Однако, как показано в главе 18, само по себе использование внешних со-
единений также сопровождается возникновением определенных проблем.
484
Часть III. Проектирование базы данных
PSQ P# PNAME COLOR WEIGHT CITY S# QTY
Р1 Nut Red 12.0 London SI 300
Р1 Nut Red 12.0 London S2 300
Р2 Bolt Green 17.0 Paris SI 200
| P6| Cog| Red 119.0| London | SI 1100 |
Puc. 12.6. Денормализованные данные о товарах и поставках
Другие проблемы
Использование концепции денормализации связано с некоторыми вполне очевидны-
ми проблемами. Одна из них заключается в том, что, начиная денормализацию, трудно
сказать, когда ее следует прекратить. В случае выполнения нормализации существуют
ясные логические причины ее продолжения до тех пор, пока не будет достигнута самая
высокая из возможных нормальных форм. Следует ли при выполнении денормализации
стремиться к тому, чтобы достичь самой низкой из возможных нормальных форм? Ко-
нечно, нет, хотя никаких логических критериев точного определения момента прекраще-
ния этого процесса не существует. Иначе говоря, в случае денормализации наша прежняя
позиция, построенная на основании строгой научной и логической теории, заменяется
позицией чисто прагматической и субъективной.
Второе очевидное затруднение связано с проблемами избыточности и аномалиями
обновления, которые возникают из-за того, что приходится иметь дело с не полностью
нормализованными переменными-отношениями. Эти проблемы достаточно подробно
обсуждались выше. Однако менее очевидной является проблема извлечения данных, т.е.
денормализация может существенно усложнить выполнение некоторых запросов. Рас-
смотрим в качестве примера следующий запрос: “Найти средний вес всех деталей опре-
деленного цвета”. При использовании обычного нормализованного макета наиболее
подходящая формулировка данного запроса будет выглядеть так.
SUMMARIZE Р PER Р { COLOR } ADD AVG ( WEIGHT ) AS AVWT
Однако при использовании переменной-отношения PSQ, показанной на рис. 12.6,
формулировка будет выглядеть несколько сложнее (не говоря уже о том, что в такой си-
туации предполагается наличие по крайней мере одной поставки для каждой детали, что
в общем случае неверно).
SUMMARIZE PSQ { Р#, COLOR, WEIGHT } PER PSQ { COLOR }
ADD AVG ( WEIGHT ) AS AVWT
(Обратите внимание на то, что во второй формулировке запрос, вероятно, будет вы-
полнить сложнее.) Иначе говоря, общепринятое мнение о том, что денормализация
“хороша для извлечения, но плоха для обновления”, вообще говоря, неверно как по со-
ображениям практичности, так и по соображениям производительности.
Третья, и самая главная, проблема формулируется следующим образом. (Это выска-
зывание относится к “истинной” денормализации, т.е. к денормализации, которая вы-
полняется только на физическом уровне, а также к тому типу денормализации, которую
иногда приходится осуществлять в современных SQL-продуктах.) Когда мы говорим, что
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 485
денормализация “способствует достижению высокой производительности”, фактически
подразумевается, что она способствует достижению высокой производительности не-
которых конкретных приложений. Любая выбранная физическая структура, которая
прекрасно подходит для одних приложений с точки зрения их производительности, мо-
жет оказаться совершенно непригодной для других. Например, предположим, что каждая
базовая переменная-отношение отображается на один физический хранимый файл, а ка-
ждый хранимый файл состоит из физически смежного набора хранимых записей, по од-
ной для каждого кортежа соответствующей переменной-отношения. Тогда в отношении
данной структуры можно сделать следующие замечания.
Допустим, что соединение отношений поставщиков, поставок и деталей представ-
лено в виде одной переменной-отношения, а значит, в виде одного хранимого
файла. Тогда запрос “Получить сведения обо всех поставщиках красных деталей”
благодаря выбранной физической структуре будет, по-видимому, выполняться
достаточно эффективно.
Однако запрос “Получить сведения о поставщиках из Лондона” при такой физиче-
ской структуре будет выполняться менее эффективно по сравнению со структу-
рой, состоящей из трех отдельных переменных-отношений, каждая из которых
отображена на физически отдельный хранимый файл. Дело в том, что в первом
случае данные будут распределены на большем участке устройства хранения и для
их извлечения потребуется существенно больше операций ввода-вывода.
Аналогичные замечания можно высказать по отношению ко всем запросам, в ко-
торых доступ осуществляется только к данным о поставщиках, деталях или по-
ставках по отдельности (без выполнения операции соединения).
12.6. Ортогональное проектирование
(небольшое отступление от темы)
В этом разделе мы кратко рассмотрим другой принцип проектирования баз данных,
который напрямую не связан с дальнейшей нормализацией, но очень похож на нее тем,
что также является научным. Он называется принципом ортогонального проектиро-
вания (principle of orthogonal design). Обратимся к рис. 12.7, на котором представлена
безусловно плохая, но вполне допустимая структура представления данных о поставщи-
ках. Здесь переменная-отношение SA соответствует поставщикам, которые находятся в
Париже, а переменная-отношение SB соответствует поставщикам, которые либо не нахо-
дятся в Париже, либо имеют статус выше 30 (т.е. предикаты этих переменных-отноше-
ний имеют именно такой смысл). Как следует из рисунка, подобная структура характери-
зуется некоторой избыточностью, точнее говоря, в ней дважды представлен кортеж для
поставщика с номером ' S3' (по одному в каждой переменной-отношении).
Отметим, что данный кортеж должен находиться в обеих переменных-отношениях.
Допустим обратное, т.е. что он находится в переменной-отношении SB, но отсутствует в
переменной-отношении SA. Применив допущение замкнутости мира к переменной-
отношению SA, можно сделать вывод, что поставщик с номером ' S3' не находится в Па-
риже. Однако данные в переменной-отношении SB свидетельствуют об обратном, т.е. о
том, что он находится в Париже. Иначе говоря, мы получили противоречие и, следова-
тельно, база данных находится в противоречивом состоянии.
486
Часть III. Проектирование базы данных
Рис. 12.7. Плохая, но вполне допустимая структура представления
данных о поставщиках
Недостаток показанной на рис. 12.7 структуры данных очевиден: один и тот же кор-
теж может дублироваться в каждой из двух переменных-отношений. Иначе говоря, две
переменные-отношения имеют перекрывающееся смысловое значение и это приводит к
тому, что один и тот же кортеж может удовлетворять предикатам обеих переменных-
отношений. Поэтому достаточно очевидным является следующее правило.
Принцип ортогонального проектирования (исходная версия). Никакие две пе-
ременные-отношения в базе данных не должны иметь перекрывающихся смысло-
вых значений.
Здесь можно сделать следующие дополнительные замечания.
1. Как говорилось в главе 9, с точки зрения пользователя, все переменные-отношения
являются базовыми (за исключением тех представлений, которые определяются им
для упрощения записи запросов). Иначе говоря, этот принцип применим для проек-
тирования всех “выражаемых”, а не только “реальных” баз данных. Здесь нам вновь
приходится иметь дело с принципом относительности баз данных. (Безусловно, ана-
логичные замечания применимы и к принципам нормализации.)
2. Обратите внимание, что две переменные-отношения могут иметь перекрывающее-
ся смысловое значение только в том случае, если они имеют одинаковые типы (т.е.
одинаковые заголовки).
3. Использование принципа ортогонального проектирования подразумевает, что
вставка кортежа рассматривается как операция вставки кортежа в базу данных, а не
в какую-то конкретную переменную-отношение, поскольку существует не более
одной переменной-отношения, предикату которой этот кортеж удовлетворяет.
Однако в настоящее время при вставке кортежа обычно требуется указывать имя
той переменной-отношения R, в которую кортеж вставляется. Но это нисколько не
противоречит предыдущему высказыванию, так как, по сути, имя R является всего
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 487
лишь сокращением для соответствующего предиката (например, PR). Действи-
тельно, команда выглядит так: INSERT кортеж t, где t должно удовлетворять
предикату PR. Более того, переменная-отношение R может быть представлением,
определенным, например, с помощью выражения типа A UNION В. Как говорилось
в главе 9, очень желательно, чтобы системе было известно, куда вставлять новый
кортеж: только в переменную-отношение А, только в переменную-отношение В или
одновременно в обе эти переменные-отношения.
На самом деле замечания, аналогичные приведенным выше, относятся ко всем ти-
пам операций, а не только к операциям INSERT. Во всех этих случаях указываемые
имена переменных-отношений в действительности являются лишь сокращениями
для их предикатов. Это замечание вряд ли можно выразить более строго, если
просто сказать, что семантика данных представлена именно предикатами пере-
менных-отношений, а не их именами.
Прежде чем завершить обсуждение принципа ортогонального проектирования,
необходимо сделать одну важную поправку. На рис. 12.8 показан еще один пример
очевидно плохой, но вполне допустимой структуры представления данных о по-
ставщиках. В этом случае две переменные-отношения сами по себе не имеют пере-
крывающегося смыслового значения, но их проекции по атрибутам {S#, SNAME} —
имеют (на самом деле смысловые значения этих проекций идентичны). В результате
попытка вставки некоторого кортежа (например, ('S6', 'Lopez')) в представление,
определенное как объединение этих двух проекций, приведет к вставке кортежа
('S6', 'Lopez', t) в переменную-отношение SX и кортежа ('S6', 'Lopez', с) —
в переменную-отношение SY (где t и с — используемые по умолчанию значения).
Ясно, что для устранения подобных проблем принцип ортогонального проектирова-
ния необходимо несколько расширить.
SX S# SNAME STATUS SY S# SNAME CITY
S1 Smith 20 SI Smith London
S2 Jones 10 S2 Jones Paris
S3 Blake 30 S3 Blake Paris
S4 Clarck 20 S4 Clarck London
S5 Adams 30 S5 Adams Athens
Рис. 12.8. Еще один неудачный, но вполне допустимый вариант представления данных о
поставщиках
Принцип ортогонального проектирования (окончательная версия). Пусть А и
В являются двумя базовыми переменными-отношениями в некоторой базе дан-
ных. Тогда для переменных-отношений А и В не должно существовать декомпо-
зиций без потерь на такие проекции А1, ..., Ат и В1, ..., Вт соответственно,
что некоторая проекция Ai в множестве проекций А1, ..., Ат и некоторая про-
екция Bj в множестве проекций В1, ..., Вт будут обладать перекрывающимися
смысловыми значениями.
488
Часть IIL Проектирование базы данных
При этом необходимо сделать следующие дополнительные замечания.
1. Здесь термин “декомпозиция без потерь” означает в точности то, что он означает
всегда, а именно — декомпозицию на множество таких проекций, которые обла-
дают следующими свойствами:
исходная переменная-отношение может быть восстановлена за счет обратной
операции соединения проекций;
ни одна из проекций не является избыточной в процессе восстановления.
2. Данная версия принципа ортогонального проектирования подразумевает предыду-
щую версию, поскольку единственная декомпозиция без потерь, которая всегда
существует для любой переменной-отношения R, является идентичной проекцией
для R (т.е. проекций по всем ее атрибутам).
Замечания
1. Предположим, что нашу традиционную переменную-отношение S с данными о по-
ставщиках для улучшения структуры информации решено разделить на несколько
фрагментов. Тогда в соответствии с принципом ортогонального проектирования не-
обходимо обеспечить, чтобы полученные фрагменты не пересекались, в том смысле,
что каждый кортеж с данными о некотором поставщике может появиться не более
чем в одном из фрагментов. Назовем такое разбиение ортогональной декомпозицией.
Замечание. Термин ортогональность выбран, исходя из тех соображений, что
данный принцип проектирования на самом деле декларирует полную взаимную
независимость базовых переменных-отношений (т.е. отсутствие перекрытия их
смысловых значений). Безусловно, этот принцип отражает очевидные соображе-
ния здравого смысла, но позволяет выразить их в формальном виде (подобно
принципам нормализации).
2. Общее назначение ортогонального проектирования заключается в сокращении избы-
точности и, следовательно, в исключении аномалий обновления (вновь аналогия с
принципами нормализации). По сути, ортогональное проектирование дополняет нор-
мализацию в том смысле, что, выражаясь нестрого, нормализация сокращает избы-
точность данных внутри переменных-отношений, тогда как ортогональное проекти-
рование сокращает избыточность данных .между переменными-отношениями.
3. Несмотря на то что принципы ортогональности очевидны с точки зрения здравого
смысла, они часто игнорируются на практике (причем иногда их даже рекоменду-
ется игнорировать). Например, приведенный ниже пример структуры данных весь-
ма распространен в финансовых базах данных.
ACTIVITIES 1997 { ENTRY#, DESCRIPTION, AMOUNT, NEW BAL }
ACTIVITIES~1998 { ENTRY#, DESCRIPTION, AMOUNT, NEW~BAL }
ACTIVITIES”!999 { ENTRY#, DESCRIPTION, AMOUNT, NEW~BAL }
ACTIVITIES~2000 { ENTRY#, DESCRIPTION, AMOUNT, NEW~BAL }
ACTIVITIES~2001 { ENTRY#, DESCRIPTION, AMOUNT, NEW~BAL }
По сути, внесение смыслового значения в имена переменных-отношений или других
объектов нарушает принцип информации, который гласит, что вся информация в базе
данных должна быть явно представлена в виде значений данных и никак иначе.
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 489
4. Если А и В являются базовыми отношениями одного типа, то следование принци-
пам ортогонального проектирования будет означать следующее.
A UNION В
A INTERSECT В
A MINUS В
Всегда является непересекающимся объединением
Всегда является пустым множеством
Всегда равно А
12.7. Другие нормальные формы
Прежде чем завершить обсуждение вопросов нормализации, следует напомнить сде-
ланное в главе 11 замечание о том, что, помимо уже описанных, существуют и другие
нормальные формы. Дело в том, что теория нормализации и связанные с ней вопросы (в
настоящее время эту область обычно называют теорией зависимостей) развились в зна-
чительную самостоятельную область знаний с обширной литературой. Исследования в
данной области продолжаются и в настоящее время, причем довольно успешно. Однако
сколько-нибудь углубленный обзор этих исследований выходит за рамки данной главы.
Заинтересованный читатель найдет достаточно полный обзор полученных в этой области
результатов в [12.17] (по состоянию на середину 1980-х годов). Ниже мы лишь кратко
упомянем о некоторых из них.
1. Доменно-ключевая нормальная форма (ДКНФ). Эта форма была предложена
Фейгином [12.15]. В отличие от рассмотренных выше нормальных форм, она не
определяется в терминах функциональных зависимостей, многозначных зависимо-
стей или зависимостей соединения. Вместо этого утверждается, что переменная-
отношение R находится в ДКНФ тогда и только тогда, когда каждое наложенное на
нее ограничение является логическим следствием ограничений доменов и ограни-
чений ключей, наложенных на данную переменную-отношение R.
Ограничение домена в том смысле, в котором оно здесь употребляется, — это
ограничение, предписывающее использование для определенного атрибута зна-
чений только из некоторого заданного домена. (В главе 8 это ограничение упо-
минается как ограничение атрибута, а не как ограничение домена.)
Ограничение ключа — это ограничение, утверждающее, что некоторый атрибут
или комбинация атрибутов представляет собой потенциальный ключ.
Концептуально реализация ограничений, которые установлены для переменной-
отношения, находящейся в ДКНФ, осуществляется очень просто, поскольку для
этого достаточно реализовать поддержку ограничений домена и ключа, а все ос-
тальные ограничения будут приведены в действие автоматически. Обратите внима-
ние, что под выражением “все остальные ограничения” подразумевается нечто
большее, чем просто функциональные и многозначные зависимости или зависимо-
сти соединения. Фактически это выражение обозначает весь предикат данной пе-
ременной-отношения.
Фейгин в [12.15] показал, что любая переменная-отношение, находящаяся в ДКНФ,
находится в 5НФ (а значит, в 4НФ и т.д.), а также в форме типа (3,3)НФ (подробнее,
о ней рассказывается ниже). Однако не всегда можно привести переменную-1
отношение к ДКНФ или получить ответ на вопрос “Когда такое приведение может
быть выполнено?”.
490
Часть III. Проектирование базы данных
2. Нормальная форма типа “выборка — объединение”. Вновь обратимся к пе-
ременной-отношению S с данными о поставщиках. Согласно описанной выше
теории нормализации эта переменная-отношение находится в 5НФ и, следова-
тельно, не характеризуется аномалиями и не нуждается в дальнейшем разбиении
на проекции для устранения аномалий. Но зачем хранить сведения обо всех по-
ставщиках в одной переменной-отношении? Может, было бы лучше разместить
данные о поставщиках из Лондона в одном отношении (например, в отношении
LS), из Парижа — в другом (например, в PS) и т.д.? Иначе говоря, может быть,
стоило бы рассмотреть возможность декомпозиции на основе некоторого огра-
ничения, а не на основе проекции? Лучше или хуже будет структура данных, по-
лученная в результате такой декомпозиции? (Фактически она всегда получается
хуже (см. упр. 7.8 в главе 7), однако классическая теория нормализации не может
дать ответа на поставленные выше вопросы.)
Другим направлением в исследованиях нормализации является применение декомпо-
зиции на основе операций, отличных от проекции. В рассматриваемом выше
примере, как уже упоминалось, операцией декомпозиции является непересекающееся
ограничение, а соответствующей операцией композиции — непересекающееся объе-
динение. Таким образом, вполне возможно создать “ограничительно-объединитель-
ную” теорию нормализации, аналогичную, но ортогональную (независимую), относи-
тельно обсуждавшейся выше проекционно-соединительной теории нормализации5.
Автору настоящей книги ничего не известно о достаточно развитых теориях подоб-
ного типа, однако некоторые исходные идеи можно найти в статье Смита [12.26], где
дано определение новой нормальной формы под названием (3,3)НФ. Подразумевает-
ся, что переменная-отношение в (3,3)НФ уже находится в НФБК, однако необяза-
тельно находится в 4НФ, так же как переменная-отношение в 4НФ не обязательно
находится в (3,3)НФ. Таким образом, как и предполагалось выше, приведение к фор-
ме типа (3,3)НФ является независимым по отношению к приведению к 4НФ (и 5НФ).
Более подробно об этом можно прочесть в [12.14], [12.22].
12.8. Резюме
В этой главе завершается обсуждение дальнейшей нормализации (начатое в гла-
ве 11), включая рассмотрение многозначных зависимостей, являющихся обобщением
понятия функциональных зависимостей, а также зависимостей соединения, являющих-
ся обобщениями многозначных зависимостей. Ниже даны определения этих понятий с
неформальной точки зрения.
Переменная-отношение R{ А, В, С} удовлетворяет многозначной зависимости А —»
В | С тогда и только тогда, когда множество значений атрибута В, соответствующее
заданной паре значений атрибутов (А, С), зависит только от значения атрибута А и
аналогично множество значений атрибута С, соответствующее заданной паре значе-
ний атрибутов (А, В), зависит только от значения атрибута А. Такая переменная-
5 Действительно, Фейгин в [12.9] назвал 5НФ проекционно-соединительной нормальной фор-
мой, поскольку это была именно такая нормальная форма, определяемая с помощью операций
проекции и соединения.
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 491
отношение может быть подвергнута декомпозиции без потерь на проекции {А, В} и
{А, С}, причем многозначные зависимости являются необходимым и достаточным
условием допустимости такой декомпозиции (теорема Фейгина).
Переменная-отношение R{А, В, ..., Z} удовлетворяет зависимости соединения
* (А, В, ..., Z) тогда и только тогда, когда она эквивалентна соединению ее про-
екций по атрибутам А, В, ..., Z. Такая переменная-отношение, очевидно, может
быть разбита на эти проекции с обеспечением декомпозиции без потерь.
Переменная-отношение находится в 4НФ в том случае, если все существующие в ней
многозначные зависимости одновременно являются функциональными зависимостями,
исходящими от ее суперключей. Переменная-отношение находится в 5НФ (также назы-
ваемой проекционно-соединительной нормальной формой) тогда и только тогда, когда
все существующие в ней зависимости соединения одновременно являются функциональ-
ными зависимостями от ее суперключей. Пятая нормальная форма (которая всегда дос-
тижима) является окончательной нормальной формой по отношению к операциям про-
екции и соединения.
В этой главе была кратко описана общая схема процедуры нормализации, пред-
ставленная в виде некоторой неформальной последовательности этапов с необходимыми
комментариями. Затем было дано краткое описание принципа ортогонального проек-
тирования, который неформально можно сформулировать следующим образом: ника-
кие две переменные-отношения не должны иметь проекций с перекрывающимся смы-
словым значением. Наконец, здесь было дано краткое описание некоторых дополнитель-
ных нормальных форм.
В заключение следует отметить, что дальнейшие исследования в данной области не-
обходимо считать чрезвычайно перспективными. Дело в том, что теория дальнейшей
нормализации, которую теперь все чаще называют теорией зависимостей, представляет
собой один из весьма субъективных научных разделов теории проектирования баз дан-
ных. Это значит, что, к сожалению, она ближе к искусству, чем к строгой методике. Для
выработки последней необходимо найти более твердые принципы и разработать соот-
ветствующие рекомендации. Поэтому любой успех в дальнейшем изучении в данной
теоретической области представляет значительный интерес для исследователей.
Упражнения
12.1. Рассматриваемые в этой главе переменные-отношения СТХ и SPJ (примеры их дан-
ных показаны на рис. 12.2 и 12.4) удовлетворяют некоторой многозначной зависи-
мости и некоторой зависимости соединения соответственно, которые потенциаль-
ными ключами данных переменных-отношений не предполагаются. Выразите эту
многозначную зависимость и эту зависимость соединения с помощью синтаксиса,
использовавшегося в главе 8.
12.2. Пусть С — это некоторое множество, а переменная-отношение R{А, В} такова, что
кортеж (а, Ь) содержится в R тогда и только тогда, когда а и b принадлежат мно-
жеству С. Какие функциональные и многозначные зависимости, а также зависимо-
сти соединения имеют место в переменной-отношении R? В какой нормальной
форме находится эта переменная-отношение?
492
Часть III. Проектирование базы данных
12.3. Пусть в некоторой базе данных содержится информация о торговых агентах, ре-
гионах сбыта и самой продукции. Каждый агент отвечает за сбыт в одном или не-
скольких регионах, и в каждом регионе имеется один или несколько торговых
агентов. Аналогично каждый агент отвечает за сбыт одного или более видов про-
дукции, а каждый вид продукции распространяется одним или несколькими торго-
выми агентами. Каждый вид продукции продается в каждом регионе, однако два
торговых агента не могут продавать один и тот же продукт в одном и том же ре-
гионе. Каждый торговый агент продает один и тот же набор продукции в каждом
регионе, за который он отвечает. Спроектируйте набор переменных-отношений,
отвечающий указанным требованиям к данным.
12.4. В ответе к упр. 11.3 в главе 11 был приведен алгоритм декомпозиции без потерь
для переменной-отношения R с ее разбиением на множество переменных-
отношений в НФБК. Измените этот алгоритм таким образом, чтобы выполнялось
аналогичное преобразование, но уже в 4НФ.
12.5. {Модифицированная версия упр. 12.3.) Пусть в некоторой базе данных содержится
информация о торговых агентах, регионах сбыта и самой продукции. Каждый тор-
говый агент отвечает за сбыт продукции в одном или нескольких регионах, и в ка-
ждом регионе имеется один или более торговых агентов. Аналогично каждый тор-
говый агент отвечает за сбыт одного или более видов продукции, а каждый вид
продукции распространяется одним или несколькими торговыми агентами. Нако-
нец, каждый вид продукции продается в одном или нескольких регионах и в каж-
дом регионе продается один или несколько видов продукции. Более того, если тор-
говый агент R отвечает за сбыт в регионе А, продукт Р продается в регионе А и тор-
говый агент R отвечает за сбыт продукта Р, то агент R продает продукт Р в регионе
А. Спроектируйте набор переменных-отношений, отвечающий указанным требова-
ниям к данным.
Список литературы
12.1. Aho A.V., Beeri С., Ullman J. D. The Theory of Joins in Relational Databases // ACM
TODS. — 1979. — 4, № 3. (Впервые опубликована в Proc. 19th IEEE Symposium on
Foundations of Computer Science. — October, 1977.)
Первая попытка рассмотреть переменную-отношение, которая не эквивалентна со-
единению любых двух своих проекций, но эквивалентна соединению трех или бо-
лее проекций. Основное назначение статьи — представить алгоритм, который те-
перь называется алгоритмом преследования (chase), предназначенный для опре-
деления, является ли данная зависимость соединения логическим следствием дан-
ного набора функциональных зависимостей (пример проблемы включения при-
веден в [12.17]). Эта проблема эквивалентна определению, будет ли данная деком-
позиция выполняться без потерь для заданного набора функциональных зависимо-
стей. В статье также обсуждается вопрос о расширении алгоритма для случая, ко-
гда заданные зависимости являются не функциональными, а многозначными.
12.2. Beeri С., Fagin R., Howard J.H. A Complete Axiomatization for Functional and
Multivalued Dependencies // Proc. 1977 ACM SIGMOD Intern. Conf, on Management
of Data. — Toronto, Canada, August, 1977.
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 493
В этой работе результаты работы Армстронга (Armstrong) [10.1] обобщаются и
распространяются на многозначные и функциональные зависимости. В частности,
дается строгий и полный набор правил вывода для многозначных зависимостей.
1. Дополнение. Если множества атрибутов А, В, С совместно содержат все атрибу-
ты переменной-отношения и А является супермножеством пересечения В л С,
то А -» В тогда и только тогда, когда А -» С.
2. Рефлексивность. Если В является подмножеством А, то А -» В.
3. Приращение. Если А —» В и С является подмножеством D, то AD —» ВС.
4. Транзитивность. Если А —>-> В и В —>-> С, то А -» С-В.
Далее следуют дополнительные полезные правила, которые выводятся из при-
веденных выше правил.
5. Псевдотранзитивность. Если А В и ВС -» D, тоАС —>-> D-BC.
6. Объединение. Если А —>-> В и А —>-> С, то А —» ВС.
7. Декомпозиция. Если А —>-> ВС, то А —>-> ВлС,А —>-> В-СиА -» С-В.
В статье также представлены еще два правила, по которым можно вывести дру-
гие функциональные зависимости на основе определенных комбинаций функ-
циональных и многозначных зависимостей.
8. Репликация. Если А —> В, то А —» В.
9. Слияние. Если А —)-» В, С —> D, D является подмножеством В, а пересечение
В n С пусто, то А —> D.
Правила Армстронга (см. главу 10) вместе с правилами 1-4, 8 и 9 образуют
строгий и полный набор правил для функциональных и многозначных зависи-
мостей.
В статье также выведено еще одно полезное правило, связывающее функцио-
нальные и многозначные зависимости.
10. Если А —>-> В и АВ —> С, то А —> С-В.
12.3. Brosda V., Vossen G. Update and Retrieval Through a Universal Schema Interface //
ACM TODS. — December, 1988. — 13, № 4.
В предыдущих попытках предоставления интерфейса “универсального отношения”
(см. аннотацию к [12.19]) рассматривались только операции извлечения данных. В
этой статье предлагается подход на основе операций обновления.
12.4. Carlson C.R., Kaplan R.S. A Generalized Access Path Model and Its Application to a
Relational Data Base System // Proc. 1976 ACM SIGMOD Intern. Conf, on Management
of Data. — Washington, D.C., June, 1976.
См. аннотацию к [12.19].
12.5. Date C.J. Will the Real Fourth Normal Form Please Stand Up? И C. J. Date and
Hugh Darwen. Relational Database Writings 1989-1991.— Reading, Mass.:
Addison-Wesley, 1992.
В работе отмечается, что “существует несколько различных понятий в области
проектирования баз данных, которые разные авторы называют одинаково — чет-
вертая нормальная форма (4НФ)”. Назначение данной работы — прояснить смысл
494
Часть III. Проектирование базы данных
этого понятия. Здесь, вероятно, следует добавить, что единственно правильное оп-
ределение 4НФ приводится в данной главе... Не верьте никаким другим!
12.6. Date C.J. The Normal Is So... Interesting (в двух частях) // DBP&D. — November-
December, 1997. — 10, Nos. 11-12.
Обсуждение нормализации в разделе 12.5 взято из этой работы. Кроме того, следу-
ет отметить некоторые дополнительные особенности.
Даже в такой базе данных, которая используется только для чтения, необходи-
мо задавать ограничения целостности, поскольку они определяют смысл дан-
ных, а, как отмечается в разделе 12.4, отказ от денормализации предоставляет
простой способ определения некоторых важных ограничений. Если же база
данных используется не только для чтения, то исключение денормализации ее
данных предоставляет простой способ реализации этих ограничений.
Денормализация предполагает наличие повышенной избыточности данных, но
(что противоречит широко распространенному ошибочному мнению) повы-
шенная избыточность данных необязательно предполагает использование про-
цедуры денормализации! По этому поводу многие авторы заблуждались и про-
должают заблуждаться до сих пор.
В общем случае следует придерживаться такого правила: денормализацию (на
логическом уровне) следует использовать в качестве тактики повышения про-
изводительности “только в ситуации, когда все другие методы себя исчерпали”.
12.7. Date C.J. The Final Normal Form! (в двух частях) // DBP&D.— January-February,
1998. — 11, Nos. 1-2.
Учебное пособие по зависимостям соединения и 5НФ.
12.8. Date C.J. What’s Normal, Anyway? // DBP&D. — March, 1998. — 11, Nos. 3.
Обзор некоторых “патологических” примеров нормализации, в частности примера
с переменной-отношением USA из упр. 11.2 главы 11.
12.9. Date C.J. Normalization Is No Panacea // DBP&D. — April, 1998. — 11, Nos. 4.
Обзор некоторых аспектов проектирования базы данных, когда применение теории
нормализации не дает результата. Данную статью не следует рассматривать как
критику этой теории.
12.10. Date C.J., Fagin R. Simple Conditions for Guaranteeing Higher Normal Forms in
Relational Databases // C. J. Date and Hugh Darwen. Relational Database Writings
1989-1991. — Reading, Mass.: Addison-Wesley, 1992. (Работа также опубликована в
ACM TODS. — September, 1992. — 17, № 3.)
В этой работе показано, что если переменная-отношение R находится в ЗНФ и все
потенциальные ключи переменной-отношения R простые (т.е. состоят из одного
атрибута), то переменная-отношение R автоматически находится в 5НФ. Иначе го-
воря, в таком случае не стоит беспокоиться о разных относительно сложных во-
просах, связанных с многозначными зависимостями, зависимостями соединения,
4НФ и 5НФ, которые обсуждались в данной главе.
Замечание. В статье также доказан другой результат, а именно: если переменная-
отношение R находится в НФБК и хотя бы один из ее потенциальных ключей явля-
ется простым, то переменная-отношение R автоматически находится в 4НФ, но не-
обязательно в 5НФ.
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 495
12.11. Date C. J., McGovern D. A New Database Design Principle // Relational Database
Writings 1991-1994. — Reading, Mass.: Addison-Wesley, 1995.
12.12. Delobel C., Parker D.S. Functional and Multivalued Dependencies in a Relational
Database and the Theory of Boolean Switching Functions // Tech. Report No. 142. —
Dept. Maths. Appl. et Informatique, Univ, de Grenoble, France. — November, 1978.
В этой работе описанные в [10.3] результаты распространяются на многозначные
зависимости по образу и подобию функциональных зависимостей.
12.13. Fagin R. Multivalued Dependencies and a New Normal. Form for Relational Databases //
ACM TODS. — September, 1977. — 2, № 3.
Под упомянутой в заголовке этой статьи новой нормальной формой подразу-
мевается 4НФ.
Здесь следует добавить замечание о внедренных многозначных зависимостях. До-
пустим, что переменная-отношение СТХ, рассмотренная в этой главе, расширена
дополнительным атрибутом DAYS, представляющим количество дней, затраченных
на преподавание предмета по учебнику TEXT некоторым преподавателем TEACHER,
ведущим некоторый курс обучения COURSE. Назовем такую расширенную перемен-
ную-отношение именем CTXD и рассмотрим приведенный ниже пример ее данных.
COURSE TEACHER TEXT DAYS
Physics Prof. Green Basic Machanics 5
Physics Prof. Green Principles of Optics 5
Physics Prof. Brown Basic Machanics 6
Physics Prof. Brown Principles of Optics 4
Math Prof. Green Basic Machanics 3
Math Prof. Green Vector Analysis 3
Math Prof. Green Trigonometry 4
Комбинация атрибутов {COURSE, TEACHER, TEXT} в таком случае является потен-
циальным ключом этой переменной-отношения, в которой имеет место следующая
функциональная зависимость.
{ COURSE, TEACHER, TEXT } -» DAYS
Можно заметить, что данная переменная-отношение находится в 4НФ, поскольку не
содержит никаких многозначных зависимостей, которые не являются одновременно
и функциональными зависимостями (если вспомнить определения 4НФ и МЗЗ). Од-
нако она содержит две внедренные многозначные зависимости (атрибута TEACHER от
атрибута COURSE и атрибута TEXT от атрибута COURSE). Внедренная многозначная за-
висимость атрибута В от атрибута А имеет место в переменной-отношении R, если в
некоторой проекции переменной-отношения R выполняется “обычная” многозначная
зависимость А —» В. Обычная многозначная зависимость является специальным
случаем внедренной многозначной зависимости, но не все внедренные многозначные
зависимости являются обычными многозначными зависимостями.
Как иллюстрируется в данном примере, внедренные многозначные зависимости так-
же предполагают избыточность, как и обычные МЗЗ, однако она не может быть ис-
ключена с помощью разбиения на проекции. Представленную выше переменную-
496
Часть III. Проектирование базы данных
отношение нельзя подвергнуть декомпозиции без потерь (она фактически находится
не только в 4НФ, но и в 5НФ), поскольку атрибут DAYS зависит от всех трех атрибу-
тов, COURSE, TEACHER и TEXT, и потому не может присутствовать в отношении без ка-
кого-либо из этих атрибутов. Значит, две внедренные многозначные зависимости
следует рассматривать как дополнительные явно заданные ограничения для данной
переменной-отношения (подробности приводятся в последующих главах книги).
12.14. Fagin R. Normal Forms and Relational Database Operators // Proc. 1979 ACM
SIGMOD Intern. Conf, on Management of Data. — Boston, Mass. — May-June, 1979.
В статье представлена концепция проекционно-соединительной нормальной фор-
мы (или 5НФ). Эта концепция также может рассматриваться как определение того,
что можно назвать “классической” теорией нормализации, т.е. теорией декомпози-
ции без потерь, основанной на проекции как операторе декомпозиции и на естест-
венном соединении как соответствующем операторе композиции.
12.15. Fagin R. A Normal Form for Relational Databases That Is Based on Domains and Keys
// ACM TODS. — September, 1981. — 6, № 3.
12.16. Fagin R. Acyclic Database Schemes (of Various Degrees): A Painless Introduction //
IBM Research Report RJ38OO.— April, 1983. (Переиздано: Proc. CAAP83 8th
Colloquium on Trees in Algebra and Programming: Springer-Ver lag Lecture Notes in
Computer Science No. 159 (eds. G. Ausiello and M. Protasi).— New York, N.Y.:
Springer-Verlag, 1983.)
В разделе 12.3 этой главы было показано, как некоторая тройная переменная-
отношение SPJ, удовлетворяющая определенному циклическому ограничению,
может быть подвергнута декомпозиции без потерь с образованием трех бинар-
ных переменных-отношений. Полученная в результате структура базы данных
(в этой работе она называется схемой) является циклической, поскольку каж-
дая из трех переменных-отношений имеет атрибут, общий с каждой из осталь-
ных двух переменных-отношений. (Если структура описана в виде гиперграфа,
в котором ребра представляют отдельные переменные-отношения, а узел, со-
единяющий два ребра, представляет общие для этих двух переменных-
отношений атрибуты, то становится понятно, почему используется термин
“циклическая структура”.) Многие реальные структуры, наоборот, являются
ациклическими. Они обладают большим количеством формальных свойств,
которые не применимы для циклических структур. В этой статье Фейгин пред-
ставляет и разъясняет некоторые из таких свойств.
Ацикличность удобно представить в следующем виде: как теория нормализации
позволяет определить целесообразность реструктуризации отдельной переменной-
отношения, так и теория ацикличности позволяет определить целесообразность ре-
структуризации набора переменных-отношений.
12.17. Fagin R., Vardi M.Y. The Theory of Data Dependencies— A Survey// IBM Research
Report RJ4321. — June, 1984. (Переиздано: Mathematics of Information Processing //
Proc. Symposia in Applied Mathematics 34, American Mathematical Society, 1986.)
В этой работе излагается краткая история теории зависимостей по состоянию на
середину 1980-х годов (следует обратить внимание, что слово “зависимость” в
данном случае относится не только к функциональным зависимостям). В частно-
сти, в статье подытожены основные достижения в трех отдельных областях этой
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 497
теории с перечнями рекомендуемой литературы по каждой из тем. Эти три темы
включают (1) проблему импликации, (2) универсальную реляционную модель и (3)
ациклические схемы. Проблема импликации состоит в выяснении для заданного
множества зависимостей D и некоторой отдельной зависимости d, будет ли зависи-
мость d логическим следствием множества зависимостей D (подробности приво-
дятся в разделе 10.7). Универсальная реляционная модель и ациклические
схемы кратко обсуждаются в комментариях к [12.19] и [12.16] соответственно.
12.18. Fagin R., Mendelzon А.О., Ullman J.D. A Simplified Universal Relation Assumption
and Its Properties 11 ACM TODS. — September, 1982. — 7, № 3.
Здесь содержится предположение о том, что реальный мир всегда может быть
представлен с помощью универсальной переменной-отношения [12.19], которая
удовлетворяет точно одной зависимости соединения вместе с некоторым множе-
ством функциональных зависимостей, а также обсуждаются следствия такого
предположения.
12.19. Kent W. Consequences of Assuming a Universal Relation // Ibid.— December,
1981. —6, №4.
Здесь несколькими способами представлена концепция универсальной перемен-
ной-отношения. В первом способе согласно порядку нормализации, описанному в
последних двух главах, предполагается возможность задания исходного универ-
сального отношения (а точнее, универсальной переменной-отношения), которое
включает все атрибуты рассматриваемой базы данных. Затем демонстрируется, как
такая переменная-отношение может последовательно заменяться “меньшими” про-
екциями (т.е. отношениями меньшей степени) вплоть до достижения некоторой
“приемлемой” структуры. Но является ли исходное предположение реальным или
справедливым? В работе утверждается, что это не так с практической и теоретиче-
ской точек зрения. В ответ на данную статью появилась публикация [12.32], а в от-
вет на нее — [12.20].
Во втором способе, более существенном с практической точки зрения, концепция
универсальной переменной-отношения выступает в качестве интерфейса пользо-
вателя. Основная идея здесь совершенно ясна и действительно (с интуитивной
точки зрения) весьма притягательна: пользователям следует составлять запросы не
в терминах переменных-отношений и их соединений, а на основе одних только ат-
рибутов, например так, как показано в приведенном ниже выражении, где требует-
ся “получить статус всех поставщиков красных деталей”.
RETRIEVE STATUS WHERE COLOR = 'Red'
В этой связи идея имеет две более или менее различающиеся интерпретации.
1. Одна возможность заключается в том, что система должна каким-то образом само-
стоятельно определить, какому логическому пути нужно следовать для выполнения
запроса (в частности, какие соединения ей необходимо создавать). Таков подход,
предлагаемый в [12.4] (эта статья, по всей видимости, является первой статьей, по-
священной возможности создания универсального интерфейса пользователя, хотя
сам термин “универсальная переменная-отношение” в ней не упоминается). Этот
подход в значительной степени зависит от правильного именования атрибутов. Та-
ким образом, например, для двух атрибутов номера поставщика (в переменных-
498
Часть III. Проектирование базы данных
отношениях S и SP соответственно) должны быть заданы одинаковые имена; и на-
оборот, для атрибутов города, в котором находится поставщик, и города, в котором
хранятся детали (в переменных-отношениях S и Р соответственно), должны быть за-
даны разные имена. Если какое-либо из этих правил будет нарушено, то некоторые
запросы могут быть выполнены не совсем корректно.
2. В другой, менее амбициозной, интерпретации все запросы рассматриваются в
терминах предопределенного набора соединений — в действительности предо-
пределенного представления, состоящего из соединения всех переменных-
отношений в рассматриваемой базе данных.
Хотя нет сомнений в том, что любой из представленных здесь подходов позволяет
значительно упростить выражения при формулировании многих практических запро-
сов (причем тот или иной вариант данного подхода будет весьма уместен в клиент-
ских приложениях, поддерживающих естественный язык общения), ясно, что в об-
щем случае система должна поддерживать и средства явного указания логического
пути доступа. Для подтверждения данного тезиса рассмотрим следующий запрос.
RETRIEVE STATUS WHERE COLOR * 'Red'
Что означает запрос “Получить статус всех поставщиков не красных деталей” или
“Получить статус всех поставщиков, которые не поставляют красные детали”? Ка-
кой бы смысл из двух предложенных не был выбран системой, должен также су-
ществовать способ формулировки и другого варианта запроса. (К тому же первый
пример может иметь альтернативную интерпретацию: “Получить статус для по-
ставщиков только красных деталей”.) В качестве третьего примера можно привес-
ти запрос “Получить имена поставщиков, находящихся в одном и том же городе”,
для которого, очевидно, придется явным образом задать соединение (поскольку в
нем предусматривается соединение переменной-отношения S с самой собой).
12.20. Kent W. The Universal Relation Revisited // ACM TODS. — December, 1983. — 8, № 4.
12.21. Korth H.F. et al. System/U: A Database System Based on the Universal Relation
Assumption // Ibid. — September, 1984. — 9, № 3.
Здесь приводится описание теории, языка определения данных DDL, языка
управления данными DML, а также практического воплощения эксперимен-
тальной системы на основе “универсального отношения”, созданной в Стэн-
фордском университете.
12.22. Maier D., Ullman J.D. Fragments of Relations // Proc. 1983 SIGMOD Intern. Conf, on
Management of Data. — San Jose, Calif. — May, 1983.
12.23. Maier D., Ullman J.D., Vardi M.Y. On the Foundations of the Universal Relation Model
П ACM TODS. — June, 1984. — 9, № 2. (Более ранняя версия этой статьи под заго-
ловком “The Revenge of the JD” опубликована в Proc. 2nd ACM SIGFACT-SIGMOD
Symposium on Principles of Database Systems. — Atlanta, Ga., March, 1983.)
12.24. Maier D., Ullman J.D. Maximal Objects and the Semantics of Universal Relation
Databases // ACM TODS. — March, 1983. — 8, № 1.
Максимальные объекты представляют собой подход для разрешения проблемы
двузначности, возникающей в универсальных реляционных системах, базовая
структура которых не является ациклической (подробности приводятся в [12.16]).
Максимальный объект соответствует предварительно объявленному подмножеству
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 499
атрибутов универсальной переменной-отношения, для которого базовая структура
будет ациклической. Такие объекты затем используются для интерпретации за-
просов, которые в противном случае были бы двусмысленными.
12.25. Nicolas J.M. Mutual Dependencies and Some Results on Undecomposable Relations И
Proc. 4th Intern. Conf, on Very Large Data Bases. — Berlin, FDR. — September, 1978.
В работе вводится концепция взаимной зависимости, которая в действительности
представляет собой частный случай зависимости соединения, не являющейся мно-
гозначной или функциональной зависимостью, и включает точно три проекции
(как в примере с зависимостью соединения, упомянутой в разделе 12.3). Однако
эта концепция не имеет ничего общего с понятием взаимной зависимости, описан-
ным в главе 11.
12.26. Osbom S.L. Towards a Universal Relation Interface П Proc. 5th Intern. Conf, on Very
Large Data Bases. — Rio de Janeiro, Brazil. — October, 1979.
В статье предполагается, что если две или более последовательностей соединений
в системе на основе “универсального отношения” генерируют потенциальный от-
вет на заданный запрос, то желательным откликом будет соединение всех таких
потенциальных ответов. Приводятся алгоритмы для генерации всех таких последо-
вательностей соединений.
12.27. Parker D.S., Delobel С. Algorithmic Applications for a New Result on Multivalued
Dependencies // Proc. 5th Intern. Conf, on Very Large Data Bases. — Rio de Janeiro,
Brazil. —October, 1979.
Здесь описано применение результатов работы [12.12] для решения различных
проблем, например для тестирования операции декомпозиции без потерь.
12.28. Sagiv Y., Delobel С., Parker D.S., Fagin R. An Equivalence between Relational
Database Dependencies and a Subclass of Propositional Logic // JACM. — June,
1981, —28, №3.
Это комбинация работ [10.8] и [12.29].
12.29. Sagiv Y., Fagin R. An Equivalence between Relational Database Dependencies and a
Subclass of Propositional Logic // IBM Research Report RJ2500. — March, 1979.
Здесь результаты работы [10.8], полученные для функциональных зависимостей,
расширены для многозначных зависимостей.
12.30. Sciore Е. A Complete Axiomatization of Full Join Dependencies П JACM.— April,
1982. —29, №2.
Здесь результаты работы [12.2], полученные для функциональных зависимостей,
расширены для многозначных зависимостей.
12.31. Smith J.M. A Normal Form for Abstract Syntax // Proc. 4th Intern. Conf, on Very Large
Data Bases. — Berlin, FDR. — September, 1978.
Здесь впервые представлено понятие нормальной формы типа (3,3)НФ.
12.32. Ullman J.D. On Kent's Consequences of Assuming a Universal Relation // ACM
TODS. — December, 1983. — 8, № 4.
12.33. Ullman J.D. The U.R. Strikes Back // Proc. 1st ACM SIGFACT-SIGMOD Symposium
on Principles of Database Systems. — Los Angeles, Calif. — March, 1982.
500
Часть III. Проектирование базы данных
Ответы к упражнениям
12.1. Сначала приведем выражение для МЗЗ для переменной-отношения СТХ.
CONSTRAINT CTX_MVD
WITH
(СТХ RENAME COURSE AS C, TEACHER AS T, TEXT AS X)
AS Tl,
(EXTEND Tl
ADD (CTX WHERE COURSE = С) {T} AS A)
AS T2,
(EXTEND T2
ADD (CTX WHERE COURSE = C AND TEXT = X) {T} AS B)
AS T3,
(T3 WHERE A * B) AS T4 :
IS_EMPTY (T4) ;
Для нее существует, конечно, и более простое выражение.
CONSTRAINT CTX_MVD СТХ = СТХ {COURSE, TEACHER} JOIN
СТХ {COURSE, TEXT} ;
А вот выражение для зависимости соединения для переменной-отношения SPJ.
CONSTRAINT SPJ_JD SPJ = SPJ {S#, P#} JOIN
SPJ {P#, J#} JOIN
SPJ {J#, S#} ;
12.2. Прежде всего обратите внимание, что переменная-отношение R содержит все воз-
можные значения атрибута А в паре со всеми возможными значениями атрибута В.
Более того, множество всех возможных значений атрибута А, например S, такое же,
как и множество всех значений атрибута В. Следовательно, переменная-отношение
R равносильна декартову произведению множества S с самим собой. Эквивалент-
ная формулировка такова: переменная-отношение R равносильна декартову произ-
ведению проекции переменной-отношения R по атрибуту А и проекции перемен-
ной-отношения R по атрибуту В. Таким образом, переменная-отношение R удовле-
творяет следующим многозначным зависимостям (которые не являются тривиаль-
ными, поскольку не удовлетворяют всем двойным переменным-отношениям).
{ } -» А | В
Эквивалентно также утверждение, что переменная-отношение R удовлетворяет за-
висимости соединения *(А, В) (вспомните, что соединение без общих атрибутов
вырождается в декартово произведение его операндов). Отсюда следует, что пере-
менная-отношение R не находится в 4НФ и может быть подвергнута декомпозиции
без потерь на две проекции по атрибутам А и В (причем тела этих проекций будут,
безусловно, идентичны). Однако переменная-отношение R находится в НФБК
(поскольку является полностью ключевой) и не удовлетворяет никаким нетриви-
альным функциональным зависимостям.
Замечание. Переменная-отношение R также удовлетворяет двум многозначным за-
висимостям.
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 501
К -Н В I { }
в А I { }
Однако они являются тривиальными, поскольку удовлетворяют любым двойным
переменным-отношениям с атрибутами А и В.
12.3. Сначала введем три переменные-отношения, первичными ключами которых будут
имена торговых агентов, названия регионов и названия товаров соответственно.
REP { REP#, ... }
KEY { REP# }
AREA { AREA#, ... }
KEY { AREA# }
PRODUCT { PROD#, ... }
KEY { PROD# }
Затем представим связь между торговыми агентами и регионами с помощью сле-
дующей переменной-отношения.
RA { REP#, AREA# }
KEY { REP#, AREA# }
Связь между торговыми агентами и продукцией представим с помощью перемен-
ной-отношения RP.
RP { REP#, PROD# }
KEY { REP#, PROD# }
Обе эти переменные-отношения представляют связи типа “многие ко многим”.
Далее для описания того, что каждый вид продукции продается в каждом регионе,
необходимо ввести следующую переменную-отношение.
АР { AREA#, PROD# }
KEY { AREA#, PROD# }
Для представления связей, существующих между регионами и продукцией, устано-
вим ограничение (назовем его С).
АР = AREA { AREA# } TIMES PRODUCT { PROD# }
Обратите внимание на следующее: в ограничении С подразумевается, что перемен-
ная-отношение АР не находится в четвертой нормальной форме (см. упр. 12.2). На
самом деле переменная-отношение АР не дает никакой дополнительной информа-
ции, которая не может быть получена из других переменных-отношений.
АР { AREA# } = AREA { AREA# }
АР { PROD# } = PRODUCT { PROD# }
Тем не менее пока будем считать, что переменная-отношение АР включена в проект
создаваемой базы данных.
Условие, что никаких два торговых агента не продают один и тот же вид продукции в
одном и том же регионе, означает, что заданной комбинации атрибутов
502
Часть III. Проектирование базы данных
{AREA#, PROD#} соответствует только одно значение номера торгового агента
(атрибут REP#). Исходя из этого, можно ввести следующую переменную-отношение.
APR { AREA#, PROD#, REP# }
KEY { AREA#, PROD# }
Здесь явным образом реализована следующая функциональная зависимость.
{ AREA#, PROD# } -> REP#
Безусловно, определение комбинации атрибутов {AREA#, PROD#} в качестве потен-
циального ключа переменной-отношения APR является достаточным условием для
выражения этой функциональной зависимости. Однако теперь переменные-
отношения RA, RP и АР оказались избыточными, поскольку они являются проек-
циями переменной-отношения APR, а потому могут быть опущены. Вместо ограни-
чения С теперь необходимо ввести следующее ограничение С1.
APR { AREA#, PROD# } = AREA { AREA# } TIMES PRODUCT { PROD# }
Оно также должно быть задано отдельно и явным образом (поскольку оно не пред-
полагается существующими потенциальными ключами).
Кроме того, поскольку каждый торговый агент продает весь свой набор товаров в
каждом из обслуживаемых им регионов, для переменной-отношения APR необхо-
димо установить дополнительное ограничение С2 (оно представляет нетривиаль-
ную МЗЗ, следовательно, переменная-отношение APR не находится в 4НФ).
REP# AREA# | PROD#
Таким образом, в окончательном виде проект базы данных состоит из переменных-
отношений REPS, AREAS, PRODUCTS и APR вместе с заданными явным образом огра-
ничениями С1 и С2. |
Это упражнение хорошо иллюстрирует тот факт, что в общем случае порядок нор-
мализации адекватно представляет некоторые семантические аспекты заданной
проблемы (в основном, зависимости, которые подразумеваются потенциальными
ключами, где под “зависимостями” имеются в виду функциональные и многознач-
ные зависимости, а также зависимости соединения). Однако может также потребо-
ваться явное указание дополнительных зависимостей для некоторых особых аспек-
тов, а отдельные аспекты могут быть и вовсе непредставимы с помощью подобных
типов зависимостей. Это упражнение демонстрирует, что не всегда желательно
“полностью” нормализовать некоторую переменную-отношение (в нашем примере
переменная-отношение APR находится в НФБК, но не в 4НФ).
12.4. Все вносимые изменения достаточно просты — стоит лишь заменить упоминания
функциональных зависимостей и НФБК понятиями многозначной зависимости и
4НФ. Тогда алгоритм декомпозиции будет следующим.
1. Зададим переменную-отношение R в качестве начального значения для деком-
позиции D.
2. Для каждой переменной-отношения Т (которая не находится в 4НФ), входящей
в состав декомпозиции D, выполним действия, которые перечислены в пп. 2 и 3.
3. Пусть зависимость X —)-> Y является многозначной зависимостью в перемен-
ной-отношении Т, которая не удовлетворяет требованиям 4НФ.
Глава 12. Дальнейшая нормализация: более высокие нормальные формы 503
, j 4. Заменим переменную-отношение Т в декомпозиции D двумя ее проекциями, а
имецнр; одной по атрибутам X и Y, а другой — по всем атрибутам, за исключе-
нием атрибута Y.
12.5. Это пример “циклического ограничения”, которому соответствует приведенная
ниже реляционная структура.
REP { REP#, ... }
KEY { REP# }
AREA { AREA#, ... }
KEY { AREA# }
PRODUCT { REP#, ... }
KEY { PROD# }
RA { REP#, AREA# }
KEY { REP#, AREA# }
AP { AREA#, PROD# }
KEY { AREA#, PROD# }
PR { PROD#, REP# }
KEY { PROD#, REP# }
Кроме того, пользователя следует информировать о том, что соединение перемен-
ных-отношений RA, RP и АР не содержит никаких ловушек соединения.
RA JOIN АР JOIN PR ) { REP#, AREA# } = RA AND
RA JOIN АР JOIN PR ) { AREA#, PROD# } ' = AP AND
RA JOIN AP JOIN PR ) { PROD#, REP# } = PR
504
Часть III. Проектирование базы данных
Глава 13
Семантическое
моделирование
13.1. Введение
Семантическое моделирование стало предметом интенсивных исследований с конца
1970-х годов. Основным побудительным мотивом подобных исследований (т.е. пробле-
мой, которую исследователи пытались разрешить) был следующий факт. Дело в том, что
системы баз данных обычно обладают весьма ограниченными сведениями о смысле хра-
нящихся в них данных. Чаще всего они знают, как обращаться с данными определенных
простых типов, и понимают некоторые простейшие ограничения целостности, наложен-
ные на эти данные. Любая более сложная интерпретация возлагается на пользователя.
Однако было бы замечательно, если бы системы могли понимать чуть больше1 и не-
сколько разумнее отвечать на запросы пользователя, а также поддерживать более слож-
ные (т.е. более высокоуровневые) интерфейсы пользователя. Например, было бы пре-
красно, если бы язык SQL мог понимать, что вес детали и поставляемое количество яв-
ляются хотя и числовыми, но все же семантически разными величинами. Это позволило
бы системе подвергнуть сомнению или даже вовсе отвергнуть запрос, в котором соеди-
нение информации о деталях и поставках выполняется посредством сравнения веса дета-
ли с поставляемым количеством.
Конечно, к приведенному выше примеру прямое отношение имеет понятие доменов
(или типов). Это служит прекрасной иллюстрацией того факта, что существующие моде-
ли данных все же не лишены семантических аспектов. В частности, домены, потенци-
альные и внешние ключи являются примерами семантических аспектов существующей
реляционной модели, что прямо следует из их определения. В качестве другого способа
реализации семантики были разработаны различные “расширенные” модели данных, ко-
торые, тем не менее, несут лишь в незначительной степени большую смысловую нагруз-
ку, чем модели, предложенные ранее. Перефразировав Кодда [13.6], можно сказать, что
задача представления смысла данных не имеет окончательного решения и можно ожи-
1 Следует отметить, что, с нашей точки зрения, система с поддержкой предикатов пе-
ременных-отношений и базы данных (обсуждавшихся в главе 8) должна была бы "понимать
немного больше ". Иначе говоря, можно было бы возразить, что описанная поддержка преди-
катов может пониматься, как удобное и эффективное основание для семантического модели-
рования. Однако, как это ни печально, большинство схем семантического моделирования не
имеет никакого строгого обоснования, поскольку все они в той или иной степени являются
произвольными (предложения в [13.17, 13.19] являются исключениями). Возможно, такое со-
стояние дел в будущем изменится, особенно благодаря растущему пониманию в мире коммер-
ции важности бизнес-правил [8.18, 8.19]. Описанные в главе 8 предикаты, по сути, как раз и
являются такими "бизнес-правилами ”.
Глава 13. Семантическое моделирование ^505
дать (или надеяться на это!) ^прекращающегося прогресса в этом направлении по мере
углубления нашего понимания существующих проблем. Термин семантическая модель,
который часто используется по отношению к той или иной “расширенной” модели, в
данном случае не совсем подходит, поскольку предполагает, что модель построена таким
образом, чтобы выявить всю семантику рассматриваемой ситуации. С другой стороны,
понятие “семантическое моделирование” действительно является довольно удачным на-
званием целой области исследований, посвященных способам представления смыслово-
го значения. В данной главе сначала представлено краткое введение в некоторые основ-
ные идеи этой области исследований, а затем подробно описан один из конкретных под-
ходов, основанный на использовании модели “сущность/связь” (наиболее распростра-
ненный на практике).
Следует отметить, что семантическое моделирование имеет также несколько других
названий, например “моделирование данных”, “^-моделирование”, “моделирование
сущностей” и “объектное моделирование”. Здесь по указанным ниже причинам пред-
почтение отдается термину “семантическое моделирование”.
Термин “моделирование данных” не подходит, поскольку он перекликается с оп-
ределенным ранее термином “модель данных”, обозначающим формальную сис-
тему, которая включает аспекты определения структуры, поддержания целостно-
сти и манипулирования данными. Кроме того, подобное название будет способст-
вовать закреплению популярного заблуждения о том, что модель данных (в при-
веденном выше смысле) включает только структуру данных.
Замечание. Стоит напомнить (см. раздел 1.3 главы 1), что термин модель данных
используется в литературе с двумя совершенно разными значениями: первое отно-
сится к модели данных вообще (реляционная модель является моделью данных
именно в этом смысле), а второе — к модели представления перманентных дан-
ных некоторого конкретного предприятия. Здесь рассматриваемый термин в по-
следнем смысле не используется, но следует иметь в виду, что он часто использу-
ется другими авторами.
Также неудачным является термин “ER-моделирование”, поскольку в нем неявно
подразумевается существование только одного подхода к данной проблеме, тогда
как на практике, безусловно, существует несколько различных подходов. Тем не
менее термин “ER-моделирование” хорошо известен, весьма популярен и принят в
широком кругу специалистов.
Относительно термина “моделирование сущностей” нет никаких значительных
возражений за исключением того, что он кажется более специализированным по
сравнению с термином “семантическое моделирование” и предполагает некото-
рый смысловой акцент, который не совсем подходит в данном случае.
Что касается термина “объектное моделирование”, то проблема здесь заключается
в том, что термин “объект” в данном контексте, очевидно, является синонимом
термина “сущность”, тогда как он используется в совершенно другом смысле в
другом контексте (в частности, в контексте баз данных других типов, рассматри-
ваемых в части VI этой книги). По мнению автора, именно этот факт (наличие у
данного термина двух разных значений) явился причиной такого явления, как
Первый Большой Просчет (First Great Blunder) [3.3]. Более подробно этот во-
прос рассматривается в главе 25.
506
Часть III. Проектирование базы данных
Возвращаясь к главной теме нашего обсуждения, следует остановиться на причи-
не включения данного материала в эту часть книги. Идеи семантического моделиро-
вания могут быть полезны как средство проектирования базы данных даже при
отсутствии их непосредственной поддержки в СУБД. Аналогично тому, как идеи
исходной реляционной модели использовались в качестве примитивного вспомога-
тельного средства при проектировании баз данных задолго до появления любых
коммерческих воплощений этой модели, так и идеи некоторой “расширенной” моде-
ли могут оказаться полезными в качестве вспомогательного средства проектирова-
ния базы данных, даже когда никакого коммерческого воплощения этих идей еще не
существует. Действительно, было бы справедливо отметить, что на момент написа-
ния этой книги идеи семантического моделирования оказали на проектирование баз
данных большое влияние — было предложено несколько технологий проектирова-
ния, основанных на том или ином семантическом подходе. Поэтому в данной главе
основной акцент будет сделан на приложении идей семантического моделирования к
задаче проектирования базы данных.
Материал этой главы упорядочен следующим образом. После данного введения,
в разделе 13.2, описываются основные термины, используемые в семантическом мо-
делировании. Затем, в разделе 13.3, обсуждается наиболее известная из расширен-
ных моделей — предложенная Ченом (Chen) модель “сущность-связь ” (или ER-
модель; entity/relationship model— ER-model). Далее, в разделах 13.4 и 13.5, рас-
сматривается применение этой модели для проектирования базы данных. (Другие
модели кратко описываются в комментариях к некоторым публикациям, упомяну-
тым в списке рекомендуемой литературы.) После этого, в разделе 13.6, предлагается
беглый анализ некоторых аспектов ER-модели, и наконец, в разделе 13.7, приводит-
ся краткое резюме.
13.2. Общий подход
Общий подход к проблеме семантического моделирования характеризуется четырьмя
основными этапами.
1. Прежде всего попытаемся выявить некоторое множество семантических концеп-
ций (понятий), которые могут быть полезны при неформальном обсуждении реаль-
ного мира.
Например, можно согласиться с тем, что мир построен из сущностей.
(Хотя невозможно с определенной точностью описать, что именно пред-
ставляет собой сущность, эта концепция, тем не менее, оказывается весьма
полезной для описания реального мира, по крайней мере с интуитивно^
точки зрения.)
Развивая данную концепцию, можно допустить, что сущности могут быть с
пользой классифицированы по разным типам сущностей. Например, можно
предположить, что каждый отдельный работник является экземпляром неко-
торого универсального типа сущности с именем EMPLOYEE (работник). Пре-
имущество такой классификации заключается в том, что все сущности опреде-
ленного типа будут обладать некоторыми общими свойствами (например, все
работники получают зарплату), а потому подобная группировка может привес-
Глава 13. Семантическое моделирование
507
ти к некоторой (и совершенно очевидной) систематизации представлений.
Например, в терминах реляционной теории выявленная общность может быть
зафиксирована в заголовке переменной-отношения.
Более того, можно пойти еще дальше и согласиться с тем, что каждая сущность
обладает неким особым свойством, предназначенным для ее идентификации, т.е.
с тем, что каждая сущность обладает собственной идентичностью.
Наконец, можно также предположить, что каждая сущность может быть связана
с другими сущностями посредством некоторых связей.
И т.д. Однако здесь следует заметить, что все эти термины (“экземпляр сущности”,
“тип сущности”, “свойство”, “связь” и т.д.) определены не совсем точно или фор-
мально, поскольку они являются всего лишь концепциями “реального мира”, а не
формальными терминами. Таким образом, данный первый этап является нефор-
мальным, тогда как приведенные ниже второй, третий и четвертый этапы, напро-
тив, достаточно формальны.
2. Далее попытаемся определить набор соответствующих символических (т.е. фор-
мальных) объектов, которые могут использоваться для представления описанных
выше семантических концепций. (Замечание. Здесь термин объект не используется
в каком-то строго определенном смысле!) Например, в расширенной реляционной
модели (RM/T) [13.6] вводится несколько особых видов отношений, которые назы-
ваются Е- и Р-отношениями. Грубо говоря, Е-отношения (от “entity-relations”)
представляют сущности, а P-отношения (от “property-relations”) — свойства, одна-
ко Е- и P-отношения, безусловно, имеют конкретные формальные определения, то-
гда как сами сущности и свойства их не имеют.
3. Кроме того, следует определить набор формальных общих правил целостности
(или, используя терминологию главы 8, “метаограничений”), предназначенных для
работы с такими формальными объектами. Например, RM/T-модель включает пра-
вило целостности свойств, которое утверждает, что для каждого элемента Р-
отношения должен существовать соответствующий ему элемент в Е-отношении
(это отражает тот факт, что каждое свойство в базе данных должно быть свойством
некоторой сущности).
4. Наконец необходимо также определить набор формальных операторов, предна-
значенных для манипулирования этими формальными объектами. Например, в
RM/T-модели присутствует оператор PROPERTY, который можно использовать для
соединения Е-отношения со всеми соответствующими ему P-отношениями незави-
симо от того, сколько их и какие им присвоены имена, т.е. оператор, позволяющий
собрать воедино все свойства любой сущности.
Описанные в пп. 2-4 объекты, правила и операторы совместно образуют расширен-
ную модель данных, но только если эти конструкции действительно являются супермно-
жеством конструкций одной из базовых моделей, например такой, как базовая реляцион-
ная модель. Однако на самом деле в данном контексте нет четкого различия между тем,
что является расширенным, а что является базовым. Обратите особое внимание на то,
что правила и операторы являются такой же частью расширенной модели, как и объ-
екты (безусловно, это утверждение справедливо и для базовой реляционной модели).
Тем не менее с Точки зрения проектирования баз данных операторы являются менее
508
Часть III. Проектирование базы данных
важной частью модели по сравнению с объектами и правилами целостности. Поэтому за
исключением нескольких посвященных операторам комментариев основное внимание в
этой главе уделяется именно объектам и правилам.
Напомним, что на первом этапе была предпринята попытка выявить множество се-
мантических концепций, которые были бы полезны для описания реального мира. Неко-
торые из этих концепций, а именно — сущности, свойства, связи и подтипы, представле-
ны в табл. 13.1 с указанием неформального определения и приведением нескольких ти-
пичных примеров. Обратите внимание, что все эти специально подобранные примеры
иллюстрируют возможность рассмотрения одного и того же объекта реального мира од-
ними пользователями в качестве сущности, другими— в качестве свойства, а третьи-
ми — в качестве связи. (Этот пример прекрасно демонстрирует, почему невозможно дать
строгое определение такого термина, как “сущность”.) Одна из целей семантического
моделирования (несомненно, полностью достигнутая) как раз и заключается в поддержке
такой гибкости интерпретации.
Таблица 13.1. Некоторые полезные семантические концепции
Понятие Неформальное определение Примеры
СУЩНОСТЬ (Entity) Некоторый отличимый объект Поставщик, деталь, поставка Работник, отдел, человек Произведение, концерт, оркестр, дирижер Заказ на поставку, серия заказов
СВОЙСТВО (Property) Элемент информации, описы- вающий сущность Номер поставщика, поставляемое количество Отдел работника, рост человека Тип концерта Дата заказа
СВЯЗЬ (Relationship) Сущность, которая служит для обеспечения взаимодействия между двумя или более други- ми сущностями Поставка (поставщик — деталь) Должность (работник — отдел) Запись (произведение — оркестр — дирижер)
ПОДТИП (Subtype) Сущность типа Y является подтипом сущности типа X тогда и только тогда, когда каждый экземпляр сущности типа У обязательно является экземпляром сущности типа X “Работник” является подтипом сущности “Человек” “Концерт” является подтипом сущ- ности “Произведение”
Кроме того, следует отметить, что вполне возможно возникновение конфликтов меж-
ду терминами, которые представлены в табл. 13.1 и используются на семантическом
уровне, и терминами, которые используются в рамках выбранного формального подхода,
например в реляционной модели. В частности, во многих схемах семантического моде-
лирования вместо термина свойство используется термин атрибут, но при этом совсем
не обязательно подразумевается, что такой атрибут представляет (или отображается на)
Глава 13. Семантическое моделирование
509
то же самое, что и атрибут реляционного уровня. Еще одним (важным!) примером может
быть то, что концепция типа сущности, как она понимается в семантическом моделиро-
вании, отличается от концепции типа, которая рассматривалась в главе 5. Точнее гово-
ря, подобным типам сущностей в реляционном проекте соответствуют переменные-
отношения, а потому они, очевидно, не соответствуют реляционными типам атрибута
(доменам). Однако по перечисленным ниже причинам они не полностью соответствуют
и типам отношений.
1. На семантическом уровне некоторые базовые типы отношений, вероятно, будут
соответствовать типам связей, а не типам сущностей.
2. Говоря упрощенно, производные типы отношений могут вообще ничему не соот-
ветствовать на семантическом уровне.
Путаница при определении этих уровней (в частности, вследствие несогласованности
используемой терминологии) как в прошлом, так и в настоящем часто служит причиной
дорогостоящих ошибок (см. раздел 25.2 главы 25).
В заключение следует заметить, что в главе 1 связи рассматривались как сущности
особого рода, причем подчеркивалось, что подобным же образом они будут рассматри-
ваться во всей книге. Кроме того, в главе 3 как одно из преимуществ реляционной моде-
ли отмечалось единство представления всех типов сущностей, включая связи, посредст-
вом переменных-отношений. Тем не менее концепция связей (так же, как и концепция
сущностей) действительно интуитивно полезна при описании реального мира. Более то-
го, представленный ниже, в разделах 13.3-13.5, подход к проектированию базы данных
будет в значительной степени опираться на различия между сущностями и связями. По-
этому в нескольких следующих разделах будет принята терминология, предусматри-
вающая разделение понятий сущностей и связей, однако в разделе 13.6 по этому вопросу
будут представлены некоторые дополнительные замечания.
13.3. Модель “сущность/связь”
Как уже упоминалось в разделе 13.1, одним из наиболее известных и получивших
широкое распространение методов семантического моделирования является построение
модели “сущность/связь” (или ER-модели). Этот подход строится на использовании
модели “сущность/связь”, предложенной Ченом в 1976 году [13.5] и с тех пор неодно-
кратно усовершенствовавшейся как самим Ченом, так и многими другими исследовате-
лями (об этом можно прочесть, например, в [13.13], [13.40]-[ 13.42]). Дальнейшее обсуж-
дение в настоящей главе, в основном, посвящено именно данному подходу. (Следует
подчеркнуть, что модель “сущность/связь” является далеко не единственной
“расширенной” моделью— их было предложено достаточно много. В частности, в
[13.5], [13.13], [13.25] и особенно в [13.19] приведены общие вводные сведения по неко-
торым из них, а в [13.22], [13.31] — вводные обзоры по данной теме.)
ER-модель включает аналоги всех семантических объектов, представленных в
табл. 13.1, каждый из которых подробно рассматривается далее в этой главе. Прежде
всего отметим, что в [13.5] была предложена не только сама ER-модель как таковая,
но и соответствующая ей технология построения диаграмм, получивших название
“ER-диаграммы”. Более подробно ER-диаграммы описываются в следующем разделе,
а на рис. 13.1 показан простой пример подобной диаграммы, взятый из [13.5]. Это
510
Часть III. Проектирование базы данных
пример представления структуры данных некоторой производственной компании
(KnowWare, Inc.). Он будет полезен при изучении последующего материала этой главы
и подробно описывается ниже. (Это расширенная версия ER-диаграммы, приведенной
на рис. 1.5 в главе 1.)
Рис. 13.1. Диаграмма модели “сущность/связъ” (сокращенная версия для рассматри-
ваемого примера)
Замечание. Большинство рассматриваемых в следующих подразделах идей хорошо
известно тем, кто знаком с реляционной моделью. Но, как будет показано, между ис-
пользуемыми в этих двух моделях терминами существуют определенные различия.
Сущности
Работа [13.5] начинается с определения сущности (entity) как “предмета, который
может быть четко идентифицирован”. При этом сущности подразделяются на силь-
ные и слабые. Слабой называется такая сущность, существование которой зависит от
другой сущности, т.е. она не может существовать, если этой другой сущности не су-
ществует. Например, на рис. 13.1 сущность DEPENDENT (подчиненный работник) явля-
ется слабой, поскольку она не может существовать (в контексте данной базы данных),
если не существует соответствующей сущности EMPLOYEE (работник). В частности, ес-
ли сведения о некотором работнике (сущность EMPLOYEE) будут удалены, то и сведения
обо всех зависящих от него работниках (сущности DEPENDENT) также будут удалены.
Сильной называется сущность, которая не является слабой. В нашем примере сущ-
ность EMPLOYEE — сильная.
Замечание. Некоторые авторы вместо термина “сильная сущность” используют тер-
мин “нормальная (regular) сущность”.
Глава 13. Семантическое моделирование
511
Свойства
Сущности (и связи) обладают некоторыми свойствами (property). Все сущности или
связи одного и того же типа обладают некоторыми общими свойствами. Например, все
работники имеют личный номер, имя, зарплату и т.д. (Замечание. В данном примере
среди свойств работника сознательно не упоминается номер отдела; причина этого разъ-
ясняется несколько ниже.) Значения свойств каждого типа извлекаются из соответст-
вующего множества значений, которое в реляционной терминологии называется доме-
ном. Ниже перечислены некоторые разновидности свойств и указаны их особенности.
Простое или составное свойство. Например, свойство “имя работника” может
быть составным, если его значение составляется из значений простых свойств
“имя”, “отчество” и “фамилия”.
Ключевое свойство (т.е. уникальное, возможно, в определенном контексте). На-
пример, имя подчиненного работника для определенного сотрудника может быть
уникальным только в контексте этого сотрудника.
Однозначное или многозначное свойство (т.е. в этой модели допускаются повто-
ряющиеся группы). Все свойства, представленные на рис. 13.1, являются одно-
значными. Однако если некоторый поставщик (SUPPLIER) будет иметь несколько
разных пунктов отгрузки, то свойство CITY (Город) для него будет многозначным.
Опущенное свойство (т.е. “неизвестное” или “непредставленное”). Эта концепция
не отражена на рис. 13.1, а ее более подробное описание приводится в главе 18.
Базовое или производное свойство. Например, общее количество деталей опре-
деленного вида может быть вычислено с помощью суммирования объема отдель-
ных поставок данной детали. Эта концепция также не представлена на рис. 13.1.
Связи
В [13.5] связь (relationship) определяется как “ассоциация, объединяющая несколько
сущностей”. Например, между отделами и работниками существует связь с именем
DEPT_EMP. Она представляет тот факт, что в каждом отделе работает определенное коли-
чество работников. Так же, как и в отношении сущностей (см. главу 1), необходимо по-
нимать принципиальную разницу между типами и экземплярами связей, однако при не-
формальном описании такими тонкостями можно пренебречь, что мы и будем неодно-
кратно делать в будущем.
Сущности, включенные в связь, называются ее участниками, а количество участни-
ков связи называется ее степенью. (Следует отметить, что в данном случае значение
термина “степень” отличается от его значения в реляционной модели.)
Пусть R является типом связи, включающей тип сущности Е в качестве участника. Ес-
ли каждый экземпляр сущности Е участвует по крайней мере в одном экземпляре связи R,
то участие сущности Е в связи R называется полным, в противном случае — частич-
ным. Например, если каждый работник обязательно должен относиться к определенно-
му отделу, то участие сущности EMPLOYEE в связи между работниками и отделами
(DEPT_EMP) является полным. В свою очередь, если допустима ситуация, когда в некото-
ром отделе не будет ни одного работника, участие сущности DEPARTMENT в связи
DEPT_EMP будет частичным.
512
Часть III Проектирование базы данных
Связи в модели “сущность/связь” могут иметь тип “один к одному”, “один ко мно-
гим” (иначе может называться “многие к одному”) или “многие ко многим”. (Для уп-
рощения изложения далее предполагается, что все связи являются двойными, т.е. имеют
степень “два”, хотя, конечно, изложенные концепции и терминологию можно без труда
расширить и на связи с более высокой степенью.) Здесь читатель, уже знакомый с осно-
вами реляционной модели, мог бы заметить, что именно тип связи “многие ко многим”
является единственным типом, представляющим истинную связь, поскольку это единст-
венный тип связи, который требует для своего представления создания отдельной пере-
менной-отношения. Связи типа “один к одному” и “один ко многим” всегда могут быть
представлены с помощью механизма внешнего ключа, помещаемого в одну из перемен-
ных-отношений, участвующих в данной связи. Однако существуют веские причины рас-
смотрения связей типа “один к одному” и “один ко многим” таким же образом, как и свя-
зи типа “многие ко многим”, по крайней мере из-за того, что достаточно часто существу-
ет возможность их эволюционирования до связи типа “многие ко многим” с течением
времени. И только если такой возможности нет, их можно рассматривать как-то иначе.
Безусловно, в некоторых случаях подобной возможности может не быть в принципе,
например всегда будет верным утверждение, что окружность обладает только одной точ-
кой, являющейся ее центром.
Подтипы и супертипы сущностей
Замечание. Представленные в этом разделе идеи не были включены в оригинальную
версию ER-модели [13.5]; они были добавлены позднее. Подробнее об этом можно про-
честь, например, в работе Тиори (Теогеу), Янга (Yang) и Фрая (Fry) [13.41].
Каждая сущность имеет по крайней мере один тип, однако у некоторой сущности
может быть одновременно несколько типов. Например, если некоторые работники
являются программистами (и все программисты являются работниками), то можно
сказать, что тип сущности PROGRAMMER (программист) является подтипом типа сущ-
ности EMPLOYEE (работник). (Или, что эквивалентно, тип сущности EMPLOYEE являет-
ся супертипом типа сущности PROGRAMMER.) Программисты автоматически обладают
всеми свойствами работников, однако обратное утверждение неверно (например,
для программистов может быть задано свойство “изученный язык программирова-
ния”, которое в общем случае не применимо ко всем работникам). Аналогично сущ-
ность PROGRAMMER автоматически участвует во всех связях, в которых участвует
сущность EMPLOYEE, однако обратное утверждение также неверно (например, про-
граммисты могут входить в профсоюз компьютерных специалистов, в который про-
чие работники в общем случае не входят). Поэтому говорится, что подтип наследу-
ет свойства и связи супертипа.
Обратите внимание, что одни программисты (сущность PROGRAMMER) могут быть при-
кладными программистами (сущность APPLICATION_PROGRAMMER), а другие — системны-
ми программистами (SYSTEM_PROGRAMMER). Исходя из этого, можно сказать, что типы
APPLICATION_PROGRAMMER и SYSTEM_PROGRAMMER являются подтипами супертипа
PROGRAMMER и т.д. Иначе говоря, сущность-подтип по-прежнему является типом сущно-
сти и, следовательно, может иметь собственные подтипы. Некоторый тип сущности, его
непосредственные подтипы, подтипы этих подтипов и т.д. все вместе образуют иерар-
хию типов сущности, пример которой представлен на рис. 13.2.
Глава 13. Семантическое моделирование
513
Здесь стоит подробно рассмотреть следующие особенности.
1. Поскольку детальное обсуждение иерархии и наследования типов будет отложено
до главы 19, следует предупредить читателя, что в данной главе термин тип имеет
такое же значение, как и в главе 5 (т.е. он не означает “тип сущности”).
2. Для читателей, знакомых с СУБД IMS (или какой-нибудь иной СУБД, в кото-
рой используется иерархическая структура данных), необходимо отметить, что
иерархии типов не следует путать с иерархиями данных. Например, на
рис. 13.2 вовсе не подразумевается, что для одного работника (EMPLOYEE) име-
ется несколько соответствующих программистов (PROGRAMMER). Наоборот, для
одного экземпляра типа сущности EMPLOYEE существует не более одного соот-
ветствующего экземпляра типа сущности PROGRAMMER, представляющего того
же работника в роли программиста.
На этом краткое обсуждение основных структурных особенностей ER-модели завер-
шено, и можно перейти к рассмотрению ER-диаграмм.
Рис. 13.2. Пример иерархии типов сущностей
13.4. ER-диаграммы
Как уже указывалось в предыдущем разделе, в [13.3] была не только введена сама
модель “сущность/связь”, но и представлена концепция ER-диаграмм. Такая диа-
грамма является методом представления логической структуры базы данных в графи-
ческом виде для более простого и наглядного отображения основных компонентов
конкретного проекта базы данных (один рисунок порой стоит тысячи слов). Действи-
тельно, популярность методов ER-моделирования как подхода для проектирования баз
данных, скорее всего, объясняется именно наличием подобной диаграммной техноло-
гии, а не чем-либо иным. Ниже правила создания ER-диаграмм поясняются на приме-
рах, представленных на рис. 13.1 и 13.2.
Замечание. Так же, как и сама модель “сущность/связь”, технология создания ER-
диаграмм постоянно совершенствуется, поэтому в данном разделе будет описана та ее
версия, которая отличается в некоторых важных аспектах от оригинальной методики,
предложенной Ченом в [13.3].
514
Часть III. Проектирование базы данных
Сущности
Каждый тип сущности на ER-диаграмме представляется в виде отдельного прямо-
угольника с указанным внутри именем сущности, причем прямоугольники сущностей
слабых типов рисуются двойной линией.
Примеры (см. рис. 13.1)
Сильные сущности:
DEPARTMENT (отдел)
EMPLOYEE (работник)
SUPPLIER (поставщик)
PART (деталь)
PROJECT (проект)
Слабая сущность:
DEPENDENT (подчиненный)
Свойства
Свойства отображаются на ER-диаграмме в виде эллипсов, содержащих имена этих
свойств. Эллипсы соединяются с соответствующей сущностью (или связью) сплошной
линией. Контур эллипса рисуется штриховой линией, если свойство производное, и
двойной линией, если свойство многозначное. Если свойство составное, то составляю-
щие его свойства показаны в виде других эллипсов, соединенных с эллипсом составного
свойства с помощью дополнительных линий. Имена ключевых свойств обычно подчер-
киваются, а множества значений не отображаются вовсе.
Примеры (см. рис. 13.1)
Для сущности EMPLOYEE:
EMP# (личный номер работника — ключевое свойство)
ENAME (полное имя — составное, состоящее из свойств FIRST (имя), MI (отчество) и
LAST (фамилия))
SALARY (зарплата)
Для сущности SUPPLIER:
S# (номер поставщика — ключевое свойство)
SNAME (имя поставщика)
STATUS (статус поставщика)
CITY (город, в котором находится поставщик)
Для связи SUPP_PART_PROJ:
QTY (количество)
Для связи PART_STRUCTURE:
QTY (количество)
Для экономии места другие свойства, представленные на рис. 13.1, не показаны.
Глава 13. Семантическое моделирование
515
Связи
Каждый тип связи показан на ER-диаграмме в виде ромба с названием связи внутри.
Ромб рисуется двойной линией, если это связь между слабым типом сущности и типом
сущности, от существования которого она зависит. Участники каждой связи соединяют-
ся с ромбом соответствующей связи сплошными линиями. Каждая такая линия содержит
надпись “1” или “М” для обозначения типа связи (“один к одному”, “один ко-многим” и
т.д.). Двойная линия обозначает полное участие в связи данной стороны.
Примеры (см. рис. 13.1)
DEPT_EMP (связь типа “один ко многим” между сущностями DEPARTMENT и EMPLOYEE)
EMP_DEP (связь типа “один ко многим” между сущностью EMPLOYEE и сущностью
слабого типа DEPENDENT)
PROJ_WORK и PROJ_MANAGER (обе связи установлены между сущностями EMPLOYEE и
PROJECT, причем первая имеет тип “многие ко многим”, а вторая — “один ко многим”)
SUPP_PART_PROJ (связь типа “многие ко многим” между сущностями SUPPLIER,
PART и PROJECT)
SUPP_PART (связь типа “многие ко многим” между сущностями SUPPLIER и PART)
PART_STRUCTURE (связь типа “многие ко многим” между сущностями PART и PART)
Обратите внимание, что в последнем случае две линии от PART к PART_STRUCTURE
отличаются надписями с указанием различных выполняемых ролей (ЕХР и IMP, ко-
торые обозначают соответственно “разложение детали на компоненты” и “сборку
детали из компонентов”). Связь PART_STRUCTURE является типичным примером ре-
курсивной связи.
Подтипы и супертипы сущностей
Пусть тип сущности Y является подтипом типа сущности X. Тогда от прямоугольника
Y к прямоугольнику X можно провести сплошную линию со стрелкой на конце возле Y.
Эта линия представляет то, что иногда называется связью принадлежности (isa
relationship) (поскольку множество всех сущностей типа Y “является” (is а) подмножест-
вом множества всех сущностей типа X).
Примеры (см. рис. 13.2)
Тип сущности PROGRAMMER является подтипом типа сущности EMPLOYEE
Типы сущностей APPLICATION_PROGRAMMER и SYSTEM_PROGRAMMER являются подти-
пами типа сущности PROGRAMMER
13.5. Проектирование базы данных с помощью
метода ER-моделирования
В определенном смысле построенная в соответствии с описанными выше правилами
ER-диаграмма является проектом базы данных. Если попытаться отобразить подобный
проект на некоторую формальную схему, соответствующую требованиям конкретной
516
Часть III. Проектирование базы данных
СУБД2, то станет ясно, что обычная ER-диаграмма для этого недостаточно точна и в ней
отсутствует описание множества важных деталей (особенно тех, которые относятся к це-
лостности данных). Для иллюстрации этого утверждения рассмотрим, что происходит
при попытке отобразить проект базы данных, показанный на рис. 13.2, на набор опреде-
лений элементов реляционной базы данных.
Сильные сущности
На рис. 13.1 показаны следующие сильные типы сущностей.
DEPARTMENT
EMPLOYEE
SUPPLIER
PART
PROJECT
Каждый сильный тип сущности отображается в базовую переменную-отношение.
Следовательно, рассматриваемая база данных будет содержать пять базовых перемен-
ных-отношений, например DEPT, ЕМР, S, Р и J, соответствующих этим пяти типам сущ-
ности. Более того, каждое из базовых отношений будет иметь потенциальный ключ
(DEPT#, ЕМР#, S#, P# и J#), соответствующий указанным на ER-диаграмме ключевым
свойствам. Для определенности допустим, что в каждой из создаваемых переменных-
отношений соответствующий потенциальный ключ определяется, как первичный. В
качестве примера ниже приводится определение переменной-отношения DEPT (в со-
кращенном виде).
VAR DEPT BASE RELATION
{ DEPT# ..., ... )
PRIMARY KEY ( DEPT# ) ;
Записать определения остальных четырех переменных-отношений предлагается чита-
телю в качестве упражнения.
Замечание. Безусловно, в документации также должны быть зафиксированы опреде-
ления доменов и допустимых множеств значений. Однако подробности здесь
опускаются, поскольку, как уже отмечалось, множества значений на ER-диаграммах не
отображаются.
Связи типа “многие ко многим”
В рассматриваемом примере присутствуют следующие связи типа “многие ко многим”.
PROJ_WORK (между работниками и проектами)
SUPP_PART (между поставщиками и деталями)
SUPP_PART_PROJ (между поставщиками, деталями и проектами)
PART_STRUCTURE (между деталями-узлами и деталями, входящими в их состав)
2 В настоящее время существует множество инструментов, позволяющих выполнить такое
отображение (например, ER-диаграмма для генерации соответствующего набора SQL-команд
CREATE TABLE).
Глава 13. Семантическое моделирование
517
Каждая такая связь отображается и в базовую переменную-отношение. Таким обра-
зом, вводятся еще четыре базовые переменные-отношения, соответствующие четырем
указанным связям. Допустим, что для связи SUPP_PART такой базовой переменной-
отношением является SP (уже знакомая нам переменная-отношение поставок). Временно
отложим описание ее первичного ключа и обратимся к внешним ключам этой перемен-
ной-отношения, которые необходимы для идентификации участников данной связи.
VAR SP BASE RELATION
{ S# ... , P# ... , ... }
FOREIGN KEY { S# } REFERENCES S
FOREIGN KEY { P# } REFERENCES P ;
Ясно, что такая переменная-отношение должна включать два внешних ключа (S#
и Р#), соответствующих двум участникам связи (сущности SUPPLIER и PART), и эти
внешние ключи должны ссылаться на соответствующие переменные-отношения S и
Р. Более того, для каждого из внешних ключей должен быть задан подходящий слу-
чаю набор правил внешних ключей, т.е. правило обновления UPDATE и правило удале-
ния DELETE (за более подробными сведениями по этой теме обратитесь к главе 8).
Ниже приведены правила, которые следует задать в случае базовой переменной-
отношения SP. (Конечно, эти правила приведены лишь в качестве иллюстрации. В
частности, обратите внимание на то, что их нельзя вывести или установить с помо-
щью одной только ER-диаграммы.)
VAR SP BASE RELATION
{ S# ... , P# ... , ... }
FOREIGN KEY ( S# ) REFERENCES S
ON DELETE RESTRICT
ON UPDATE CASCADE
FOREIGN KEY ( P# ) REFERENCES P
ON DELETE RESTRICT
ON UPDATE CASCADE ;
Что можно сказать о первичном ключе этой переменной-отношения? Одним из воз-
можных способов его определения может быть комбинация внешних ключей, идентифи-
цирующих участников соответствующей связи (в случае базовой переменной-отношения
SP ими являются атрибуты S# и Р#). Это возможно, если данная комбинация имеет уни-
кальное значение для каждого экземпляра данной переменной-отношения (обычно так и
бывает, хотя могут быть и обратные случаи) и если разработчик базы данных не возра-
жает против использования составных первичных ключей (на практике это в равной сте-
пени возможно и невозможно). В качестве альтернативного варианта первичного ключа
можно использовать новый несоставной суррогатный атрибут “номер поставки”
(подробности приводятся в [13.10], [13.16]). В нашем примере будет использован первый
из двух описанных выше вариантов. Таким образом, в определение SP необходимо доба-
вить следующее предложение.
518
Часть III. Проектирование базы данных
PRIMARY KEY { S#, P# }
В качестве упражнения читателю предлагается самостоятельно рассмотреть связи
PR0J_W0RK, PART_STRUCTURE и SUPP_PART_PROJ.
Связи типа “многие к одному”
В рассматриваемом примере присутствуют три связи типа “многие к одному”.
PROJ_MANAGER (между проектами и их менеджерами)
DEPTJSMP (между работниками и отделами)
EMP_DEP (между подчиненными и руководящими работниками)
Только в последней из трех связей участвует слабый тип сущности (DEPENDENT), тогда
как в двух других участвуют только сильные типы сущностей. Связь со слабым типом
сущности будет обсуждаться несколько позже, а сейчас рассмотрим какую-либо из двух
других связей, например DEPTJSMP. В данном случае не требуется вводить никаких новых
переменных-отношений3. Вместо этого достаточно просто ввести приведенный ниже
внешний ключ в переменную-отношение, расположенную со стороны “многие” (ЕМР),
который будет ссылаться на переменную-отношение на стороне “один” (DEPT).
VAR ЕМР BASE RELATION
{ EMP# ... , DEPT# ... , ... }
PRIMARY KEY { EMP# }
FOREIGN KEY { DEPT# } REFERENCES DEPT
ON DELETE ...
ON UPDATE ... ;
В данном случае возможности определения правил удаления DELETE и обновления
UPDATE точно такие же, как и в случае внешнего ключа, представляющего участника свя-
зи типа “многие ко многим” (в общем случае). Здесь вновь следует отметить, что они не
показаны на данной ER-диаграмме.
Замечание. В рассматриваемом примере предполагается, что связи типа “один к од-
ному” (которые не так уж часто встречаются на практике) следует рассматривать так же,
как связи “многие к одному”. Подробное описание особенностей отображения связей ти-
па “один к одному” приводится в [13.7].
Слабые сущности
Связь между сущностью слабого типа и той сильной сущностью, от которой она зависит,
безусловно, является связью типа “многие к одному”, как это уже отмечалось выше. Однако
правила удаления и обновления для этой связи должны выглядеть так, как показано ниже.
ON DELETE CASCADE
ON UPDATE CASCADE
3 Хотя, возможно, это имело бы некоторый смысл. Как указывалось в разделе 13.1, могут
существовать веские причины для рассмотрения определенных связей типа “многие к одному”
так, как будто на самом деле они имеют тип “многие ко многим". Дополнительную информа-
цию можно найти в последней части работы [18.20].
Глава 13. Семантическое моделирование
519
Взятые в совокупности, эти правила выражают обязательную зависимость существо-
вания, что иллюстрируется следующим примером.
VAR DEPENDENT BASE RELATION
{ EMP# ... }
FOREIGN KEY ( EMP# ) REFERENCES EMP
ON DELETE CASCADE
ON UPDATE CASCADE ;
Что является первичным ключом данной переменной-отношения? Как и в случае со
связью “многие ко многим”, здесь также возможен некоторый выбор. Одним из вариан-
тов является комбинация внешнего ключа и ключевого свойства слабой сущности, пред-
ставленного на ER-диаграмме, если, опять же, разработчик базы данных не возражает
против использования составных первичных ключей. Альтернативным вариантом пер-
вичного ключа является введение нового несоставного суррогатного атрибута
(подробности приводятся в [13.10], [13.16]). В рассматриваемом примере мы применим
первый из двух приведенных выше вариантов, для чего добавим в определение перемен-
ной-отношения следующее предложение.
PRIMARY KEY { ЕМР#, DEP_NAME }
Свойства
Каждое показанное на ER-диаграмме свойство отображается в отдельный атрибут в
соответствующей переменной-отношении, за исключением случая многозначного свой-
ства, для которого потребуется создать новую переменную-отношение, что прямо следу-
ет из принципов нормализации. Домены для множеств значений создаются простым и
очевидным способом (хотя, конечно, сам выбор множеств допустимых значений может
оказаться не совсем простой задачей), поэтому подробности здесь опущены.
Супертипы и подтипы сущности
Поскольку на рис. 13.1 не содержится никаких супертипов или подтипов, далее
речь пойдет о примере, представленном на рис. 13.2. Рассмотрим типы сущностей
EMPLOYEE и PROGRAMMER. Предположим для простоты, что программисты обладают
навыками работы только с одним языком программирования (т.е. свойство LANG яв-
ляется однозначным)4.
Супертип EMPLOYEE отображается в базовую переменную-отношение, например
ЕМР, обычным образом (т.е. так, как уже обсуждалось выше).
4 Здесь, в частности, следует отметить, что мы не собираемся отображать типы сущно-
стей EMPLOYEE и PROGRAMMER на какие-то “супертабличные” или “подтабличные” конструк-
ции. В этом заключается концептуальная трудность или, по крайней мере, ловушка: из того,
что на ER-диаграмме тип сущности Yявляется подтипом типа сущности X, не следует, что ре-
ляционный аналог сущности Yявляется “подчиненным”реляционного аналога сущности X, и это
действительно так. Более подробно данная тема рассматривается в [13.12].
520
Часть III. Проектирование базы данных
Подтип PROGRAMMER отображается в другую базовую переменную-отношение, на-
пример PGMR, с таким же первичным ключом, что и у переменной-отношения ее
супертипа, но с другим набором атрибутов, соответствующим свойствам, которые
применяются для описания только работников-программистов (например, LANG в
нашем примере).
VAR PGMR BASE RELATION
{ EMP# ... , LANG, ... }
PRIMARY KEY { EMP# } ... ;
Более того, первичный ключ переменной-отношения PGMR также является
внешним ключом, который ссылается на переменную-отношение ЕМР. Следо-
вательно, приведенное выше определение необходимо соответствующим об-
разом расширить (в частности, обратите внимание на определение правил
удаления и обновления).
VAR PGMR BASE RELATION
{ EMP# ... , LANG, ... }
PRIMARY KEY ( EMP# ) ;
FOREIGN KEY ( EMP# ) REFERENCES EMP
ON DELETE CASCADE
ON UPDATE CASCADE ;
Нам также потребуется представление, например с именем EMP_PGMR, являющееся
соединением переменных-отношений супертипа и подтипа.
VAR EMP_PGMR VIEW
ЕМР JOIN PGMR ;
Обратите внимание, что это соединение имеет тип связи “(нуль или один) к
одному”, направлено от потенциального ключа к соответствующему внешне-
му ключу и этот внешний ключ сам по себе является потенциальным ключом.
В результате представление будет содержать сведения только о работниках-
программистах.
Такая структура позволяет выполнять следующие действия.
С помощью базовой переменной-отношения ЕМР можно получить доступ
(например, для извлечения данных) к тем свойствам, которые являются общими
для всех работников.
С помощью базовой переменной-отношения PGMR можно получить доступ к осо-
бым свойствам, принадлежащим только программистам.
С помощью представления EMP_PGMR можно получить доступ ко всему набору
свойств программистов.
В базовую переменную-отношение ЕМР можно вставлять сведения о работниках,
которые не являются программистами.
Сведения о работниках-программистах можно вставлять в базу данных с помо-
щью представления EMP_PGMR.
Глава 13. Семантическое моделирование
521
Сведения о любых работниках (программистах и не программистах) можно уда-
лить из базы данных, удалив их из базовой переменной-отношения ЕМР, а сведения
о работниках-программистах можно удалить из базы данных, удалив их из пред-
ставления EMP_PGMR.
Свойства, общие для всех работников, можно обновлять в базовой переменной-
отношении ЕМР, а свойства только работников-программистов можно обновлять и
с помощью представления EMP_PGMR.
Свойства, характерные только для программистов, можно обновлять в базовой
переменной-отношении PGMR.
Статус сотрудника-не программиста можно изменить на статус программиста за
счет вставки сведений об этом сотруднике в базовую переменную-отношение PGMR
или же в представление EMP_PGMR.
Статус программиста можно изменить на статус сотрудника-не программиста за счет
удаления сведений об этом программисте из базовой переменной-отношения PGMR.
Читателю предлагается самостоятельно разобраться в других типах сущностей, пока-
занных на рис. 13.2 (APPLICATION-PROGRAMMER и SYSTEM_PROGRAMMER).
13.6. Краткий анализ ER-модели
В этом разделе кратко рассматриваются некоторые определенные аспекты ER-модели.
Большая часть излагаемого здесь материала взята из другой работы автора [13.8], в которой
эта тема обсуждается подробнее. Дополнительные сведения и комментарии можно найти в
аннотациях, помещенных в список рекомендуемой литературы к данной главе.
ER-модель как основа реляционной модели
Рассмотрим подход с использованием ER-модели с несколько иной точки зрения.
Надо полагать, вполне очевидно, что идеи, послужившие основанием для разработки
этого подхода, во многом очень близки тем идеям, которые послужили Кодду нефор-
мальной основой при создании им исходной формальной реляционной модели. Как
уже объяснялось в разделе 13.2, общий подход к разработке “расширенных” моделей
включает четыре больших этапа; назначение каждого из них можно кратко сформули-
ровать следующим образом.
1. Идентифицировать полезные семантические концепции.
2. Определить формальные объекты.
3. Определить формальные правила поддержки целостности данных (“метаограничения”).
4. Определить формальные операторы.
Обратите внимание, что эти этапы вполне применимы и для разработки базовой
реляционной модели (а также для любой другой формальной модели данных), а не
только для “расширенных” моделей, подобных ER-модели. Иначе говоря, для того
чтобы создать формальную базовую реляционную модель, Кодд прежде всего должен
был выявить некоторые неформальные “полезные семантические концепции”. Эти
концепции в основе своей были близки идеям ER-моделированя или чему-то очень
522
Часть III. Проектирование базы данных
схожему с ними. Действительно, работы Кодда подтверждают это, поскольку в его
первой статье (самой ранней версии работы [5.1]), посвященной реляционной модели,
имеются следующие строки.
“Множество сущностей заданного типа сущности можно рассматривать как
отношение, и такое отношение мы будем называть отношением типа сущно-
сти... Оставшиеся отношения... между типами сущностей... называются меж-
сущностными отношениями... Важнейшим свойством каждого межсущност-
ного отношения является то, что [оно содержит по крайней мере два внешних
ключа, которые] обращаются к различным типам сущностей либо к общему
типу сущности, выполняющему различные роли. ”
Здесь Кодд явно предлагает использовать отношения для моделирования и “сущ-
ностей”, и “связей”. Но самое главное заключается в том, что отношения являются
формальными объектами, а реляционная модель — формальной системой. Ценность на-
учного вклада Кодда состоит в том, что он нашел удачную формальную модель для оп-
ределенных аспектов реального мира.
В противоположность этому ER-модель не является (или, по крайней мере, не в пер-
вую очередь является) формальной моделью. Фактически она состоит из набора пре-
имущественно неформальных концепций, соответствующих только первому из четырех
приведенных выше этапов. (Более того, ее формальные аспекты на самом деле не очень
значительно отличаются от соответствующих аспектов основной реляционной модели;
обсуждение этого вопроса будет продолжено ниже.) Для проектирования базы данных,
конечно, полезно иметь в своем распоряжении, помимо всего прочего, набор концепций,
определенных на этапе 1. Однако несомненным остается тот факт, что проектирование
базы данных не может быть завершено без применения формальных объектов и правил,
представленных на этапах 2 и 3, а множество других задач и вовсе не может быть реше-
но без использования формальных операторов, определяемых на этапе 4.
• Следует отметить, что перечисленные выше замечания не предполагают доказатель-
ства бесполезности ER-модели; скорее всего, наоборот. Однако одной этой модели не-
достаточно. Более того, несколько странным кажется тот факт, что первые описания не-
формальной ER-модели были опубликованы спустя несколько лет после опубликования
описания формальной реляционной модели, изначально основанной (как мы видели) на
некоторых идеях ER-модели.
Является ли ER-модель моделью данных
Из вышеизложенного не совсем ясно, является ли ER-модель на самом деле моде-
лью данных, по крайней мере в предложенном в этой книге смысле (т.е. формальной
системой, включающей структурные аспекты, аспекты поддержания целостности и
манипулирования данными). Конечно, термин “ER-моделирование” обычно использу-
ется для обозначения процесса выбора только структуры базы данных, хотя выше, в
разделах 13.3-13.55, рассматривались и некоторые аспекты целостности (они, в основ-
5 Основная слабость здесь заключается в том, что ER-модель за исключением некоторых
специальных (но, надо полагать, очень важных) случаев совершенно непригодна для работы с
ограничениями целостности или бизнес-правилами. Процитируем типичное высказывание на
Глава 13. Семантическое моделирование
523
ном, относились к первичным и внешним ключам). Однако при более внимательном
чтении работы [13.5] можно предположить, что ER-модель действительно является
моделью данных, но такой, которая представляет собой лишь тонкий слой на вершине
базовой реляционной модели (и, конечно, не может заменить реляционную модель,
как хотелось бы некоторым авторам). Это утверждение можно обосновать приведен-
ными ниже доводами.
Фундаментальный элемент данных в ER-модели, т.е. ее фундаментальный фор-
мальный элемент, существующий в противоположность неформальным элементам
(“сущностям”, “связям” и т.д.), — это отношение степени п.
Операторы ER-модели, в основном, являются операторами реляционной алгебры.
(Действительно, работу [13.5] нельзя назвать очень ясной в этом отношении, но в
ней предлагается менее мощное по сравнению с реляционной алгеброй множество
операторов, среди которых, например, не существует объединения и явно задан-
ного соединения.)
Именно в вопросах целостности эти два подхода в некоторой степени отличаются
один от другого: ER-модель содержит набор встроенных правил целостности, со-
ответствующих некоторым (но не всем) описанным в этой книге правилам, необ-
ходимым для внешнего ключа. Таким образом, там, где для “чистой” реляционной
системы потребовалось бы явно сформулировать некоторые правила для внешних
ключей, для ER-модели достаточно было указать, что данная переменная-
отношение имеет некоторый тип, — и соответствующие правила для внешних
ключей были бы задействованы.
Сравнительный анализ сущностей и связей
В этой книге уже несколько раз отмечалось, что “связи” лучше всего рассматривать
просто как сущности определенного рода. И наоборот, обязательным условием исполь-
зования ER-модели является то, что эти два понятия должны каким-то образом разли-
чаться. По мнению автора, любой подход, при котором преследуется такое разделение,
обладает серьезными недостатками, поскольку, как отмечалось выше, в разделе 13.2,
один и тот же элемент может совершенно справедливо рассматриваться как сущность
одними пользователями и как связь— другими. В частности, рассмотрим следующий
пример с заключением брака.
С одной стороны, очевидно, что браком называется некоторая связь между двумя
людьми. В качестве примера можно привести запрос “С кем вступила в брак Эли-
забет Тейлор в 1975 году?”.
С другой стороны, не менее очевидно, что брак является сущностью определенно-
го типа. В качестве примера можно привести следующий запрос: “Сколько браков
было заключено в этой церкви с апреля?”.
этот счет из работы [13.27]: “Декларативные процессы очень сложны для того, чтобы их
можно было выразить в виде части бизнес-модели, а потому они должны быть определены
отдельно аналитиком/разработчиком". При этом все еще остается в силе аргумент, что
проектирование базы данных должно быть процессом точного определения приемлемых огра-
ничений (см. [8.18], [8.19], [13.17]-[13.19]).
524
Часть III. Проектирование базы данных
Если в методике проектирования базы данных между сущностями и связями
предполагается наличие определенных различий, то в лучшем случае эти две интер-
претации будут рассматриваться асимметрично (т.е. запросы для “сущностей” и за-
просы для “связей” будут выглядеть совершенно по-разному). В худшем случае одна
интерпретация вовсе не будет поддерживаться (т.е. один из классов запросов сфор-
мулировать будет невозможно).
В качестве еще одной иллюстрации рассмотрим следующее утверждение из учебного
пособия по ER-моделированию [13.17].
"Обычно в начале, в процессе разработки концептуальной схемы, некоторые
связи представляются в виде атрибутов [которые в данном случае означают
внешние ключи]. Затем эти атрибуты преобразуются в связи по мере дальней-
шей разработки проекта и углубления понимания его особенностей. ”
Но что произойдет, если атрибут станет внешним ключом позже, т.е. если база дан-
ных будет изменена уже после того, как она использовалась в течение некоторого време-
ни? Если эту идею логически развивать, то можно прийти к выводу, что макет базы дан-
ных должен содержать связи и совсем не содержать атрибутов. (На самом деле эта пози-
ция обладает некоторыми достоинствами; см. аннотацию к [13.18] в конце этой главы.)
Заключительные замечания
Помимо описанной в этой главе схемы ER-моделирования, существует много других
семантических схем моделирования. Однако большинство из них очень похожи одна на
другую; в частности, многие из них можно характеризовать просто как тот или иной ва-
риант графических обозначений для представления некоторых ограничений для внешних
ключей, плюс несколько иных дополнительных компонентов. Безусловно, подобные
графические компоненты могут быть полезны для представления “всей картины в це-
лом”, но они слишком просты, чтобы с их помощью можно было выполнить все необхо-
димые проектировочные работы6. В частности, как отмечалось выше, они обычно не
подходят для определения общих ограничений целостности. Например, как можно было
бы представить на ER-диаграмме наличие зависимости соединения?
13.7. Резюме
Эта глава начиналась с краткого введения в общие идеи семантического моделиро-
вания. В целом, данный процесс состоит из четырех перечисленных ниже этапов, пер-
вый из которых является неформальным, а остальные — формальными.
1. Идентифицировать полезные семантические концепции.
2. Определить формальные объекты.
3. Определить формальные правила поддержки целостности данных (“метаограничения”).
4. Определить формальные операторы.
6 Печально, но простые решения остаются очень популярными даже тогда, когда они чрез-
мерно просты. В таких случаях можно согласиться с Эйнштейном, который однажды заметил,
что "все вещи следует делать настолько простыми, насколько это возможно, но не проще".
Глава 13. Семантическое моделирование
525
В качестве примера полезных семантических концепций можно назвать концепции
сущности, свойства, связи и подтипа.
Замечание. Следует особо подчеркнуть, что между неформальным уровнем семанти-
ческого моделирования и базовым формальным системным уровнем весьма вероятно
появление терминологических конфликтов и что наличие подобных конфликтов часто
приводит к путанице.
Основная цель исследований в области семантического моделирования состоит в том,
чтобы сделать СУБД более “разумными”. А более конкретная цель заключается в пре-
доставлении некоторого систематического подхода к решению проблемы проектирова-
ния базы данных. В настоящей главе было описано применение одной из
“семантических” моделей, предложенной Ченом для решения указанной проблемы, а
именно — модель “сущность/связь”, иначе называемая ER-моделью.
В связи со сказанным выше стоит повторить мысль о том, что первая статья о ER-
моделировании [13.5] на самом деле содержала два различных, более или менее незави-
симых, предложения: саму ER-модель, а также технологию диаграммного ER-
моделирования. Как было отмечено в разделе 13.4, широкую популярность ER-модели,
скорее всего, можно объяснить именно наличием этой технологии использования диа-
грамм, а не какой-либо другой причиной. Однако для использования технологии ER-
диаграмм совсем не обязательно принимать все идеи этой модели. Данные диаграммы
можно применять в качестве основы в любой методике проектирования, например в ме-
тодике на основе RM/T-модели, описанной в [13.6]. Эта особенность часто упускается из
виду при сравнении удобства использования ER-модели и других методик, разработан-
ных для проектирования базы данных.
Сравним теперь идеи семантического моделирования (и ER-модель в частности) с
методом нормализации, описанным в главах И и 12. Метод нормализации предусматри-
вает приведение больших переменных-отношений к набору переменных-отношений
меньшего размера. При этом предполагается, что на исходном этапе имеется небольшое
количество больших переменных-отношений, которые после выполнения определенных
операций к завершающему этапу будут преобразованы в множество малых переменных-
отношений, т.е. произойдет отображение больших отношений в малые (это, конечно же,
очень приблизительная формулировка). Однако метод нормализации не содержит ника-
ких упоминаний о том, каким именно образом могут быть получены исходные большие
переменные-отношения. Нисходящие методики, подобные описанной в настоящей главе,
предназначены для решения именно этой проблемы, т.е. они позволяют отобразить неко-
торую предметную область реального мира на набор больших переменных-отношений.
Иначе говоря, эти два подхода дополняют друг друга. Таким образом, общая процедура
проектирования базы данных включает два следующих этапа.
1. Использование методов ER-моделирования (или другой аналогичной методики)
для создания “больших” переменных-отношений, представляющих сильные сущ-
ности, слабые сущности и т.д.
2. Использование идей дальнейшей нормализации для разбиения созданных
“больших” переменных-отношений на “малые”.
Однако из особенностей проведенного в данной главе обсуждения можно сделать вы-
вод, что в общем случае семантическое моделирование не является такой же строгой и
ясной дисциплиной, как методика дальнейшей нормализации, описанная в главах 11
526
Часть III Проектирование базы данных
и 12. Суть в том, что (как было указано в начале настоящей главы) проектирование базы
данных все еще является весьма субъективным занятием. Оно и не может быть объек-
тивным, поскольку существует сравнительно мало действительно строгих принципов,
которые могут использоваться для разрешения этой проблемы (немногие существующие
на сегодняшний день принципы, в основном, являются принципами нормализации). Из-
ложенные в настоящей главе идеи можно рассматривать как чисто эмпирические реко-
мендации, которые действительно могут быть весьма полезны на практике.
В заключение следует упомянуть еще один очень важный момент. Несмотря на заяв-
ление, что эта область исследований все еще остается очень субъективной, в ней есть од-
на особая часть, в которой идеи семантического моделирования в настоящее время могут
быть весьма уместны и полезны. Речь идет о словаре данных, который в определенном
смысле можно рассматривать как “базу данных разработчика для создаваемой им базы
данных”. В словаре данных разработчик может хранить сведения о решениях, принятых
в процессе проектирования базы данных [13.2]. Таким образом, изучение семантическо-
го моделирования может оказаться чрезвычайно полезным для проектирования системы
управления словарем данных. В нем могут быть указаны типы сущностей, которые сло-
варь должен поддерживать и понимать, например категории сущностей (такие, как силь-
ные и слабые сущности в ER-модели), правила целостности (такие, как полное или час-
тичное участие в связи ER-модели), супертипы и подтипы сущностей и т.д.
Упражнения
13.1. Что означает термин “семантическое моделирование”?
13.2. Перечислите четыре основных этапа разработки определения любой “расширенной”
модели, подобной технологии ER-моделирования.
13.3. Дайте определение следующим терминам ER-модели.
иерархия типов ключевое свойство связь сильная сущность
набор значений слабая сущность
наследование свойство супертип/подтип сущность
13.4. Приведите примеры связей следующих типов:
а) связь типа “многие ко многим”, в которой один из участников является слабой
сущностью;
б) связь типа “многие ко многим”, в которой один из участников является другой
связью;
в) связь типа “многие ко многим”, имеющая собственный подтип;
г) подтип, связанный со слабой сущностью, которая не зависит от его супертипа.
13.5. Нарисуйте ER-диаграмму для базы данных учебного процесса из упр. 8.10 главы 8.
13.6. Нарисуйте ER-диаграмму для базы данных, содержащей информацию о персонале
компании, из упр. 11.3 главы 11. Используйте ее для вывода соответствующего на-
бора базовых переменных-отношений.
Глава 13. Семантическое моделирование
527
13.7. Нарисуйте ER-диаграмму для базы данных системы учета заказов из упр. 11.4 гла-
вы 11. Используйте ее для вывода соответствующего набора базовых переменных-
отношений.
13.8. Нарисуйте ER-диаграмму для базы данных, содержащей информацию о продажах,
из упр. 12.3 главы 12. Используйте ее для вывода соответствующего набора базо-
вых переменных-отношений.
13.9. Нарисуйте ER-диаграмму для модифицированной базы данных о продажах из
упр. 12.5 главы 12. Используйте ее для вывода соответствующего набора базовых
переменных-отношений.
Список литературы
Обширность предлагаемого списка рекомендуемой литературы объясняется большим
количеством конкурирующих методик проектирования, существующих в настоящее
время в деловом и научном мире. Полное согласие в этой области еще не достигнуто,
поэтому несмотря на то, что рассмотренная в данной главе методика ER-моделирования
является наиболее распространенным подходом, не все специалисты с ней согласны.
Действительно, следует отметить, что самые распространенные подходы вовсе не обя-
зательно являются самыми лучшими. Также заметим, что многие коммерческие продук-
ты представляют собой нечто большее, чем просто инструменты разработки баз данных.
Часто наряду с предоставлением средств определения структуры базы данных (схемы)
они позволяют генерировать целые приложения: пользовательские формы, логику при-
ложений, триггерные процедуры и т.д.
В дополнение к предлагаемому списку литературы следует также упомянуть некото-
рые ссылки на отчет ISO о концептуальной схеме [2.3], книгу Кента [2.4] и книгу Росса о
бизнес-правилах [8.18], [8.19].
13.1. Abrial J.R. Data Semantics // J. W. Klimbie and K. L. Koffeman (eds.). Data Base
Management. — Amsterdam, Netherlands: North-Holland; New York, N.Y.: Elsevier
Science, 1974.
Одна из самых ранних публикаций в области семантического моделирования. Сле-
дующая цитата прекрасно передает общий дух изложения материала в этой статье:
“Совет читателю: если вы хотите найти в данной статье определение термина се-
мантика, прекратите чтение, поскольку такого определения здесь нет”.
13.2. Bernstein Р. A. The Repository: A Modem Vision // Database Programming and
Design. — December, 1996. —9, № 12.
Похоже, что во время написания этой статьи возникла тенденция к замене термина
словарь термином репозитарий. Репозитарием называется СУБД, предназначенная
для управления метаданными, причем не только для СУБД, но и для всех видов про-
граммных инструментов: “инструментов проектирования, разработки и распростра-
нения программного обеспечения, а также инструментов управления проектами в об-
ласти электроники, механики, разработки Web-сайтов и многих других типов офици-
альных документов, которые относятся к инженерно-конструкторской работе”. Эта
работа является вводным пособием для изучения концепций репозитария.
13.3. Blaha М., Premerlani W. Object-Oriented Modeling and Design for Database
Applications. — Upper Saddle River, N.J.: Prentice-Hall. — 1998.
528
Часть III. Проектирование базы данных
В этой книге подробно описывается методология проектирования Object
Modeling Technique (ОМТ). Ее можно рассматривать, как вариацию ER-
моделирования (объекты в ней соответствуют сущностям ER-модели), которая
представляет собой нечто большее, чем просто методику проектирования базы
данных. См. также [13.32].
13.4. Booch G. Object-Oriented Design with Applications. — Redwood City, Calif.:
Benjamin/Cummings. — 1991.
Cm. [13.32].
13.5. Chen P. P.-S. The Entity-Relationship Model — Toward a Unified View of Data // ACM
TODS.— 1976.— 1, № 1. (Переиздано: M. Stonebraker (ed.) Readings in Database
Systems. — San Mateo, Calif.: Morgan Kaufmann, March, 1988.)
В статье впервые представлены ER-модель и ER-диаграмма. Как уже говорилось в
настоящей главе, с тех пор данная модель претерпела значительные изменения, по-
скольку приведенные в этой первой статье объяснения и определения, конечно же,
были не очень строгими и точными, а потому нуждались в усовершенствовании.
(Одно из чаще всего высказываемых критических замечаний по отношению к ER-
моделированию состоит в том, что термины модели не имеют единого и четкого
определения, а интерпретируются различными способами. Конечно, вся область
изучения баз данных характеризуется наличием неточной и противоречивой тер-
минологии, однако в наибольшей степени это относится к рассматриваемой здесь
области.) Вот несколько примеров таких неточностей.
В разделе 13.3 отмечается, что сущность определяется как “предмет, который
может быть четко идентифицирован”, а связь— как “ассоциация сущностей”.
При этом сразу же возникает вопрос “А является ли связь сущностью?”. Ясно, что
связь является “предметом, который может быть четко идентифицирован”, одна-
ко из последующих разделов этой статьи следует, что термин “сущность” преду-
смотрен для чего-то определенно не являющегося “связью”. Если все же допус-
тить, что это так, то почему модель называется “модель «сущность/связь»”? В
статье все это определено не очень четко.
Сущности и связи могут иметь атрибуты (в этой главе мы использовали
термин “свойство”). В статье снова не дается четкого определения этому
термину, поскольку сначала атрибут определяется как свойство, которое не
является первичным ключом или его компонентом (в противоположность
реляционному определению), а затем он используется в стандартном реля-
ционном смысле.
Предполагается, что первичный ключ связи является комбинацией внешних
ключей, которые идентифицируют сущности, включенные в состав данной
связи (однако термин “внешний ключ” при этом не используется). Это допу-
щение верно только для связей типа “многие ко многими” и то не всегда. На-
пример, рассмотрим переменную-отношение SPD {S#, Р#, DATE, QTY}, со-
держащую сведения о поставках некоторых деталей некоторыми поставщи-
ками по некоторым датам. Предположим, что один и тот же поставщик может
поставлять одну и ту же деталь несколько раз, но только по разным датам.
Тогда первичным ключом (или, по крайней мере, единственным потенциаль-
Глава 13. Семантическое моделирование
529
ным ключом) этой переменной-отношения является комбинация атрибутов
{S#, Р#, DATE}, причем поставщики и детали могут быть описаны, как сущ-
ности, а для дат этого сделать нельзя.
13.6. Codd E.F. Extending the Database Relational Model to Capture More Meaning H ACM
TODS. — December, 1979. — 4, № 4.
В статье представлена “расширенная” версия реляционной модели— RM/T-
модель. Можно сразу же отметить несколько отличий между RM/Т- и ER-моделью.
Во-первых, в RM/T-модели не делается никаких различий между сущностями и
связями (связь рассматривается всего лишь как особый вид сущности). Во-вторых,
структурные и целостные аспекты RM/T-модели более обширны и определены бо-
лее четко, чем в ER-модели. В-третьих, RM/T-модель содержит несколько специ-
альных операторов в дополнение к операторам базовой реляционной модели (хотя
в этой области еще предстоит дополнительная работа).
Вкратце RM/T-модель функционирует следующим образом.
Во-первых, сущности (включая “связи”) представляются Е- и Р-отношениями1,
которые являются особыми видами отношений общего типа степени n. Е-
отношения используются для указания существования некоторых сущностей, а
Р-отношения — для указания некоторых свойств этих сущностей.
Во-вторых, среди сущностей могут быть заданы разные связи; например, типы
сущностей А и В могут образовывать ассоциацию (этот термин принят в RM/T-
модели для связи типа “многие ко многим”) или же тип сущности Y может быть
объявлен подтипом другого типа сущности X. RM/T-модель включает фор-
мальную структуру каталога, предназначенную для предоставления системе
сведений о существовании подобных связей. В результате система может при-
вести в действие различные ограничения целостности, которые подразумева-
ются наличием таких связей.
В-третьих, для манипулирования различными объектами RM/T-модели (Е- и
P-отношениями, каталогом отношений и т.д.) предусмотрены операторы вы-
сокого уровня.
В RM/T-модели имеются аналоги всех конструкций ER-модели (сущность, связь,
свойство, подтип), которые перечислены в табл. 13.1. Точнее, в ней поддерживает-
ся классификационная схема сущностей, которая во многих случаях представ-
ляет собой наиболее значительный или, по крайней мере, наиболее очевидный ас-
пект всей модели. В соответствии с этой схемой сущности разделяются на три ос-
новные категории: ядра, характеристики и ассоциации.
Ядра. Это сущности, характеризующиеся независимым существованием. Они
представляют те объекты, “для описания которых и создается база данных”.
Иначе говоря, ядрами называются сущности, которые не являются ни характе-
ристиками, ни ассоциациями (см. ниже).
Характеристики. Это сущности, предназначенные для описания или
“предоставления характеристики” некоторой другой сущности. Существование
характеристик зависит от существования описываемых ими сущностей. Опи-
сываемая сущность может быть ядром, характеристикой или ассоциацией. *
7 Или, скорее, Е- и Р-переменными-отношениями.
530
Часть III. Проектирование базы данных
Ассоциации. Это сущности, представляющие связь типа “многие ко многим”
(или “многие ко многим, ко многим” и т.д.) между двумя или более сущностя-
ми. Участвующие в ассоциации сущности могут представлять собой ядра, харак-
теристики или соединения.
Кроме того, необходимо отметить следующее.
Сущности (независимо от их классификации) могут также иметь свойства.
В частности, любая сущность (опять-таки, независимо от классификации) мо-
жет иметь свойство, предназначенное для указания на некоторую другую сущ-
ность. Такое указание представляет связь типа “многие к одному”, имеющуюся
между двумя сущностями.
Замечание. Такие указания не рассматривались в исходной статье [13.6], а были
предложены позже.
Поддерживаются супертипы и подтипы сущностей. Если сущность Y является
подтипом сущности X, то сущность Y является ядром, характеристикой или ас-
социацией в зависимости от того, чем является сущность X: ядром, характери-
стикой или ассоциацией.
Все перечисленные выше концепции можно следующим образом соотнести с их
аналогами в ER-модели (несколько неформально). Ядро соответствует сильной
сущности ER-модели, характеристика — слабой сущности, а ассоциация — связи
(только для типа “многие ко многим”).
Замечание. Иногда в литературе встречается термин первичный домен, который
также впервые был определен в этой статье. Первичным доменом называется до-
мен, на котором определен по крайней мере один первичный ключ, состоящий из
единственного (не составного) атрибута. Например, в примере базы данных по-
ставщиков и деталей первичными доменами будут S# и Р#.
Приведенные выше краткие сведения следует дополнить упоминанием о том, что в
модели RM/Т предусмотрена поддержка суррогатов (подробности приводятся в
[13.16]), временного измерения и различных типов обобщения данных (подробности
приводятся в [13.35], [13.36]).
13.7. Date C.J. A Note on One-to-One Relationships // Relational Database Writings: 1985—
1989. — Reading, Mass.: Addison-Wesley, 1990.
Это расширенное рассмотрение проблемы связей типа “один к одному”, которая
оказалась более сложной, чем может показаться на первый взгляд.
13.8. Date C.J. Entity/Relationship Modeling and the Relational Model // C. J. Date and
Hugh Darwen. Relational Database Writings: 1989-1991.— Reading, Mass.:
Addison-Wesley, 1992.
13.9. Date C.J. Don't Encode Information into Primary Keys! // C.J. Date and Hugh Darwen.
Relational Database Writings: 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
Здесь представлены неформальные аргументы против того, что иногда называют
“разумными ключами”. К тому же следует упомянуть работу [13.10], в которой
приведены рекомендации относительно внешних ключей.
13.10. Date C.J. Composite Keys // С. J. Date and Hugh Darwen. Relational Database Writings
1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
Глава 13. Семантическое моделирование
531
Цитата из аннотации к этой работе: “Собраны и проанализированы аргументы за и
против включения составных [ключей] в макет реляционной базы данных... пред-
ложены рекомендации”. В частности, в статье показано, что суррогатные ключи
[13.16] не всегда рекомендуется использовать.
13.11. Date C.J. A Database Design Dilemma? И На Web-сайте DBP&D ww.dpbd.com
(January, 1999) (см. также приложение В в [3.3]).
На первый взгляд, заданный тип сущности (например, “работник”) может быть
представлен в реляционной системе либо с помощью типа EMPLOYEE (т.е. домена),
либо с помощью переменной-отношения EMPLOYEE. В этой короткой статье даются
рекомендации по выбору одного из двух вариантов.
13.12. Date C.J. Subtables and Supertables (в двух частях) // На Web-сайте DBP&D
ww.dpbd.com (появится в конце 2000 или в начале 2001 года) (см. также приложе-
ние D в [3.3]).
Часто считается, что наследование типов сущностей в реляционном контексте мо-
жет быть организовано с помощью “подтаблиц” и “супертаблиц”, где сущность-
подтип отображается в подтаблицу, а сущность-супертип — в супертаблицу. В ча-
стности, во время создания этой книги именно такой подход поддерживался в
SQL3 (см. приложение Б) и в некоторых существующих продуктах. В данной ста-
тье содержится острая критика этой идеи.
13.13. Elmasri R., Navathe S.B. Fundamentals of Database Systems (2nd edition). — Redwood
City, Calif.: Benjamin/Cummings, 1994.
В этом учебном пособии по проектированию баз данных две главы из 25 имею-
щихся посвящены ER-методам проектирования баз данных.
13.14. Embley D.W. Object Database Development: Concepts and Principles. — Reading,
Mass.: Addison-Wesley, 1998.
Представлена методика проектирования на основе OSM-модели (Object-oriented
Systems Model). Некоторые элементы OSM-модели похожи на ORM-модель
[13.17]—[13.19].
13.15. Fleming С.С., Von Halle В. Handbook of Relational Database Design. — Reading,
Mass.: Addison-Wesley, 1989.
Прекрасное практическое пособие по проектированию баз данных в реляционных
системах с конкретными примерами реализации в среде СУБД DB2 компании IBM
и DBC/1012 компании Teradata (теперь NCR). Описаны этапы как логического, так
и физического проектирования, хотя в книге термин “логическое проектирование”
используется для описания того, что мы называем реляционным проектированием,
а термин “реляционное проектирование” включает по крайней мере несколько ас-
пектов того, что мы называем физическим проектированием!
13.16. Hall Р., Owlett J., Todd S.J.P. Relations and Entities // G. M. Nijssen (ed.). Modelling in
Data Base Management Systems. — Amsterdam, Netherlands: North-Holland; New
York, N.Y.: Elsevier Science, 1975.
Это первая статья, в которой подробно рассмотрена идея суррогатных ключей
(позднее они были введены в состав модели RM/Т). Суррогатным называется ключ
в обычном реляционном смысле, но дополнительно обладающий перечисленными
ниже специфическими свойствами.
532
Часть III. Проектирование базы данных
Всегда состоит только из одного атрибута.
Значениями этого атрибута являются только суррогаты (отсюда и их название),
выбранные для ссылки на сущности, которые они обозначают. Иначе говоря,
эти значения служат лишь для представления того факта, что соответствующие
сущности существуют, не несут никакой другой информации и никакой другой
смысловой нагрузки.
При вставке в базу данных новой сущности присваивается значение суррогат-
ного ключа, которое никогда прежде не использовалось и никогда не будет ис-
пользоваться, даже если данная сущность впоследствии будет удалена.
В идеале, значения суррогатного ключа должны генерироваться системой, но сам
способ их генерации (системный или пользовательский) не имеет никакого отно-
шения к основной идее суррогатных ключей.
Здесь, вероятно, стоит заметить, что суррогаты не являются (как полагают некоторые
авторы) тем же, что и “идентификаторы кортежей”, потому что последние идентифи-
цируют кортежи, а суррогаты идентифицируют сущности, между тем как никакой
прямой связи типа “один к одному” между кортежами и сущностями не существует
(в частности, вспомните об идентификаторах производных кортежей). Более того,
идентификаторы кортежей обладают дополнительными преимуществами в отноше-
нии производительности, чего не скажешь о суррогатах, поскольку доступ к кортежу
через идентификатор кортежа происходит очень быстро (предполагается, что корте-
жи базового отношения отображаются непосредственно на физическую структуру
хранения, что в действительности имеет место во многих современных программных
продуктах). Кроме того, идентификаторы кортежа обычно скрыты от пользователя,
тогда как суррогаты чаще всего — нет (по принципу информаций), т.е. идентифика-
тор кортежа нельзя сохранить, как значение атрибута, а суррогат можно.
Короче говоря, суррогаты являются логической концепцией, а идентификаторы
кортежей — физической.
13.17. Halpin Т. Conceptual Schema and Relational Database Design (2nd edition). — Sydney,
Australia: Prentice-Hall of Australia Pty., Ltd. 1995.
Подробное описание ORM-модели (см. аннотации к двум следующим работам).
13.18. Halpin Т. Business Roles and Object-Role Modeling // DBP&D, № 10, October, 1996.
Великолепное введение в объектно-ролевое моделирование (object-role
modeling— ORM) [13.17]. Автор начинает с наблюдения, что “[в отличие от] ER-
модели, для которой существуют десятки разных диалектов, ORM-модель имеет
лишь несколько диалектов с незначительными различиями”. (Замечание. Один из
таких диалектов называется NIAM-моделью [13.29].) ORM-моделирование также
называется моделированием на основе фактов, потому что проектировщик начи-
нает процесс моделирования с записи (на естественном языке или с помощью спе-
циальных графических обозначений) ряда элементарных фактов (или, точнее, ти-
пов фактов), которые в совокупности характеризуют все особенности моделируе-
мой организации. Ниже приводятся некоторые примеры таких типов фактов.
Каждый работник имеет одно имя.
Каждый работник отчитывается о своей деятельности перед по крайней мере
одним другим работником.
Глава 13. Семантическое моделирование
533
Если работник el отчитывается перед работником е2, то обратное (т.е. работ-
ник е2 отчитывается перед работником el) невозможно.
Ни один работник не может руководить одним и тем же проектом и оценивать
результаты его выполнения.
Как видите, типы фактов на самом деле представляют собой предикаты или
бизнес-правила. Как следует из названия этой статьи, подход к проектированию
базы данных в ORM-модели очень близок к тем методам, которые предпочитают
сторонники использования “бизнес-правил” [8.18], [9.19] и сам автор. В общем
случае факты представляют собой роли, выполняемые объектами в отношениях
между собой (отсюда и название “объектно-ролевое моделирование”). Обратите
внимание, что “объекты” в действительности представляют сущности, а не объ-
екты в конкретном смысле этого термина, описанном в части VI этой книги, а
связи между ними вовсе не обязательно являются бинарными. Однако факты
действительно являются элементарными, т.е. они не могут быть декомпозирова-
ны на меньшие факты.
Замечание. Основная идея о том, что база данных на концептуальном уровне
должна содержать только элементарные (или неприводимые) факты, принадлежит
Холлу (Holl), Оулетту (Owlett) и Тодду (Todd) [13.16].
Обратите внимание, что в ORM-модели нет понятия “атрибут”. В результате, как по-
казано в этой статье, ORM-проекты концептуально проще и устойчивее, чем их ана-
логи, выполненные в RM-модели (в этой связи см. также [13.19]). Однако атрибуты
могут появляться и действительно появляются при автоматической генерации на ос-
нове ORM-макета соответствующего SQL-описания проекта или его RM-макета.
В ORM-модели также особо подчеркивается использование “фактов-образцов”
(т.е. экземпляров фактов-образцов, которые иначе можно было бы назвать пред-
ложениями) в качестве способа проверки корректности проекта со стороны конеч-
ного пользователя. Как утверждается в данной статье, такой подход достаточно
просто реализовать при моделировании на основе фактов, но гораздо труднее реа-
лизовать при работе с ER-моделью.
Конечно, существует много логически эквивалентных способов описания данного
предприятия и соответственно много логически эквивалентных ORM-схем. По
этой причине ORM-моделирование включает набор правил преобразования, позво-
ляющих выполнять преобразования с получением логически эквивалентных схем.
Поэтому ORM-инструменты позволяют выполнять некоторую оптимизацию про-
ектов в соответствии с требованиями разработчика. Как уже говорилось выше, с их
помощью можно также генерировать SQL-описание проекта или его RM-модель,
опираясь на созданную ORM-модель, либо выполнять обратную процедуру вос-
становления ORM-модели из SQL-описания проекта или его RM-модели. В зави-
симости от используемой СУБД созданное SQL-описание проекта может включать
объявление ограничений целостности (в стиле SQL/92) или предусматривать их
поддержку с помощью хранимых процедур или триггеров. В отношении ограниче-
ний отметим, что в отличие от ER-модели ORM-модель по определению содержит
“развитый язык для формулирования ограничений”. (Однако в [13.19] автор при-
знает, что не все бизнес-правила можно выразить с помощью принятых в ORM-
модели графических обозначений. Для некоторых из них все же придется исполь-
зовать текстовые формулировки.)
534
Часть III. Проектирование базы данных
Наконец, ORM-модель, безусловно, может рассматриваться как высокоуровневое
абстрактное представление базы данных (на самом деле следовало бы возразить,
что оно, скорее, ближе к чистому, возможно, даже в некоторой степени строгому,
реляционному представлению). Благодаря этому появляется возможность задавать
запросы непосредственно ей самой [13.19].
13.19. Halpin Т. Conceptual Queries // Data Base Newsletter, 26 № 3, March-April, 1998.
Цитата из аннотации к этой работе: “Формулировка нетривиальных запросов с по-
мощью таких реляционных языков программирования, как SQL и QBE, может ока-
заться очень сложной задачей для конечных пользователей. Язык ConQuer являет-
ся новым концептуальным языком создания запросов, который основан на объект-
но-ролевом моделировании и предоставляет простой и понятный пользователям
способ формулирования запросов... В этой статье описаны преимущества [такого
языка] по сравнению с традиционными языками запросов в отношении формули-
рования запросов и бизнес-правил”.
Помимо всего прочего, в статье обсуждается приведенный ниже запрос на языке
ConQuer, смысл которого состоит в следующем: “Извлечь данные о работниках,
которые водят машину, и об отделах, в которых они работают”.
^Работник
+-водит Машину
+-работает в ^Отделе
Если сотрудник в общем случае умеет управлять произвольным количеством ма-
шин, а работать может только.₽ одном отделе, то базовая SQL-схема может состо-
ять из двух таблиц, а соответствующий SQL-запрос иметь следующий вид.
SELECT DISTINCT XI.ЕМР#, XI.BRANCH#
FROM EMPLOYEE AS XI, DRIVES AS X2
WHERE XI.EMP# = X2.EMP# ;
Теперь предположим, что служащий может работать одновременно в нескольких
отделах. Тогда базовая SQL-схема должна включать не две, а три таблицы, а соот-
ветствующий SQL-запрос будет иметь следующий вид.
SELECT DISTINCT Х1.ЕМР#, ХЗ.BRANCH#
FROM EMPLOYEE AS XI, DRIVES AS X2, WORKS_FOR AS X3
WHERE XI.EMP# = X2.EMP# AND XI.EMP# = X3.EMP#;
Однако в запрос на языке ConQuer никаких изменений вносить не потребуется.
Как видно из предыдущего примера, язык ConQuer может рассматриваться, как
весьма строгий вариант реализации логической независимости от данных. Для
объяснения этого замечания придется несколько уточнить архитектуру
ANSI/SPARC [2.1], [2.2]. Как говорилось в главе 2, логическая независимость от
данных означает независимость от изменений концептуальной схемы, но дело в
том, что в предыдущем примере не было сделано никаких изменений концептуаль-
ной схемы! Причина в том, что современные SQL-продукты поддерживают работу
с концептуальной схемой не совсем должным образом. Вместо этого они, скорее
всего, поддерживают работу с SQL-схемой. При этом SQL-схема может рассмат-
риваться как некий промежуточный уровень между истинным концептуальным
Глава 13. Семантическое моделирование
535
уровнем и внутренним или физическим уровнем. Если ORM-инструмент позволяет
определить истинную концептуальную схему и отобразить ее на SQL-схему, то
язык ConQuer может обеспечить требуемую независимость от изменений в SQL-
схеме (конечно, при соответствующих изменениях этого отображения).
Из статьи не совсем ясно, чем ограничивается выразительная мощь языка
ConQuer. Автор статьи не дает прямого ответа на поставленный вопрос, но от-
мечает, что “этот язык позволяет идеально формулировать любые вопросы, ко-
торые имеют какое-то отношение к данному приложению; причем иногда на
практике достаточно и меньше того, что он предоставляет”. К тому же автор за-
являет, что “наиболее мощной функциональной возможностью языка ConQuer...
является его способность выполнять корреляции с произвольным уровнем слож-
ности”, и приводит следующий пример.
*^Работник1
+-живет в Городе1
+-родился в Стране1
+-руководит работой Работника2, который
+-живет в Городе1
+-родился в Стране2 <> Стране1
Этот запрос означает: “Извлечь данные о сотрудниках, руководящих работой дру-
гих сотрудников, которые живут в том же городе, что и их руководитель, но роди-
лись в другой стране”. Автор предлагает попробовать сформулировать этот запрос
на языке SQL!
Наконец, в отношении языка ConQuer и бизнес-правил автор говорит: “Хотя графи-
ческие обозначения ORM-модели могут выразить больше бизнес-правил, чем [ER-
модель], их все еще приходится дополнять текстовым описанием [для выражения не-
которых ограничений]. В настоящее время продолжаются исследования, проводимые
в направлении адаптации языка ConQuer для достижения указанной цели”.
13.20. Hammer М.М., McLeod D. J. The Semantic Data Model: A Modelling Mechanism for
Database Applications // Proc. 1978 ACM SIGMOD Intern. Conf, on Management of
Data. — Austin, Texas. — May-June, 1978.
Семантическая модель данных (Semantic Data Model — SDM) представляет собой
другой формальный подход к проектированию базы данных. Как и в случае ER-
моделирования, в этой модели основное внимание уделяется структурным аспек-
там и аспектам целостности и совсем немного внимания (или вообще никакого) —
аспектам манипулирования данными (операторам). Об этом также можно прочесть
в [13.21], [13.24].
13.21. Hammer М., McLeod D. Database Description with SDM: A Semantic Database Model
// ACM TODS. — September, 1981. — 6, № 3.
См. комментарий к [13.20].
13.22. Hull R., King R. Semantic Database Modeling: Survey, Applications, and Research
Issues // ACM Comp. Surv. — September, 1987. — 19, № 3.
Исчерпывающее учебное пособие по семантическому моделированию. Эта статья
является прекрасной отправной точкой для изучения семантического моделирова-
ния и связанных с ним проблем и тем.
536
Часть III. Проектирование базы данных
13.23. Jacobson I. et al. Object-Oriented Software Engineering (revised printing). — Reading.
Mass.: Addison-Wesley, 1994.
В этой работе описывается метод проектирования Object-Oriented Software
Engineering (OOSE). Так же, как и при использовании ОМТ-модели [13.3], компо-
ненты OOSE (по крайней мере, имеющие отношение к базам данных) могут рас-
сматриваться как вариация ER-модели (как и в случае с ОМТ-моделью, OOSE-
объекты соответствуют ER-сущностям). Приведем следующую цитату:
“Большинство используемых сегодня методов разработки как информационных,
так и технических систем основано на функциональной декомпозиции этой систе-
мы и/или декомпозиции на основе используемых данных. Такие подходы сильно
отличаются от объектно-ориентированных методов, в которых данные и функции
тесно связаны”. Похоже, что здесь автор указывает на существенное отличие меж-
ду объектным подходом и подходом на основе использования базы данных. Пред-
полагается, что базы данных, по крайней мере совместно используемые базы дан-
ных общего назначения, которым уделяется больше всего внимания со стороны
специалистов в области баз данных, отделены от “функций”, т.е. предполагается,
что базы данных проектируются независимо от приложений, в которых они будут
использоваться. Тем не менее мы считаем, что специалисты в области объектно-
ориентированного подхода употребляют термин “база данных” в непосредствен-
ной связи с конкретным приложением, а не как совместно используемую базу
данных общего назначения.
См. также аннотацию к [13.32] и обсуждение объектных баз данных в главе 24.
13.24. Jagannathan D. et al. SIM: A Database System Based on the Semantic Data Model // Proc.
1988 ACM SIGMOD Intern. Conf, on Management of Data. — Chicago, Ill., June, 1988.
Описание коммерческой СУБД, которая построена на основе семантической моде-
ли данных, предложенной Хаммером и Мак-Леодом в [13.20].
13.25. Keuffel W. Battle of the Modeling Techniques: A Look at the Three Most Popular Modeling
Notations for Distilling the Essence of Data // DBMS. — August, 1996. — 9, № 9.
“Тремя наиболее популярными системами обозначения являются” ER-модель,
NIAM-метод [13.29] и SOM-метод. Автор утверждает, что ER-модель является
“дедушкой” двух других моделей, но одновременно подвергает ее критике в связи
с отсутствием необходимого формального обоснования. Например, сущности, свя-
зи и атрибуты (т.е. свойства) “описываются без упоминания о том, как они были
открыты”. NIAM-метод является гораздо более строгим. Если строго следовать
правилам этой модели, можно получить концептуальный макет, который “обладает
гораздо большей целостностью”, чем макеты, полученные на основе других моде-
лей, хотя “некоторые разработчики могут посчитать строгость NIAM-модели
чрезмерно ограничивающей” (!). SOM-модель “напоминает ER-модель... из-за
[аналогичной] нестрогой формулировки определений сущностей, атрибутов и свя-
зей”. Но она отличается от ER-модели тем, что в ней поддерживаются групповые
атрибуты (т.е. на самом деле повторяющиеся группы), позволяющие одному
“объекту” (т.е. сущности) содержать другие. (В ER-модели сущность может со-
держать повторяющиеся группы атрибутов, но не других сущностей.)
13.26. Mannila Н., Raiha K..-J. The Design of Relational Databases. — Wokingham, UK:
Addison-Wesley, 1992.
Глава 13. Семантическое моделирование
537
Согласно предисловию эта книга является “учебным пособием для студентов и
библиографическим справочником по вопросам проектирования реляционных баз
данных”. В ней, с одной стороны, описаны теория зависимостей и процедура нор-
мализации, а с другой — ER-модель, причем в каждом случае изложение ведется с
формальной точки зрения. Ниже перечислены названия глав из этой книги, кото-
рые могут дать представление о ее содержании.
Принципы проектирования
Ограничения целостности и зависимости
Свойства реляционных схем
Аксиоматизация зависимостей
Алгоритмы для задач проектирования
Отображения между ER-диаграммами и схемами реляционных баз данных
Преобразования схем
Примеры проектирования баз данных
Описанные в книге технологии были воплощены ее авторами в виде коммерчески рас-
пространяемого инструмента проектирования Design By Example (макет по образцу).
13.27. Moriarty Т. Enterprise View (regular column) // DBP&D. — August, 1997. — 10, № 8.
В этой работе описан коммерческий инструмент проектирования и разработки
приложений Usoft (www.usoft.com), который позволяет определять бизнес-правила
с помощью SQL-подобного синтаксиса, а затем использовать их для генерации
приложения (включая создание определения базы данных).
13.28. Nijssen G.M., Duke D.J., Twine S.M. The Entity-Relationship Data Model Considered
Harmful // Proc. 6th Symposium on Empirical Foundations of Information and Software
Sciences. — Atlanta, Ga., 1988.
“Может ли использование ER-модели привести к пагубным последствиям?” Мы
можем дать несколько подтверждений положительного ответа на этот вопрос,
включая следующие.
Путаница между типами и переменными-отношениями (см. обсуждение в раз-
деле 25.2 в главе 25)
Странная ситуация с подтаблицами и супертаблицами [13.12]
Широкое расхождение с принципом относительности базы данных (см. главу 9)
Путаница между сущностями и связями, обсуждавшаяся выше в этой главе
В данной работе этот перечень недостатков ER-модели был расширен.
Модель предлагает несколько перекрывающихся способов представления
структур данных, что чрезмерно усложняет процесс проектирования.
Нет никаких критериев выбора одного из нескольких альтернативных пред-
ставлений, что на практике может иметь весьма нежелательное следствие: не-
обходимость внесения изменений в уже завершенный проект при изменении
определенных обстоятельств.
Имеется слишком мало способов представления требований поддержки цело-
стности данных, что делает неосуществимыми некоторые аспекты процесса
проектирования (“[действительно] ограничения могут быть формально выра-
538
Часть III. Проектирование базы данных
жены с помощью более общих схем, например таких, как логика предикатов.
[Однако] полагать, что это есть обоснованный предлог для исключения
[ограничений] из модели данных, — все равно что полагать, что некий язык
программирования очень хорош, [даже несмотря на то, что] для реализации
всех тех функций, которые нельзя прямо выразить с помощью данного языка,
придется вызывать подпрограммы, написанные на языке ассемблера!”).
Вопреки популярному мнению ER-модель не является хорошим средством об-
щения конечных пользователей и профессионалов в области баз данных.
ER-модель нарушает принцип концептуализации: “Концептуальная схема
должна... включать [только] концептуально приемлемые аспекты предметной
области, как статические, так и динамические, и, следовательно, исключать все
аспекты (внешнего и внутреннего) представления данных, физической органи-
зации данных и доступа к ним, [а также] все аспекты частного представления
внешнего пользователя, например форматы сообщений, структуры данных и
т.д.” [2.3]. Действительно, авторы этой работы считают, что ER-модель “по су-
ти представляет собой реинкарнацию” старой сетевой модели CODASYL (см.
главу 1). “Можно ли считать основной причиной широкого распространения
ER-модели в сообществе специалистов в области [баз данных] то, что в ней
особое внимание уделяется структурам реализации?”
В этой статье также указаны многочисленные более мелкие недостатки ER-
модели. Затем в качестве возможного перспективного варианта в ней предлага-
ется альтернативная методология NIAM [13.29]. В частности, в статье подчерки-
вается, что в NIAM нет излишнего разделения на атрибуты и связи, которое име-
ется в ER-модели.
13.2 9.О11е T.W., Sol H.G., Verrijn-Stuart А.А. (eds.). Information Systems Design
Methodologies: A Comparative Review. — Amsterdam, Netherlands: North-Holland;
New York, N.Y.: Elsevier Science, 1982.
Доклады конференции IFIP Working Group 8.1, в которых описаны 13 различных
методик и результаты их применения для решения стандартной тестовой задачи.
Среди прочих рассматривается и методика NIAM [13.28]. Эта работа, вероятно,
была одной из первых работ по методике NIAM. В книгу также включены обзоры
некоторых предложенных подходов, включая NIAM.
13.30. Papazoglou М.Р. Unraveling the Semantics of Conceptual Schemas // CACM. —
September, 1995. — 38, № 9.
В этой работе предлагается подход на основе того, что можно назвать запросами к
метаданным, т.е. на основе запросов, которые обращены к смыслу (а не к значе-
ниям) данных, или, иначе говоря, запросов к самой концептуальной схеме. Приме-
ром такого запроса является простой запрос “Что такое постоянный работник?”.
13.31. Peckham J., Maryanski F. Semantic Data Models // ACM Comp. Surv. — 1988. — 20, № 3.
Еще один вводный обзор (см. [13.22]).
13.32. Reed Р. Unified Modeling Language Takes Shape // DBMS. — July, 1998. — 11, № 8.
Универсальный язык моделирования UML (Unified Modeling Language) пред-
ставляет собой еще одну графическую систему обозначений, предназначенную
для проектирования и разработки приложений (иначе говоря, она позволяет
Глава 13. Семантическое моделирование
539
разрабатывать приложения с помощью рисунков). Она также может использо-
ваться для разработки SQL-схем.
Замечание. Вполне вероятно, что вскоре язык UML приобретет большое коммер-
ческое значение, прежде всего из-за того, что он был принят в качестве стандарта
группой OMG (Object Management Group), поскольку имеет очень сильную объ-
ектную основу. Этот язык уже поддерживается многими коммерческими про-
граммными продуктами.
В нем предусмотрено моделирование данных и процессов (чего нет в ER-модели),
однако ограничениям целостности не уделяется достаточного внимания. (В разделе
этой работы “От моделей к коду, бизнес-правила” термин декларативный вообще
не упоминается! Основное внимание, скорее, сконцентрировано на генерации про-
цедурного кода приложения для реализации “процессов”. Вот цитата из этой рабо-
ты: “UML формализует то, что уже давно знали практики: объекты реального мира
лучше всего моделировать с помощью самодостаточных сущностей, которые со-
держат данные и функции”. И далее: “С исторической точки зрения очевидно, что
формальное разделение данных и функций привело к тому, что усилия по созда-
нию программного обеспечения имели преходящую ценность”. Эти замечания мо-
гут быть верны в отношении приложения, но совсем не очевидно, что это верно в
отношении баз данных [24.29].)
Язык UML появился на основе ранней работы Буча Booch method [13.4], работы
Румбау об ОМТ-модели [13.3] и работы Якобсона об OOSE-методе [13.23]. Буч,
Румбау и Якобсон недавно выпустили несколько книг о языке UML, которые, не-
сомненно, следует включить в список рекомендуемой литературы: The Unified
Modeling Language User Guide, The Unified Modeling Language Reference Manual и
The Unified Software Development Process (опубликованы издательством Addison-
Wesley в 1999 году).
(К. Ларман. Применение UML и шаблонов проектирования. — М.: Издательский
дом “Вильямс”, 2001.)
13.33. Schmid Н. A., Swenson J. R. On the Semantics of the Relational Data Base Model // Proc.
1975 ACM SIGMOD Intern. Conf, on Management of Data. — San Jose, Calif, May, 1975.
В этой работе представлена “базовая семантическая модель”, которая предшест-
вовала работе Чена с описанием ER-модели [13.5], но была во многом подобна
этой модели (конечно, за исключением используемой терминологии, поскольку
Шмид и Свенсон использовали термины независимый объект, зависимый объ-
ект и ассоциация вместо терминов Чена сильная сущность, слабая сущность и
связь соответственно).
13.34. Sowa J.F. Conceptual Structures: Information Processing in Mind and Machine.—
Reading, Mass.: Addison-Wesley, 1984.
Эта книга посвящена не самим системам баз данных, а скорее общей проблеме
представления и обработки знаний. Однако некоторые ее части непосредственно
относятся к теме настоящей главы. (Последующие замечания основаны на докладе
автора, сделанном им в 1990 году по поводу применения “концептуальных струк-
тур” для семантического моделирования.) Основная проблема использования ER-
диаграмм (и связанных с ней формальных методов) заключается в том, что они
менее строги, чем формальная логика. В результате они не могут справиться с не-
540
Часть III. Проектирование базы данных
которыми важными аспектами проектирования (например, не допускают исполь-
зования кванторов, входящих в состав большинства ограничений целостности), с
которыми может справиться формальная логика. (Кванторы были изобретены
Фреже в 1879 году, что позволяет утверждать, что ER-диаграммы представляют
“тип логики по состоянию до 1879 года”!) Но формальная логика гораздо сложнее
воспринимается при чтении. Как говорит автор, “исчисление предикатов является
языком ассемблера для представления знаний”. Концептуальные графы — это дос-
таточно читабельные и строгие графические обозначения, представляющие всю
логику в целом. Следовательно (согласно утверждениям автора), они гораздо
больше подходят для семантического моделирования, чем ER-диаграммы и им по-
добные модели.
13.35. Smith J.M., Smith D.C.P. Database Abstractions: Aggregation // CACM. — June,
1977.—20, №6.
См. аннотацию к [13.36].
13.36. Smith J.M., Smith D.C.P. Database Abstractions: Aggregation and Generalization //
ACM TODS. — June, 1977. — 2, № 2.
Идеи, высказанные в [13.35], [13.36], оказали значительное влияние на формули-
ровку положений RM/T-модели [13.6], особенно в области определения подти-
пов и супертипов.
13.37. Storey V.C. Understanding Semantic Relationships П The VLDB Journal. — October,
1993. —2, №4.
В аннотации к настоящей статье говорится, что семантические модели данных бы-
ли разработаны сообществом исследователей баз данных с использованием таких
абстракций, как подтип, обобщение и ассоциация. Помимо этих хорошо известных
понятий, дополнительные семантические понятия были введены исследователями
в таких дисциплинах, как лингвистика, логика и когнитивная психология. В статье
исследуются некоторые из этих дополнительных понятий и обсуждается их влия-
ние на проектирование баз данных.
13.38. Sundgren В. The Infological Approach to Data Bases // J. W. Klimbie and
K. L. Koffeman (eds.). Data Base Management. — Amsterdam, Netherlands:
North-Holland; New York, N.Y.: Elsevier Science, 1974.
Информационно-логическим (infological) называется один из подходов семантиче-
ского моделирования, который долгие годы успешно использовался в Скандинавии.
13.39. Tasker D. Fourth Generation Data: A Guide to Data Analysis for New and Old
Systems. — Sydney, Australia: Prentice-Hall of Australia Pty., Ltd., 1989.
Прекрасное практическое пособие по проектированию баз данных, в котором вни-
мание уделяется, главным образом, индивидуальным элементам данных (т.е. доме-
нам). Элементы данных разделены на три основных типа: именные, количествен-
ные и описательные. Именные элементы определяют сущности и в реляционном
смысле относятся к первичным и внешним ключам. Количественные элементы
представляют собой меру или расположение согласно какой-то шкале (возможно,
по шкале “дата/время”) и могут подвергаться обычным арифметическим манипу-
ляциям. Все остальные элементы данных относятся к описательным. (Конечно, это
краткое описание не может дать полного представления обо всей классификацион-
ной схеме.) В книге подробно обсуждается каждый из перечисленных типов эле-
Глава 13. Семантическое моделирование
541
ментов данных. Эти описания не всегда можно назвать “реляционно чистыми”, по-
скольку, например, использованное автором понятие “домена” не вполне отвечает
реляционному смыслу этого термина. Однако в книге содержится достаточно ма-
териала, имеющего большое практическое значение.
13.40. Teorey T.J., Fry J.P. Design of Database Structures. — Englewood Cliffs, N.J.:
Prentice-Hall, 1982.
Это учебник по всем вопросам проектирования баз данных, который разделен на
пять частей: введение, концептуальное проектирование, практическое проектиро-
вание (т.е. преобразование концептуального проектирования в конструкции, кото-
рые можно применить для конкретной СУБД), физическое проектирование и во-
просы специализированного проектирования.
(Тиори Т., Фрай Дж. Проектирование структур баз данных: в 2 книгах: Пер. с англ.
— М.: Мир, 1985.)
13.41. Teorey T.J., Yang D., Fry J.P. A Logical Design Methodology for Relational Databases Using
the Extended Entity-Relationship Model // ACM Comp. Surv. — June, 1986. — 18, № 2.
В представленную в этой работе “расширенную ER-модель” добавлена поддержка
иерархий типов сущностей, неопределенных значений (глава 18) и связей, вклю-
чающих больше двух участников.
13.42. Teorey T.J. Database Modeling and Design: The Entity-Relationship Approach. — San
Mateo, Calif.: Morgan Kaufmann, 1998.
Более современный учебник с описанием применения концепций ER-модели и
“расширенной” ER-модели [13.41] для проектирования базы данных.
542
Часть III. Проектирование базы данных
Часть IV
Управление
транзакциями
Эта часть книги состоит из двух глав, которые посвящены тесно связанным темам:
восстановлению и параллельности. Обе они являются аспектами более общей темы
управления транзакциями, но по методическим соображениям их желательно рассматри-
вать по отдельности.
Восстановление и параллельность, или, точнее, управление восстановлением и па-
раллельностью, связаны с общим понятием защиты данных, т.е. предохранения дан-
ных от утраты или повреждения. В частности, риск потери данных существует по сле-
дующим причинам.
Система может быть повреждена во время выполнения некоторых программ, в ре-
зультате чего база данных может оказаться в совершенно непредсказуемом со-
стоянии.
При одновременном (“параллельном”) выполнении между двумя программами
возможен конфликт из-за обращения к одним и тем же данным, что приведет к
получению неправильных результатов как внутри базы данных, так и вне ее.
В главе 14 рассматривается восстановление, а в главе 15 — параллельность.
Замечание. Некоторые разделы этих глав уже были опубликованы в несколько другой
форме в книге An Introduction to Database Systems: Volume II (Addison-Wesley, 1983).
543
Глава 14
Восстановление
14.1. Введение
Как уже говорилось во введении к настоящей части, эта и следующая главы посвящены
восстановлению и параллельности. Данные понятия очень тесно связаны и составляют части
более общей темы управления транзакциями. Однако в целях упрощения представления ма-
териала желательно рассматривать их по отдельности (по крайней мере до тех пор, пока не
будет закончено описание основных концепций). В настоящей главе основное внимание уде-
ляется восстановлению, а параллельность будет рассмотрена в главе 15, хотя время от време-
ни здесь неизбежно будут встречаться ссылки на вопросы, относящиеся к параллельности.
Восстановление в системе баз данных означает, в первую очередь, восстановление
самой базы данных, т.е. возвращение базы данных в определенное состояние, которое
считается корректным (или, точнее говоря, непротиворечивым1), если в результате како-
го-либо сбоя текущее состояние стало противоречивым или по крайней мере подозри-
тельным. Основной принцип, на котором строится подобное восстановление, достаточно
прост и может быть выражен одним словом — избыточность. (Эта избыточность орга-
низуется на физическом уровне. По причинам, указанным в части III, такую избыточ-
ность не следует показывать на логическом уровне.) Иначе говоря, убедиться в том, что
база данных действительно восстанавливаема, можно, получив гарантии, что любая
часть содержащейся в базе данных информации может быть реконструирована из другой
информации, избыточно сохраняемой где-то в системе.
Прежде чем идти дальше, необходимо уяснить, что принцип восстановления (а в дей-
ствительности и обработки транзакций в целом) в значительной степени не зависит от
того, какой является базовая система: реляционной или какой-либо еще. (С другой сто-
роны, следует отметить, что исторически сложилось так, что большая часть теоретиче-
ских исследований в области обработки транзакций была выполнена и продолжает вы-
полняться именно в реляционном контексте.) Нужно также заметить, что это весьма об-
ширный предмет обсуждения, и мы сможем познакомить читателя только с наиболее
важными и основополагающими принципами. Для более углубленного изучения предме-
та можно обратиться к источникам, указанным в списке литературы в конце данной гла-
вы (в частности, обратите особое внимание на издание [14.12]).
План этой главы выглядит следующим образом. После короткого введения в разде-
лах 14.2 и 14.3 описываются фундаментальные понятия транзакции и восстановления
транзакции (т.е. восстановления базы данных после неудачного выполнения какой-либо
1 Здесь термин "непротиворечивое состояние” означает "удовлетворяются все известные
ограничения целостности”. Обратите внимание, что непротиворечивое состояние не обяза-
тельно значит корректное, тогда как корректное состояние обязательно должно быть непро-
тиворечивым. Непротиворечивое состояние может, тем не менее, быть некорректным в том
смысле, что оно неточно отражает истинное состояние дел в реальном мире. Значение термина
"непротиворечивое состояние” можно определить как “корректное в рамках тех ограничений,
которые установлены в рассматриваемой системе”.
544
Часть IV. Управление транзакциями
транзакции). Затем в разделе 14.4 более глубоко обсуждается проблема восстановления
системы (восстановление после одновременного нарушения выполнения всех текущих
транзакций, вызванного неким сбоем системы). После этого в разделе 14.5 кратко рас-
сматривается восстановление носителей (т.е. восстановление после какого-либо физиче-
ского повреждения базы данных, например из-за поломки головок дискового
накопителя). Далее в разделе 14.6 описывается исключительно важная проблема двух-
фазной фиксации транзакций, а в разделе 14.7 обсуждаются относящиеся к делу опера-
ции языка SQL. И наконец в разделе 14.8 приводятся краткое резюме и несколько заклю-
чительных замечаний.
14.2. Транзакции
Как уже указывалось в разделе 14.1, мы начнем с изучения фундаментального поня-
тия транзакции. Транзакция — это логическая единица работы. Рассмотрим следую-
щий пример. Предположим сначала, что переменная-отношение Р (переменная-
отношение деталей) включает дополнительный атрибут TOTQTY, представляющий собой
общий объем поставок для каждой детали. Другими словами, предполагается, что значе-
ние атрибута TOTQTY для любой конкретной детали равно сумме всех значений атрибута
QTY для всех поставок данной детали (в терминах главы 8 это ограничение базы данных).
На рис. 14.1 показан псевдокод процедуры вставки в базу данных сведений о новой по-
ставке со значением 1000 для поставщика 'S5' и детали 'Р1' (команда INSERT добавляет
сведения о новой поставке в отношение SP, а команда UPDATE обновляет значение атри-
бута TOTQTY для детали 'Р1').
BEGIN TRANSACTION ;
INSERT INTO SP
RELATION { TUPLE { S# S# ( 'S5' ),
P# P# ( 'Pl' ),
QTY QTY ( 1000 ) } } ;
IF <возникла ошибка> THEN GO TO UNDO ; END IF ;
UPDATE P WHERE P# = P# ( 'РГ )
TOTQTY := TOTQTY + QTY ( 1000 ) ;
IF <возникла ошибка> THEN GO TO UNDO ; END IF ;
COMMIT ;
GO TO FINISH ;
UNDO :
ROLLBACK ;
FINISH :
RETURN ;
Puc 14 1 Пример транзакции (псевдокод)
Глава 14. Восстановление
545
В приведенном примере предполагается, что речь идет об одиночной, атомарной
операции. На самом деле добавление сведений о новой поставке — это выполнение двух
обновлений в базе данных: операции INSERT и операции UPDATE. Более того, в базе дан-
ных между этими двумя обновлениями временно нарушается требование, что значение
атрибута TOTQTY для детали ' Р1' равно сумме всех значений атрибутов QTY для этой де-
тали. Таким образом, логическая единица работы (т.е. транзакция) вовсе необязательно
является простой одиночной операцией системы баз данных; чаще всего она представля-
ет собой последовательность из нескольких таких операций. В общем случае выполне-
ние этой последовательности переводит базу данных из одного непротиворечивого со-
стояния в другое, причем в промежуточных точках выполнения база данных может на-
ходиться в противоречивом состоянии.
Из этого следует, что не допустимо, чтобы одно из обновлений было выполнено, а
другое нет, так как в этой ситуации база данных останется в противоречивом состоянии.
В идеальном случае необходимо иметь абсолютную гарантию, что всегда будут выпол-
няться оба обновления. К сожалению, подобную гарантию дать нельзя, поскольку нельзя
исключить вероятность того, что может случиться что-то непредвиденное, причем в са-
мый неподходящий момент. Например, между операциями INSERT и UPDATE может про-
изойти сбой системы или же во время выполнения второй операции может возникнуть
арифметическое переполнение и т.п. Однако система, поддерживающая обработку
транзакций, гарантирует максимум из того, что можно гарантировать, а именно — что
если во время выполнения неких обновлений произойдет ошибка (по любой причине), то
все эти обновления будут отменены. Таким образом, транзакция или полностью выпол-
няется, или полностью отменяется (как будто она вообще не выполнялась), т.е. выполне-
ние неатомарной последовательности операций с точки зрения внешнего наблюдателя
будет выглядеть так же, как выполнение атомарной операции.
Системный компонент, обеспечивающий атомарность (или ее подобие), называется
менеджером транзакций или диспетчером обработки транзакций (transaction
processing monitor— TP-monitor), а ключевыми элементами в его выполнении служат
операторы COMMIT и ROLLBACK.
Оператор COMMIT (зафиксировать) сигнализирует об успешном окончании транзак-
ции. Он сообщает менеджеру транзакций, что логическая единица работы успеш-
но завершена, база данных вновь находится (или будет находиться) в непротиво-
речивом состоянии, а все обновления, выполненные данной логической единицей
работы, теперь могут быть “зафиксированы”, т.е. сделаны постоянными.
Оператор ROLLBACK (откатить) сигнализирует о неудачном окончании транзакции.
Он сообщает менеджеру транзакций, что произошла какая-то ошибка, база данных
находится в противоречивом состоянии и следует выполнить “откат” всех проведен-
ных при выполнении этой транзакции обновлений, т.е. они должны быть отменены.
Таким образом, в приведенном примере оператор COMMIT должен выполняться, если оба
обновления прошли успешно, после чего выполненные в базе данных изменения станут по-
стоянными. Если что-то не так, если обновление было прервано каким-либо условием
ошибки, то выполняется оператор ROLLBACK и любые внесенные изменения отменяются.
Замечание. Даже если в последнем случае попытаться выполнить оператор COMMIT, то
система, в принципе, все равно должна проверить соблюдение существующих ограниче-
ний целостности, обнаружить противоречивость возникшего состояния базы данных и
Часть IV. Управление транзакциями
(
546
принудительно выполнить откат. Однако следует быть реалистами и понимать, что сис-
тема не всегда может знать обо всех уместных в каждой конкретной ситуации ограниче-
ниях, а потому выполнение оператора ROLLBACK по требованию пользователя следует
считать необходимым. На момент написания этой книги коммерческие СУБД обладали
лишь ограниченными возможностями проверки ограничений целостности в процессе
фиксации транзакций.
Кстати, следует отметить, что реальные приложения могут не только модифициро-
вать базу данных (или пытаться это сделать), но также отсылать пользователю некото-
рые сообщения о том, что произошло. В нашем примере можно отослать пользователю
сообщение “Сведения о поставке введены” после выполнения операции COMMIT и сооб-
щение “Ошибка — сведения о поставке не введены” в противном случае. Выдача сооб-
щений, в свою очередь, имеет дополнительное значение для восстановления. Более под-
робно эти вопросы обсуждаются в [14.12].
Замечание. Читателя может удивить тот факт, что обновление можно отменить. Дело в
том, что система поддерживает файл или журнал регистрации на ленте либо чаще всего на
диске, где записываются детальные сведения обо всех выполненных операциях обновления и,
в частности, новое и старое значения модифицированного объекта. Таким образом, при необ-
ходимости отмены некоторого обновления система может использовать соответствующий
журнал регистрации для возвращения объекта в первоначальное состояние.
(На самом деле это слишком упрощенное объяснение. На практике журнал регистра-
ции состоит из двух частей: активной (или оперативной) и архивной (или автономной).
Оперативная часть используется во время нормальной работы системы для записи под-
робных сведений об осуществляемых обновлениях и обычно размещается на диске. По-
сле того как файл оперативной части заполняется, его содержимое перемещается в авто-
номную часть, которая обычно размещается на магнитной ленте, поскольку эта часть
всегда обрабатывается последовательно.)
Еще один важный момент. Система должна гарантировать, что индивидуальные опе-
раторы сами по себе атомарны (т.е. выполняются полностью или не выполняются
совсем). Это особенно важно для реляционных систем, в которых операторы многоуров-
невые и обычно оперируют множеством кортежей одновременно. Выполнение таких
операторов ни в коем случае не должно прерываться до завершения операции, в резуль-
тате чего система может остаться в противоречивом состоянии (например, если обнов-
лена только часть требуемых кортежей). Другими словами, если произошла ошибка во
время выполнения подобного оператора, база данных должна остаться полностью неиз-
мененной. Более того, как объясняется в главах 8 и 9, это должно быть справедливо даже
в том случае, когда действия оператора являются причиной выполнения дополнительных
фоновых операций, например каскадного удаления внешних ключей.
14.3. Восстановление транзакции
Транзакция начинается в результате успешного выполнения оператора BEGIN
TRANSACTION и заканчивается успешным выполнением оператора COMMIT или ROLLBACK.
Оператор COMMIT устанавливает так называемую точку фиксации (которая в коммер-
ческих продуктах иначе называется точкой синхронизации (syncpoint)). Точка фик-
сации соответствует концу логической единицы работы и, следовательно, точке, в ко-
торой база данных находится (или будет находиться) в состоянии непротиворечивости.
Глава 14. Восстановление
547
В противовес этому после выполнения оператора ROLLBACK база данных вновь возвра-
щается в состояние, в котором она была в момент начала обработки оператора BEGIN
TRANSACTION, т.е. в предыдущую точку фиксации. (Понятие “предыдущая точка фикса-
ции” достаточно корректно даже в случае первой транзакции в программе при
условии, что первый оператор BEGIN TRANSACTION по умолчанию устанавливает в про-
грамме первичную точку фиксации.)
Замечание. В этом разделе термин “база данных” фактически означает доступную для
транзакции часть базы данных. Другие транзакции могут выполняться параллельно с
данной транзакцией и вносить изменения в собственные части базы данных. Таким обра-
зом, “вся база данных” может и не быть в полностью непротиворечивом состоянии в мо-
мент фиксации конкретной транзакции. Однако, как объясняется в разделе 14.1, в данной
главе игнорируется возможность параллельного выполнения транзакций (поскольку та-
кое упрощение существенно не влияет на рассматриваемый вопрос).
Ниже перечислены случаи установки точки фиксации.
1. Все обновления, совершенные программой с момента установки предыдущей точ-
ки фиксации, выполнены, т.е. получили статус постоянных. До достижения точки
фиксации все выполненные транзакцией обновления могут расцениваться только
как пробные в том смысле, что они могут быть отменены (т.е. существует возмож-
ность их отката). Однако гарантируется, что с момента фиксации обновление уже
никогда не будет отменено (это и есть определение понятия “зафиксировано”).
2. Утрачена вся информация о позиционировании базы данных и сняты все блокиров-
ки кортежей. Позиционирование базы данных в этом контексте означает, что в лю-
бой заданный момент выполняющаяся программа обычно адресуется к конкретно-
му кортежу (например, посредством определенных курсоров в случае языка SQL,
как показано в главе 4). Эта адресуемость в точке фиксации теряется. Понятие
“блокировка кортежей” рассматривается в следующей главе.
Замечание. В некоторых системах имеется опция, с помощью которой программа
может сохранять адресуемость к некоторым кортежам (и, следовательно, сохранять
некоторые кортежи заблокированными) от одной транзакции к другой. Более под-
робно речь об этом пойдет ниже, в разделе 14.7.
Здесь п. 2 (исключая замечание о возможности сохранения некоторой адресуемости
и, следовательно, соответствующей блокировки кортежей) также применим, когда тран-
закция завершена оператором ROLLBACK, а не COMMIT. К п. 1 это, конечно, не относится.
Обратите особое внимание на то, что операторы COMMIT и ROLLBACK завершают тран-
закцию, а не программу. В общем случае выполнение одной программы включает вы-
полнение некоторой последовательности транзакций, запускаемых одна за другой, как
показано на рис. 14.2.
А сейчас вернемся к примеру из предыдущего раздела (см. рис. 14.1). В нем исполь-
зуется явный тест для определения ошибок, и при обнаружении любой из них оператор
ROLLBACK выполняется явным образом. Однако не вызывает сомнения то, что работа сис-
темы не может быть построена на предположении, что в программах всегда будут ис-
пользоваться явные тесты для выявления всех возможных типов ошибок. Следовательно,
система будет выполнять оператор ROLLBACK неявно для любой программы, которая по
какой-либо причине не была нормально завершена (на рис. 14.1 “нормальное
завершение” означает явное выполнение оператора COMMIT или ROLLBACK).
548
Часть IV. Управление транзакциями
_ *------Транзакция 1--►,
I---------------1--------------------1-------------
Начало BEGIN COMMIT
программы TRANSACTION
------| -^Трэкзакция 2 (отменена) ------------
BEGIN ROLLBACK
TRANSACTION
•«------Транзакция 3 --►
—H----------------------------1----------------1
BEGIN COMMIT Завершение
TRANSACTION программы
Рис. 14.2. Выполнение типичной программы представляет собой последова-
тельность из нескольких транзакций
Из всего сказанного выше следует, что транзакции — это не только логические едини-
цы работы, но и единицы восстановления. При успешном завершении транзакции система
гарантирует, что выполненные ею обновления будут существовать в базе данных постоян-
но, даже если система потерпит крах в следующий момент. Вполне возможно, что в систе-
ме произойдет сбой после успешного выполнения оператора COMMIT, но перед тем, как об-
новления будут физически записаны в базу данных (они все еще могут оставаться в буфере
оперативной памяти и, таким образом, могут быть утеряны в момент сбоя системы). Даже
если подобное случится, процедура перезагрузки системы все равно должна повторно вно-
сить эти обновления в базу данных на основе анализа соответствующих записей в журнале
регистрации. (Из этого следует, что журнал регистрации должен быть физически записан
перед завершением операции COMMIT. Это важное правило называется протоколом пред-
варительной записи в журнал (write-ahead log rule).) Процедура перезагрузки позволяет
восстановить любые успешно завершенные транзакции, обновления которых не были фи-
зически записаны во вторичную память до возникновения сбоя системы. Следовательно,
как и указывалось ранее, транзакция действительно является единицей восстановления.
Замечание. В следующей главе будет показано, что транзакции также являются еди-
ницами параллельности. Более того, поскольку они предназначены для перевода базы
данных из одного непротиворечивого состояния в другое непротиворечивое состояние,
транзакции являются и единицами целостности (см. главу 8).
ACID-свойства транзакций
Как и в [14.14], можно подытожить материал этого и предыдущего разделов, сделав
заключение, что транзакции обладают четырьмя важными свойствами: атомарностью
(atomicity), согласованностью (consistency), изолированностью (isolation) и долговечно-
стью (durability). Этот набор свойств принято называть ACID-свойствами (по первым
буквам их английских названий).
В Атомарность. Транзакции атомарны (выполняется все или ничего).
Согласованность. Транзакции сохраняют базу данных в согласованном состоянии.
Это означает, что они переводят базу данных из одного непротиворечивого состоя-
ния в другое, но без обязательной поддержки ее непротиворечивости во всех проме-
жуточных точках выполнения.
Глава 14. Восстановление
549
Изолированность. Транзакции изолированы одна от другой. Это означает, что,
даже если будет запущено множество транзакций, работающих параллельно, ре-
зультаты любых операций обновления, выполняемых отдельной транзакцией,
будут скрыты от всех остальных транзакций до тех пор, пока эта транзакция не
будет зафиксирована. Иначе говоря, для любых отдельных транзакций Т1 и Т2
справедливо следующее утверждение: Т1 сможет увидеть результаты выполнен-
ных транзакцией Т2 обновлений только после завершения выполнения транзак-
ции Т2, а транзакция Т2 сможет увидеть результаты выполненных транзакцией
Т1 обновлений только после завершения выполнения транзакции Т1. Более под-
робно эта тема рассматривается в главе 15.
Долговечность. Если транзакция зафиксирована, выполненные ею обновления
сохраняются в базе данных постоянно, даже если в следующий момент произой-
дет сбой системы.
14.4. Восстановление системы
Система должна быть готова к восстановлению не только после локальных отказов,
подобных возникновению условия переполнения при выполнении операции в пределах
определенной транзакции, но и после глобальных нарушений, подобных отключению
питания. Локальное нарушение по определению влияет только на ту транзакцию, в кото-
рой оно, собственно говоря, и произошло. Подобные нарушения уже обсуждались выше,
в разделах 14.2 и 14.3. Глобальное нарушение воздействует сразу на все транзакции, вы-
полнявшиеся в момент его возникновения, и, следовательно, приводит к более значи-
тельным для системы последствиям. Ниже кратко описывается, какие действия необхо-
димо выполнить в процессе восстановления после глобального отказа системы. Сущест-
вует две обширные категории глобальных нарушений.
Отказы системы (например, сбои в питании) воздействуют на все выполняю-
щиеся в данный момент транзакции, но не нарушают физическое состояние базы
данных. Отказ системы иногда также называют мягким отказом.
Отказы носителей (например, поломка головки дискового накопителя), которые
могут представлять угрозу для физического состояния всей базы данных или ка-
кой-либо ее части, способны воздействовать по крайней мере на те транзакции,
которые используют поврежденную часть базы данных. Отказ носителя иногда
также называют жестким отказом.
В этом разделе будут рассмотрены отказы системы, а в разделе 14.5 — отказы носителей.
Критическим моментом в отказе системы является потеря содержимого основной
(оперативной) памяти (в частности, буферов базы данных). Поскольку точное состояние
любой выполнявшейся в момент отказа системы транзакции остается неизвестным, такая
транзакция никогда не сможет быть успешно завершена. Поэтому при перезагрузке сис-
темы любая такая транзакция будет отменена (т.е. будет выполнен ее откат).
Более того, при перезагрузке системы, возможно, потребуется (как указывалось в
разделе 14.3) повторно выполнить транзакции, которые успешно завершились до ава-
рийного отказа, но выполненные ими обновления еще не были перенесены из буферов
базы данных в физическую базу данных во вторичной памяти.
550
Часть IV. Управление транзакциями
Возникает очевидный вопрос: “Как в процессе перезагрузки система узнает, какую
транзакцию следует отменить, а какую выполнить повторно?”. Ответ заключается в том,
что система автоматически создает контрольные точки с некоторым наперед заданным
интервалом (обычно, когда в журнале накапливается определенное число записей). Соз-
дание контрольной точки означает: а) физическую перезапись (“принудительная разгруз-
ка”) содержимого рабочих буферов базы данных непосредственно в базу данных и б) фи-
зическое помещение в файл журнала специальной записи контрольной точки. На
рис. 14.3 представлен пример выполнения транзакций до аварийного сбоя системы
(время возрастает слева направо).
Рис. 14.3. Пять возможных вариантов выполнения транзакций
К этому можно добавить следующие комментарии.
Отказ системы произошел в момент tf.
Ближайшая к моменту tf контрольная точка была создана в момент tc.
Транзакция Т1 успешно завершена до момента tc.
Транзакция Т2 начата до момента tc и успешно завершена после момента tc, но
до момента tf.
Транзакция ТЗ также начата до момента tc, но не завершена к моменту tf.
Транзакция Т4 начата после момента tc и успешно завершена до момента tf.
Транзакция Т5 также начата после момента tc, но не завершена к моменту tf.
Очевидно, что при перезагрузке системы транзакции типа ТЗ и Т5 должны быть отме-
нены, а транзакции типа Т2 и Т4 — выполнены повторно. Заметьте, что транзакции типа
Т1 вообще не участвуют в процессе перезагрузки, так как выполненные ими обновления
были принудительно занесены в физическую базу данных в момент tc как часть проце-
дуры создании этой контрольной точки. Обратите внимание также на то, что транзакции,
завершившиеся неудачно (т.е. для них был выполнен откат) до момента tf, также не бу-
дут принимать участия в процессе перезагрузки (подумайте, почему).
Следовательно, во время перезагрузки система прежде всего идентифицирует все
транзакции типа Т2-Т5. При этом осуществляются следующие действия.
Глава 14. Восстановление
551
1. Создается два списка транзакций; назовем их UNDO (отменить) и REDO (выполнить
повторно). В список UNDO заносятся все транзакции, упомянутые в последней из
существующих записей контрольной точки, а список REDO пока остается пустым.
2. В журнале регистрации поиск организуется с записи последней контрольной точки.
3. Если в журнале регистрации обнаружена запись BEGIN TRANSACTION с указанием о на-
чале выполнения некоторой транзакции Т, то эта транзакция добавляется в список UNDO.
4. Если в журнале регистрации обнаружена запись COMMIT, свидетельствующая об оконча-
нии выполнения некоторой транзакции Т, эта транзакция добавляется в список REDO.
5. По достижении конца файла журнала регистрации списки UNDO и REDO анализиру-
ются для выявления транзакций типа Т2 и Т4, помещенных в список REDO, и тран-
закций типа ТЗ и Т5, оставшихся в списке UNDO.
После этого система просматривает журнал регистрации в обратном направлении,
выполняя откат транзакций из списка UNDO, а затем вновь просматривает журнал в пря-
мом направлении, повторно выполняя транзакции из списка REDO2.
Замечание. Восстановление согласованного состояния базы данных посредством от-
мены выполненных операций иногда называется обратным восстановлением. Анало-
гично восстановление согласованного состояния базы данных за счет повторного выпол-
нения уже выполненных действий называется прямым восстановлением.
И наконец, когда такая восстановительная работа будет завершена, тогда (и только
тогда) система будет готова к дальнейшей работе.
14.5. Восстановление носителей
Замечание. Тема восстановления носителей представляет собой нечто совершенно
самостоятельное и не имеющее отношения к транзакциям и восстановлению системы
после сбоев. Она включена в данное обсуждение только для завершенности всей картины.
Как уже отмечалось в разделе 14.4, отказы носителей— это нарушения наподобие
поломки головок дискового накопителя или отказа контроллера дисков, когда некоторая
часть базы данных разрушается физически. Восстановление после такого нарушения
включает перезагрузку (или восстановление) базы данных с резервной копии (или
дампа) и последующее использование журнала регистрации (как его активной, так и ар-
хивной частей) для повторного выполнения всех транзакций, успешно завершенных в
системе с момента создания данной резервной копии. При этом нет никакой необходи-
мости отменять транзакции, которые выполнялись в момент отказа носителей, поскольку
по определению все обновления, выполненные этими транзакциями, уже полностью от-
менены (фактически просто утрачены).
Таким образом, процедура восстановления носителей подразумевает наличие в сис-
теме утилиты копирования/восстановления. Функция копирования этой утилиты ис-
пользуется для создания резервной копии в установленные моменты. (Такие копии могут
2 Следует иметь в виду, что описываемая здесь процедура восстановления системы очень упроще-
на. В частности, здесь показано, что сначала выполняются операции отмены, а затем — операции по-
вторного выполнения Первые системы действительно так работали, но современные системы по со-
ображениям производительности обычно работают несколько иначе (см. [4.17], [4.19]).
552
Часть IV. Управление транзакциями
сохраняться либо на ленте, либо на других устройствах архивирования. Совсем необяза-
тельно, чтобы они создавались на устройствах хранения с прямым доступом.) Функция
восстановления утилиты используется в случае отказа носителя для воссоздания базы
данных с требуемой резервной копии.
14.6. Двухфазная фиксация
В этом разделе кратко рассматривается очень важное усовершенствование основной
концепции фиксации/отката транзакций, а именно — протокол двухфазной фиксации.
Использование этого протокола оказывается важным всякий раз, когда определенная
транзакция может взаимодействовать с несколькими независимыми менеджерами ре-
сурсов, каждый из которых распоряжается собственным набором восстанавливаемых ре-
сурсов и поддерживает собственный журнал регистрации3. Например, пусть транзакция,
выполняемая на мэйнфрейме IBM, модифицирует как базу данных СУБД IMS, так и базу
данных СУБД DB2 (между прочим, подобная транзакция вполне допустима). Если тран-
закция завершается успешно, то все выполненные ею обновления, как в базе данных
СУБД IMS, так и в базе данных СУБД DB2, должны быть зафиксированы. В противном
случае для всех внесенных обновлений должен быть выполнен откат. Иначе говоря, не-
допустима ситуация, когда обновления информации в базе данных СУБД IMS зафикси-
рованы, а для обновлений информации в базе данных СУБД DB2 выполнен откат, или
наоборот. Суть в том, что в подобном случае транзакция перестанет быть атомарной.
Отсюда следует, что для транзакции не имеет смысла выполнять оператор COMMIT в
СУБД IMS и оператор ROLLBACK в СУБД DB2. Даже если один и тот же оператор будет
выдан для обеих СУБД, система все равно может дать сбой между завершением этих
двух операций и полученные результаты окажутся неудовлетворительными. Вместо это-
го транзакция должна выдать общесистемную команду COMMIT (или ROLLBACK). Выпол-
нением таких глобальных операций фиксации или отката управляет системный компо-
нент, называемый координатором. Его задача состоит в получении гарантий, что оба
менеджера ресурсов (т.е. СУБД IMS и СУБД DB2 в нашем примере) согласованно вы-
полнят фиксацию или откат тех обновлений, за которые они ответственны. Более того,
он должен обеспечивать такую гарантию даже в том случае, если отказ системы про-
изошел до завершения всего процесса. Все это достигается за счет использования прото-
кола двухфазной фиксации.
Ниже приведена последовательность работы координатора. Для простоты примем,
что транзакция в базе данных выполнена успешно, а значит, выдана общесистемная ко-
манда COMMIT, а не ROLLBACK. После получения запроса на выполнение команды COMMIT
координатор осуществляет следующий двухфазный процесс.
1. Первая фаза начинается с выдачи координатором всем менеджерам ресурсов
указания подготовиться к завершению транзакции “тем или иным способом”. На
практике это означает, что каждый участник процесса, т.е. каждый менеджер
ресурсов, должен принудительно выгрузить все записи журнала регистрации для
используемых транзакцией локальных ресурсов в собственный физический жур-
нал регистрации (т.е. из первичной во вторичную энергонезависимую память).
3 В частности, это важно в контексте распределенных систем баз данных, а потому данный
вопрос более подробно рассматривается в главе 20.
Глава 14. Восстановление
553
Теперь, что бы ни случилось, менеджер ресурсов будет иметь постоянную запись
о работе, выполненной им в процессе обработки данной транзакции, а значит, в
случае необходимости сможет зафиксировать выполненные обновления или от-
менить их. Если принудительная разгрузка прошла успешно, менеджер ресурсов
отвечает координатору, что все “ОК”. В противном случае он посылает противо-
положное сообщение — “Not ОК”.
2. Вторая фаза наступает после того, как координатор получит соответствующие
ответы от всех участников. Сначала он принудительно выгружает записи о за-
вершаемой транзакции в собственный физический журнал регистрации, фикси-
руя свое решение относительно этой транзакции. Если все поступившие ответы
были “ОК”, то координатор принимает решение глобально зафиксировать дан-
ную транзакцию. Если же поступил хотя бы один ответ “Not ОК”, то для тран-
закции будет выполнен глобальный откат. Затем координатор каким-либо спосо-
бом информирует каждого из участников транзакции о своем решении и каждый
участник согласно поступившей инструкции должен или локально зафиксиро-
вать транзакцию, или выполнить ее откат. Обратите внимание, что каждый
участник должен делать то, что ему велел координатор в ходе выполнения вто-
рой фазы; в этом и состоит суть данного протокола. Обратите также внимание,
что именно появление записи этого решения в физическом журнале регистрации
координатора и отмечает переход от фазы 1 к фазе 2.
Теперь, если система дает сбой в какой-либо точке всего этого процесса в целом,
процедура перезагрузки будет искать запись о принятом решении в журнале регистрации
координатора. Если она будет обнаружена, то можно будет установить, какое решение
было принято до остановки, и продолжить обработку. Если подобная запись не будет об-
наружена, будет принято решение об откате данной транзакции и, следовательно, про-
цесс так или иначе завершится.
Замечание. Стоит подчеркнуть, что если координатор и участники выполняют свою ра-
боту на различных компьютерах, что типично для распределенной системы (глава 20), то
ошибка в работе координатора может привести к тому, что некий участник достаточно дол-
го будет ожидать поступления сведений о принятом координатором решении. В течение
всего времени ожидания любое из обновлений, произведенное транзакцией в базе данных
этого участника, должно быть скрыто от других транзакций (иначе говоря, эти обновления
должны быть заблокированы, о чем речь пойдет в следующей главе).
Отметим, что менеджер передачи данных (см. главу 2) также может рассматривать-
ся как менеджер ресурсов в описанном выше смысле. Это означает, что сообщения
можно считать такими же восстанавливаемыми ресурсами, как и саму базу данных, а
менеджер передачи данных должен быть способен участвовать в процессе двухфазной
фиксации. Для дальнейшего изучения этого вопроса, а также общей идеи двухфазной
фиксации обратитесь к [14.12].
14.7. Поддержка языка SQL
В этом разделе кратко рассматриваются средства поддержки работы с транзакциями в
языке SQL и, в частности, процедур восстановления на основе транзакций. Прежде всего, в
языке SQL поддерживаются обычные операции COMMIT и ROLLBACK (с необязательным допол-
554
Часть IV. Управление транзакциями
нительным ключевым словом WORK в обоих случаях, описанным выше, в главе 4). Для каждо-
го открытого курсора эти операции принудительно выполняют операцию CLOSE (закрыть), что
вызывает потерю всей имевшейся информации о позиционировании базы данных.
Замечание. В некоторых версиях языка SQL предусмотрена возможность защиты от ав-
томатического выполнения операции CLOSE (для операции COMMIT, но не для ROLLBACK) и
вызванной этим потери информации о позиционировании. Например, в СУБД DB2 при
объявлении курсора допускается использование опции WITH HOLD. В результате при выпол-
нении операции COMMIT подобный курсор не закрывается, а остается открытым и позицио-
нированным таким образом, что выполнение очередной команды FENCH вызовет перемеще-
ние к следующей строке последовательности. В данном случае при выполнении следующей
операции OPEN не потребуется вновь обрабатывать код (возможно, очень сложный), пред-
назначенный для восстановления утраченной информации о позиционировании. Такая воз-
можность в настоящее время включена в версию стандарта SQL3 (см. приложение Б).
Важное различие между способом поддержки средств работы с транзакциями в языке
SQL и общими концепциями, обсуждавшимися в этой главе, состоит в том, что язык SQL
не имеет никакого явного оператора BEGIN TRANSACTION. Вместо этого транзакция неяв-
но начинается всякий раз, когда программа выполняет операцию инициализации тран-
закции при условии отсутствия уже выполняющейся транзакции. (Подобно описанной
выше возможности сохранения информации о позиционировании, вполне вероятно, что
поддержка явной операции BEGIN TRANSACTION станет в языке SQL стандартной. В на-
стоящее время она включена в состав версии стандарта SQL3.) Подробное описание опе-
раций инициализации транзакции здесь не приводится; достаточно сказать, что операции
определения данных и манипулирования ими, обсуждавшиеся в предыдущих главах, от-
носятся к операциям инициализации, а операции COMMIT и ROLLBACK, очевидно, нет.
Специальный оператор SET TRANSACTION используется для задания характеристик тран-
закции, которая будет инициализирована. (Оператор SET TRANSACTION может выполнять-
ся только тогда, когда не выполняются никакие транзакции, и сам по себе он не является
инициализирующим транзакцию оператором.) Здесь мы обсудим только две из сущест-
вующих характеристик: режим доступа и уровень изоляции. Ниже показан общий син-
таксис этого оператора.
SET TRANSACTION <список опций> ;
Здесь параметр <список опций> включает режим доступа, уровень изоляции или и
то, и другое.
Режим доступа может быть либо только для чтения (READ ONLY), либо для чтения
и записи (READ WRITE). Если ничего не оговорено, то по умолчанию используется
значение READ WRITE. Если оговорен уровень изоляции READ UNCOMMITTED, то по
умолчанию используется значение READ ONLY. Если применяется значение READ
WRITE, то значение READ UNCOMMITTED не может использоваться при определении
уровня изоляции.
Уровень изоляции определяется в виде ISOLATION LEVEL <изоляциЯ>, где пара-
метр изоляция может иметь одно из следующих значений: READ UNCOMMITTED,
READ COMMITTED, REPEATABLE READ или SERIALIZABLE. Более подробные пояснения
приведены в главе 15.
Глава 14. Восстановление
555
14.8. Резюме
В этой главе кратко представлена необходимая информация об обработке транзак-
ций. Транзакция — это логическая единица работы, а также единица восстановле-
ния (кроме того, единица параллельности и целостности; подробности приводятся в гла-
вах 15 и 8 соответственно). Транзакции обладают ACID-свойствами — атомарностью,
согласованностью, изолированностью и долговечностью. Управление транзакция-
ми предусматривает решение задачи организации их выполнения таким образом, чтобы
соблюдение всех этих важнейших свойств абсолютно гарантировалось. Проще говоря,
общая цель функционирования всей системы может быть определена как надежное вы-
полнение потока транзакции.
Транзакции инициируются операцией BEGIN TRANSACTION и завершаются опера-
цией COMMIT (в случае успешного завершения) либо ROLLBACK (в случае неудачного
завершения). Оператор COMMIT устанавливает точку фиксации (при этом обновле-
ния становятся постоянными). Выполнение оператора ROLLBACK возвращает базу
данных в предыдущую точку фиксации (все внесенные изменения отменяются). Ес-
ли транзакция не достигает запланированного завершения, система принудительно
выполняет для нее операцию ROLLBACK (восстановление транзакции). Для получе-
ния возможности отмены (или повторного внесения) выполненных обновлений сис-
тема поддерживает журнал регистрации транзакций. Важно отметить, что все за-
писи регистрации хода выполнения некоторой транзакции должны быть физически
занесены в журнал до выполнения для этой транзакции операции COMMIT (правило
предварительной записи в журнал).
Кроме того, необходимо гарантировать сохранение ACID-свойств транзакций
даже в случае сбоя системы. Для обеспечения такой гарантии система должна: а)
повторно выполнить всю работу, выполненную транзакциями, которые успешно
завершились до момента отказа; б) отменить всю работу, выполненную транзак-
циями, которые начались, но не закончились до момента сбоя. Восстановление
системы осуществляется как часть процедуры перезагрузки (которая иначе назы-
вается процедурой перезагрузки/восстановления). Анализируя последнюю имею-
щуюся в журнале запись контрольной точки, система определяет, какую работу
необходимо выполнить повторно, а какую отменить. Записи контрольной точки за-
носятся в журнал через установленное время.
Система также обеспечивает восстановление носителей, что реализуется путем вос-
становления базы данных с заранее созданной резервной копии (дампа) с последующим
использованием журнала для повторного выполнения всей работы, проведенной в базе
данных после создания данной резервной копии. Для поддержки функции восстановле-
ния носителей используются утилиты восстановления с резервной копии.
Системы, позволяющие транзакциям взаимодействовать с двумя (или более) раз-
личными менеджерами ресурсов (например, с двумя разными СУБД или СУБД и
менеджером передачи данных), должны использовать протокол, называемый прото-
колом двухфазной фиксации, который обеспечивает обязательное соблюдение
свойства атомарности транзакции. Две фазы этого протокола включают: а) подгото-
вительную фазу, в которой координатор дает указание всем участникам быть го-
товыми “действовать одним из возможных способов”; б) фазу фиксации, в которой
координатор (после того как все участники дали ожидаемый от них ответ во время
556
Часть IV. Управление транзакциями
предыдущей фазы) инструктирует участников, что можно выполнить окончательную
фиксацию данной транзакции (или ее откат в случае получения хотя бы одного от-
рицательного ответа).
В отношении средств поддержки восстановления, определенных в стандарте языка
SQL, следует отметить, что в языке SQL предусмотрены явные операции COMMIT и
ROLLBACK, но нет явной операция BEGIN TRANSACTION. В нем также предусмотрена опе-
рация SET TRANSACTION, которая позволяет установить режим доступа и уровень изо-
ляции для следующей выполняемой транзакции.
И еще один момент. По умолчанию считалось, что в данной главе речь идет о
среде прикладного программирования. Тем не менее все описанные концепции при-
менимы и к пользовательской среде (хотя на этом уровне они могут быть в опреде-
ленной степени скрыты). Например, SQL-продукты обычно позволяют пользователю
вводить SQL-операции интерактивно, с терминала. Обычно каждая такая интерак-
тивная SQL-операция обрабатывается как отдельная транзакция — по умолчанию
система будет автоматически выполнять операцию COMMIT от имени пользователя
сразу после выполнения заданной им SQL-операции (или же операцию ROLLBACK, ес-
ли произойдет сбой). Однако в некоторых системах пользователи могут запрещать
такие автоматические операции COMMIT и вместо этого выполнять целую серию SQL-
операций (за которыми последует явная операция COMMIT), как единую транзакцию.
На практике делать это не рекомендуется, так как в подобном случае часть базы
данных может быть заблокирована и на длительное время стать недоступной для
других пользователей (глава 15). Более того, в такой операционной среде для конеч-
ных пользователей возможно возникновение ситуации взаимной блокировки, что яв-
ляется еще одним аргументом в пользу отказа от подобной практики (подробности
приводятся в главе 15).
Упражнения
14.1. Системы баз данных не позволяют транзакции фиксировать изменения только в
отдельных базах данных (или переменных-отношениях и т.д.), т.е. без одновремен-
ного фиксирования этих изменений во всех других базах данных (или переменных-
отношениях и т.д.). Почему?
14.2. Транзакции не могут быть вложены одна в другую. Почему?
14.3. Дайте определение правила предварительной записи в журнал. Для чего оно нужно?
14.4. Каков смысл описанных ниже требований с точки зрения восстановления?
а) Принудительная запись буферов базы данных во время операции COMMIT.
б) Запрещение физической записи буферов в базу данных до выполнения опера-
ции COMMIT.
14.5. Изложите суть протокола двухфазной фиксации и опишите последствия отказа во
время каждой из его двух фаз для координатора и участника в отдельности.
14.6. Используя базу данных поставщиков и деталей, создайте SQL-программу для вы-
борки и распечатки сведений обо всех деталях в порядке их номеров детали, уда-
ляя каждую десятую строку и начиная каждую новую транзакцию после каждой
Глава 14. Восстановление
557
десятой строки. Предположим, что для внешнего ключа таблицы деталей по отно-
шению к данным о поставщиках для операции DELETE задано правило CASCADE (т.е.
в рамках этого упражнения можно игнорировать поставки).
Замечание. В данном случае предложено предоставить решение с помощью языка
SQL, поэтому при подготовке ответа можно использовать механизм SQL-курсоров.
Список литературы
14.1. Bernstein Р.A. Transaction Processing Monitors И САСМ. — November, 1990. — 33, № 11.
“ТР-система является интегрированным набором продуктов, которые... вклю-
чают аппаратное обеспечение, такое как процессоры, оперативная память, диски,
контроллеры обмена данными, а также программное обеспечение, такое как опе-
рационные системы, СУБД, компьютерные сети и TP-диспетчеры. Интеграция
этих средств, в основном, достигается благодаря TP-диспетчерам.” Эта статья
является хорошим неформальным введением в структуру и функции диспетчеров
обработки транзакций.
14.2. Bernstein Р.А., Hadzilacos V., Goodman N. Concurrency Control and Recovery in
Database Systems. — Reading, Mass.: Addison-Wesley, 1987.
В этом учебнике намного шире, чем в представленной главе, описываются не только
восстановление (как следует из ее названия), но и обработка транзакций в целом.
14.3. Bilris A. et al. ASSET: A System for Supporting Extended Transactions 11 Proc. 1994
ACM SIGMOD Int. Conf, on Management of Data, Minneapolis, Minn., May, 1994.
Основные понятия в области обработки транзакций, изложенные в этой и следую-
щей главах, считаются чрезмерно жесткими для некоторых типов приложений
(особенно для высокоинтерактивных приложений), а потому для устранения дан-
ного недостатка было предложено несколько “расширенных моделей обработки
транзакций” [14.15]. Но на время написания настоящей книги ни одно из этих
предложений не продемонстрировало своего очевидного превосходства над дру-
гими. В результате “разработчики баз данных [не спешили] с включением какой-
либо одной модели в свои программные продукты”.
Основное назначение системы ASSET выглядит несколько иначе. Вместо предло-
жения еще одной модели обработки транзакций в ней предлагается набор прими-
тивных операторов (включая оператор COMMIT, а также новые операторы), которые
могут быть использованы для “определения настраиваемых моделей обработки
транзакций, подходящих для специализированных приложений”. В частности, в
статье показано, как система ASSET может использоваться для определения
“вложенных транзакций, разделяемых транзакций, хроник и других расширенных
моделей обработки транзакций, описанных в литературе”.
14.4. Bjork L.A. Recovery Scenario for a DB/DC System 11 Proc. ACM National Conference. —
Atlanta, Ga, August, 1973.
Эта и аналогичная статья Дэвиса (Davies) [14.7] представляют собой, наверное,
наиболее ранние теоретические работы в области восстановления.
14.5. Crus R.A. Data Recovery in IBM DATABASE 2 H IBM Sys. J. — 1984. — 23, № 2.
558
Часть IV. Управление транзакциями
Здесь подробно описан механизм восстановления, используемый в системе DB2
(тем самым дано очень хорошее общее описание механизма восстановления). В
частности, объясняется, как система DB2 восстанавливается в процессе восста-
новления после сбоя в системе, в то время как сама транзакция находится посе-
редине отката. При решении этой проблемы необходимо убедиться в том, что
незафиксированные обновления транзакции, для которой выполнялся откат, бу-
дут действительно отменены.
14.6. Date C.J. Distributed Database: A Closer Look 11 C.J. Date and Hugh Darwen. Relational
Database Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
В разделе 14.6 этой главы описан базисный протокол двухфазной фиксации, для
которого можно предложить некоторые усовершенствования. Например, если уча-
стник Р отвечает координатору С в фазе 1, что он не совершает обновлений в дан-
ной транзакции (т.е. работает в режиме только для чтения), то С может просто иг-
норировать Р в фазе 2. Соответственно, если все участники в фазе 1 сообщают, что
они работают в режиме только для чтения, фаза 2 может быть опущена.
Также возможны и другие усовершенствования. В статье приводится вводное опи-
сание некоторых из них. Специально описаны протоколы предположительной
фиксации и предположительного отката (улучшенные версии базисного прото-
кола), модель дерева операций (когда участнику необходимо отвечать за выполне-
ние определенной части транзакции в качестве координатора), а также ситуация,
при которой во время пересылки подтверждения от участника к координатору
происходит коммуникационный сбой.
Замечание. Хотя, в основном, обсуждение ведется в контексте распределенных сис-
тем, большинство обсуждаемых концепций в действительности может иметь более
широкое применение. Подробно указанные вопросы рассматриваются в главе 20.
14.7. Davies С.Т., Recoveiy Jr. Semantics for a DB/DC System // Proc. ACM National Conf. —
Atlanta, Ga, August, 1973.
См. комментарий к [14.4].
14.8. Davies C.T., Recovery Jr. Data Processing Spheres of Control 11 IBM Sys. J.—
1978. — 17, № 2.
Понятие сфер управления (Spheres of Control) было первой попыткой изучить и
формализовать то, что в дальнейшем стало называться обработкой транзакций.
Сфера управления — это абстракция, представляющая часть работы, которая со
стороны может выглядеть атомарной. В отличие от транзакций сферы управления
могут вкладываться одна в другую до любого уровня (в упражнениях к данной гла-
ве рассмотрен вопрос, почему транзакции не могут быть вложены одна в другую).
14.9. Garcia-Molina Н., Salem К. Sagas И Proc. 1987 ACM SIGMOD Intern. Conf, on
Management of Data. — San Francisco, Calif, May, 1987.
Большинство проблем, связанных с транзакциями, состоит в том, что по умол-
чанию транзакции длятся очень короткое время (милли- или даже микросекун-
ды). Но если транзакция длится долго (часы, дни, недели), то а) в случае ее от-
ката будет отменена очень большая часть работы; б) даже если все пройдет ус-
пешно, она все же будет удерживать ресурсы системы неопределенно долгое
время, тем самым блокируя доступ к ним других пользователей (этот вопрос
подробнее обсуждается в следующей главе). К сожалению, множество реаль-
Глава 14. Восстановление
559
ных транзакций стремится к увеличению времени своего действия, особенно в
новейших сферах применения, таких как проектирование и разработка про-
граммного и аппаратного обеспечения.
Хроники представляют собой попытку решения этой проблемы. Хроника
(saga) — это последовательность коротких транзакций (в обычном понимании
этого термина), для которых со стороны системы гарантируется, что либо все
транзакции данной последовательности будут выполнены успешно, либо будут
выполнены некоторые компенсационные транзакции, предназначенные для
отмены результатов успешно выполненных транзакций в случае незавершенного
выполнения всей хроники в целом (таким образом, система будет приведена в
состояние, существовавшее до начала выполнения хроники). Например, в бан-
ковских системах для транзакции “Добавить $100 на счет А” компенсационной
транзакцией, очевидно, будет “Снять $100 со счета А”. Расширение оператора
COMMIT позволяет пользователю информировать систему о том, что в случае от-
мены только что завершенной транзакции должна быть запущена определенная
компенсационная транзакция. Обратите внимание, что в идеале компенсацион-
ная транзакция никогда не должна завершаться откатом.
14.10. Gray J. Notes on Data Base Operating System 11 Operating Systems: An Advanced
Course. — New York, N.Y.: Springer-Verlag, 1978.
Это один из первых источников литературы о транзакциях, содержащий первое
общедоступное описание протокола двухфазной фиксации. Очевидно, оно не столь
всеобъемлюще, как более новые работы [14.12], но мы все еще рекомендуем с ним
ознакомиться.
14.11. Gray J. The Transaction Concept: Virtues and Limitations П Proc. 7th Intern. Conf, on
Very Large Data Bases. — Cannes, France, 1981.
В этой работе приводится краткое описание проблем, связанных с транзакция-
ми, включая вопросы их реализации. Одна из таких проблем формулируется
следующим образом. Обычно предполагается, что транзакции не могут вкла-
дываться одна в другую (в упражнениях к данной главе рассматривается во-
прос, почему этого не может быть). Возникает вопрос: “А может, все-таки
можно сделать так, чтобы транзакция состояла из нескольких малых
«подчиненных транзакций»?”. Краткий ответ таков: “Да!”. Это допустимо для
транзакций, которые в определенные моменты свЬего выполнения будут уста-
навливать промежуточные точки сохранения (savepoints) и соответственно в
случае необходимости откатываться в такую предыдущую точку вместо того,
чтобы откатиться полностью к началу транзакции. Действительно, подобные
точки сохранения использовались в нескольких системах, включая систему
Ingres (коммерческий продукт, а не прототип) и систему R (но не DB2). Данная
концепция представляется наиболее близкой к реальному понятию транзакции.
Обратите внимание, что создание точки сохранения — это не то же самое, что
выполнение операции COMMIT, поскольку обновления, осуществленные тран-
закцией, все еще не видны для других транзакций до тех пор, пока не будет
успешно завершена вся транзакция.
14.12. Gray J., Reuter A. Transaction Processing: Concepts and Techniques. — San Mateo,
Calif.: Morgan Kaufmann, 1993.
560
Часть IV. Управление транзакциями
Если какая-либо публикация в области информатики и заслуживает эпитета
“классическая”, то это, наверное, именно эта книга. Ее размер может показаться
просто устрашающим, однако авторам удалось пролить свет даже на самые слож-
ные аспекты обсуждаемой темы и одновременно сделать чтение предлагаемого ма-
териала достаточно легким. В предисловии авторы заявляют о своем намерении
“помочь... в решении реальных проблем”; книга “прагматична и очень подробно
освещает основные проблемы обработки транзакций”; в ней “представлены фраг-
менты программ, демонстрирующие... основные алгоритмы и структуры данных”;
однако она не является “энциклопедией”. Вопреки последнему утверждению, эта
книга представляет собой достаточно полное руководство по данной теме и ей,
очевидно, суждено стать стандартным пособием в данной области. Настоятельно
рекомендуем вам ее прочесть.
14.13. Gray J. et al. The Recovery Manager of the System R Data Manager П ACM Comp.
Surv. — June, 1981, — 13, №2.
Работы [14.13], [14.18] связаны с особенностями средств восстановления системы
System R (одной из первых систем в данной области). В [14.13] дается краткий об-
зор всей подсистемы восстановления, а в [14.18] подробно описывается механизм
теневой страницы (см. ниже).
14.14. Harder Т., Reuter A. Principles of Transaction-Oriented Database Recovery // Ibid.—
1983.— 15, №4.
В этой статье впервые было представлено сокращение “ACID-свойства”. В ней да-
ется очень четкое и подробное представление о принципах восстановления. Здесь
приведена продуманная терминология для описания схем восстановления и мето-
дов регистрации входа в систему, даны классификация и описание множества су-
ществующих систем в соответствии с этой терминологией. Также приведены инте-
ресные эмпирические данные, показывающие частоту возникновения и типичное
время восстановления для трех видов сбоев (локальных, системных и сбоев носи-
телей) в больших системах.
Тип отказа Частота возникновения Время восстановления
Локальный Системный Сбой носителей 10—100 раз в минуту Несколько раз в неделю Один или два раза в год Равно времени выполнения транзакции Несколько минут 1—2 часа
14.15. Evolving System Concept (invited talk) П Proc. 21 st Int. Conf. On Very Large Data
Bases. — Zurich, Switzerland, September, 1995.
Прекрасный краткий обзор вариантов эволюции понятия “транзакция”, которые
удовлетворяли бы новым требованиям со стороны приложений.
14.16. Korth H.F., Levy Е., Silberschatz A. A Formal Approach to Recovery by Compensating
Transactions 11 Proc. 16th Intern. Conf, on Very Large Data Bases.— Brisbane,
Australia, 1990.
Здесь идет речь о компенсационных транзакциях, которые используются в хро-
никах [14.9] и в других случаях для “отмены” зафиксированных (а также незафик-
сированных) транзакций.
Глава 14. Восстановление
561
14.17. Lomet D., Tuttle M.R. Redo Recovery after System Crashes // Proc. 21st Int. Conf. On
Very Large Data Bases. — Zurich, Switzerland, September, 1995.
В этой работе дан строгий и тщательный анализ процесса восстановления повтор-
но выполняемых обновлений (т.е. процесса прямого восстановления). “[Хотя] про-
цесс восстановления повторно выполняемых обновлений является всего лишь од-
ной из форм восстановления, он имеет... большое значение [поскольку является
значительной частью всего процесса восстановления] и должен помочь в разреше-
нии самых сложных проблем.” (В этой связи отметим, что в отличие от алгоритма,
описанного в разделе 14.4, в методе ARIES [14.19] “предполагается понимание
восстановления... как восстановления повторно выполняемых обновлений и вос-
становления отмененных обновлений”.) Авторы заявляют, что их анализ приводит
к лучшему пониманию существующих реализаций и может значительно усовер-
шенствовать системы восстановления.
14.18. Lorie R. A. Physical Integrity in a Large Segmented Database // ACM TODS.—
1977.—2, № 1.
Как уже объяснялось в комментариях к [14.13], в этой статье описывается меха-
низм теневой страницы — один из наиболее важных аспектов восстановления
системы System R. (Отметим, что термин целостность (Integrity) в заглавии статьи
имеет значение, несколько отличное от описанного в главе 8.) Идея механизма те-
невой страницы очень проста. Когда незафиксированное обновление впервые за-
писывается в базу данных, система не переписывает существующую страницу, а
сохраняет новую где-нибудь на диске. Старая страница — это “тень” новой. Фик-
сация обновления предусматривает установку различных указателей на новую
страницу и удаление теневой страницы. И наоборот, откат обновления — это пере-
установка указателей на теневую страницу и отбрасывание новой.
Несмотря на кажущуюся простоту механизм теневой страницы имеет один серьез-
ный недостаток, заключающийся в разрушении любой физической кластеризации,
ранее установленной для данных, и потому этот механизм не был перенесен из сис-
темы System R в систему DB2 [14.5], хотя и применялся в системе SQL/DS [4.13].
14.19. Mohan С., Haderle D., Lindsay В. et al. ARIES: A Transaction Recovery Method
Supporting Fine-Granularity Locking and Partial Rollbacks Using Write-Ahead Logging
// ACM TODS. — 1992. — 17, № 1.
Название алгоритма ARIES (Algorithm for Recovery and Isolation Exploiting
Semantics) расшифровывается как “алгоритм восстановления и использующей
изоляцию семантики”. Он применяется (“в некоторой степени”) в некоторых
коммерческих и экспериментальных системах, в частности в системе DB2. Вот
несколько перефразированная цитата из этой статьи: “Решения [проблемы обра-
ботки транзакций] можно оценить с помощью нескольких критериев: степени
параллельности в пределах одной страницы и нескольких страниц; сложности
полученной логики; накладных расходов, связанных с использованием простран-
ства для хранения журнала регистрации транзакций и данных на долговремен-
ном устройстве хранения и в оперативной памяти; накладных расходов, связан-
ных с многочисленными синхронными и асинхронными операциями ввода-
вывода, которые необходимо выполнить во время перезагрузки/восстановления
и нормальной обработки; типов поддерживаемых функций (частичного отката
562
Часть IV. Управление транзакциями
транзакций и т.д.); объема вычислений, выполняемых во время перезагруз-
ки/восстановления; степени параллельности вычислений, выполняемых во время
перезагрузки/восстановления; уровня откатов транзакций, вызванных ситуация-
ми взаимной блокировки в системе; ограничений, накладываемых на хранимые
данные (например, требований уникальности ключей для всех записей, ограни-
чений максимального размера объектов до размера страницы и т.д.); способно-
сти поддерживать новые режимы блокировки, в которых допускается параллель-
ное выполнение (на основе коммутативности и других свойств) таких операций,
как инкремент/декремент для тех же данных, но разными транзакциями и т.д. По
этим критериям [ARIES] оценивается очень высоко”.
Со времени создания метода ARIES появилось множество его усовершенствова-
ний, разработано и описано в литературе несколько специализированных версий:
ARIES/CS (для систем с архитектурой “клиент/сервер”), ARIES/IM (для обработки
индексов) и ARIES/NT (для вложенных транзакций) и т.д.
Ответы к некоторым упражнениям
14.1. Подобные действия будут противоречить понятию “атомарность транзакции”. Ес-
ли бы транзакция зафиксировала некоторые, не все свои, обновления, то незафик-
сированные обновления можно было бы впоследствии аннулировать, в то время
как зафиксированные, конечно же, отменить было бы уже невозможно. Таким об-
разом, для транзакции не будет выполнено условие атомарности, требующее
“выполнить все или ничего”.
14.2. Подобное решение будет противоречить понятию “атомарность транзакции”.
Предположим, что транзакция В была вложена в транзакцию А. Тогда последова-
тельность событий будет такой (для простоты предположим, что имеет смысл го-
ворить об “обновлении кортежа”).
BEGIN TRANSACTION (транзакция А) ;
BEGIN TRANSACTION (транзакция В) ;
транзакция В обновляет кортеж t ;
COMMIT (транзакция В) ;
ROLLBACK (транзакция А) ;
Если кортеж b восстанавливается до своего предыдущего значения (назовем его
pre-А), то фиксация (COMMIT) транзакции В, по сути, не происходит полностью.
Однако если фиксация (COMMIT) транзакции В была истинной, то кортеж b не может
быть восстановлен до своего значения pre-А и, следовательно, откат (ROLLBACK)
транзакции А не может быть успешным.
Требование того, чтобы транзакции не могли вкладываться одна в другую, означа-
ет возможность выполнения команды BEGIN TRANSACTION только в том случае, ес-
ли не выполняются никакие транзакции.
Однако многие авторы (начиная с Дэвиса [14.7]) предложили реализовать воз-
можность вложения транзакций за счет отмены требования долговечности
(свойство “D” в ACID-свойствах) по отношению к части внутренней транзак-
Глава 14. Восстановление
563
ции. Это означает, что фиксация (COMMIT), выполняемая внутренней транзак-
цией, приведет к фиксации обновлений этой транзакции, но только до сле-
дующего внешнего уровня. Если же этот внешний уровень завершается откатом
выполненных действий, внутренняя транзакция также завершается откатом. В
данном примере операция COMMIT для транзакции В зафиксировала бы обнов-
ления до окончания транзакции А, но не для внешнего мира и впоследствии
действительно могла бы быть отменена.
Полезно будет детальнее рассмотреть упомянутые выше идеи. Вложенные
транзакции можно рассматривать как обобщение понятия точек сохранения
[14.11]. Точки сохранения позволяют организовать транзакции в виде последо-
вательности действий (а потому откат можно выполнить в любой момент до
начала любого другого предыдущего действия в этой последовательности), а
вложенность, наоборот, позволяет организовать транзакции в виде иерархии
таких действий (рис. 14.4).
Иначе говоря:
команда BEGIN TRANSACTION расширяется для поддержки подчиненных транзак-
ций (т.е. если команда BEGIN TRANSACTION стартует тогда, когда выполняется ка-
кая-то транзакция, запускается дочерняя транзакция);
команда COMMIT фиксирует выполне-
ние транзакции, но только в пределах
родительской области видимости
(если транзакция является дочерней);
команда ROLLBACK отменяет выпол-
ненную работу, но только до начала
этой отдельной транзакции (включая
дочерние транзакции, дочерние тран-
закции этих дочерних транзакций и
т.д., но не родительскую транзакцию).
Отметим, что вложенные транзакции в
языках, подобных языку SQL, весьма не-
удобны для воплощения (с синтаксиче-
ской точки зрения), так как в них имеет-
ся один серьезный недостаток— отсутствие явного оператора BEGIN TRANSACTION
(необходим некоторый явный способ определения начала внутренней транзакции
или точки фиксации для отката, если эта внутренняя транзакция потерпела неудачу).
14.4.
а) В случае отказа системы никогда не потребуется выполнять операции REDO.
б) Физическая операция UNDO никогда не будет необходимой. Следовательно, поме-
щать в журнал регистрации сведения об операциях UNDO также необязательно.
Это упражнение является типичным примером широкого класса приложений, для
которых обычно применяется следующее решение.
14.6.
EXEC SQL DECLARE СР CURSOR FOR
SELECT P.P#, P.NAME, P.COLOR, P.WEIGHT, P.CITY
Puc. 14.4. Пример построения вложен-
ной транзакции
564
Часть IV. Управление транзакциями
FROM P
WHERE P.P# > previousJP#
ORDER BY P# ;
previousJP# := ' ' ;
eof := false ;
DO WHILE ( eof = false ) ;
EXEC SQL OPEN CP ;
DO count := 1 TO 10 ;
EXEC SQL FETCH CP INTO :P#, ... ;
IF SQLSTATE = '02000' THEN
DO ;
EXEC SQL CLOSE CP ;
EXEC SQL COMMIT ;
eof := true ;
END DO ;
ELSE print P#, ... ;
END IF ;
END DO ;
EXEC SQL DELETE FROM P WHERE P.P# = :P# ;
EXEC SQL CLOSE CP ;
EXEC SQL COMMIT ;
previous_P# := P# ;
END DO ;
Обратите внимание на то, что информация о позиционировании в таблице деталей Р
утрачивается в конце каждой транзакции (даже если не закрывать явным образом
курсор СР, оператор COMMIT закроет его автоматически). Поэтому приведенный код
не будет особенно эффективным в связи с тем, что для каждой новой транзакции
потребуется выполнить поиск в таблице деталей для возврата к прежней позиции.
Ситуацию можно немного поправить, если использовать индекс по столбцу P# (что
обычно происходит на практике, так как {Р#} является первичным ключом) и оп-
тимизатор выберет этот индекс в качестве пути доступа к данной таблице.
Глава 14. Восстановление
565
Глава
Параллельность
15.1. Введение
Как разъяснялось во введении к главе 14, восстановление данных и параллельное вы-
полнение операций следует рассматривать совместно, поскольку обе эти темы являются
частями более общей темы, связанной с обработкой транзакций. Однако в этой главе
основное внимание уделяется именно вопросам параллельности. Термин паралле-
льность означает поддержку СУБД одновременной обработки многих транзакций, по-
лучающих доступ к одним и тем же данным, причем в одно и то же время. Как известно,
для корректной обработки параллельно выполняющихся транзакций без возникновения
конфликтных ситуаций в любой системе необходимо использовать некоторый механизм
управления параллельностью. Ниже, в разделе 15.2, приведены примеры конфликт-
ных ситуаций, возникновение которых возможно при отсутствии соответствующего ме-
ханизма управления параллельностью.
Данная глава имеет следующую структуру.
Как уже говорилось, в разделе 15.2 рассматриваются проблемы, которые могут
иметь место при отсутствии должного механизма управления параллельностью.
В разделе 15.3 предлагается стандартный метод разрешения таких проблем, полу-
чивший название метод блокировки.
Замечание. Блокировка не является единственно возможным подходом к решению
проблемы управления параллельностью, однако именно этот метод чаще всего
используется на практике. Некоторые другие подходы описаны в комментариях,
приведенных в списке литературы [15.1], [15.3], [15.6], [15.7], [15.14], [15.15].
В разделе 15.4 поясняется, как можно использовать механизм блокировки для ре-
шения проблем, обсуждавшихся в разделе 15.2.
К сожалению, использование метода блокировки связано с возникновением дру-
гих проблем, самой известной из которых является ситуация взаимной блоки-
ровки, описываемая в разделе 15.5.
В разделе 15.6 рассматривается концепция упорядочиваемости, представляющая
собой некоторый формальный критерий правильности выполнения определенного
набора параллельно выполняемых транзакций.
В разделах 15.7 и 15.8 продолжается рассмотрение некоторых важных дополне-
ний к основной идее блокировки, а именно — концепций уровней изоляции и
механизма блокировки намерения.
В разделе 15.9 описываются соответствующие средства языка SQL.
В разделе 15.10 дается краткое резюме и несколько заключительных замечаний к
материалу данной главы.
566
Часть IV. Управление транзакциями
Замечание. Здесь также будет уместно еще раз привести общие замечания, которые
были сделаны во введении к главе 14.
Во-первых, идеи управления параллельностью, как и идеи восстановления
данных, в значительной степени не зависят от того, какой является СУБД: реляци-
онной или какой-либо другой. Однако большая часть теоретической работы в этой
области, как и в области восстановления данных, была выполнена именно в реля-
ционном контексте, исходя из соображений “определенности” [15.5].
Во-вторых, управление параллельностью, как и восстановление данных, является
весьма обширной темой, а потому в этой главе будут описаны только наиболее важные
идеи. Обсуждение некоторых последних достижений в этой области знаний содержит-
ся в упражнениях и в ответах к ним, а также в списке литературы в конце главы.
15.2. Три проблемы параллельности
Прежде всего следует рассмотреть проблемы, которые обязательно должны устра-
няться любым из предлагаемых методов управления параллельностью. При обработке
транзакций в общем случае возможны три типа ситуаций, при которых параллельное вы-
полнение транзакций, каждая из которых сама по себе является корректной, из-за взаим-
ных помех способно привести к неправильному результату. Обратите внимание, что вно-
сящая помеху транзакция сама по себе может быть вполне корректной, а неправильный
конечный результат возникает из-за бесконтрольного чередования операций двух пра-
вильных транзакций. (Выражение “правильная транзакция” здесь означает, что эта тран-
закция не нарушает золотое правило, описанное в главе 8.) Ниже приводятся три про-
блемы, возникающие при параллельной обработке транзакций.
Потеря результатов обновления
Зависимость от незафиксированных результатов
Несогласованная обработка данных
Проблема потери результатов обновления
Рассмотрим ситуацию, показанную на рис. 15.1. Здесь транзакция А считывает неко-
торый кортеж t в момент tl, а транзакция В считывает этот же кортеж t в момент t2.
Далее транзакция А обновляет кортеж t в момент t3 (исходя из значений, считанных в
момент tl), а транзакция В обновляет тот же кортеж t в момент t4 (исходя из значений,
считанных в момент t2 и аналогичных значениями, которые были считаны в момент tl).
Можно видеть, что результат операции обновления, выполненной транзакцией А, будет
утерян, поскольку в момент t4 он будет перезаписан в результате операции обновления,
выполняемой транзакцией В.
Замечание. Здесь и далее в этой главе вновь делается допущение, что имеет смысл
говорить об “обновлении кортежа”.
Проблема зависимости от незафиксированных результатов
Проблема зависимости от незафиксированных результатов может возникнуть в том
случае, если любой транзакции разрешено считывание (или, что еще хуже, обновление)
кортежа, который только что был обновлен другой транзакцией, но результаты выполне-
Глава 15. Параллельность
567
ния этой транзакции еще не были зафиксированы. Если некоторое обновление не зафик-
сировано, всегда существует определенная вероятность, что оно не будет зафиксировано
никогда из-за отката данной транзакции. В этом случае первая транзакция будет обраба-
тывать данные, которые уже не существуют (и, в сущности, никогда не существовали).
Данная ситуация представлена на рис. 15.2 и 15.3.
Транзакция А Время Транзакция В
Извлечение кортежа t tl —
— t2 1 Извлечение кортежа t
Обновление кортежа t 1 t3 —
— t4 Обновление кортежа р
— Ф —
Рис. 15.1. Потеря в момент t4 результатов обновления, выполненного транзакцией А
Транзакция А Время Транзакция В
— 1 tl Обновление кортежа t
Извлечение кортежа t t2 —
— t3 Отмена выполнения транзакции
— г —
Рис. 15.2. В момент t2 транзакция А оказывается зависимой от незафиксированных ре-
зультатов обновления
Транзакция А Время Транзакция В
— tl Обновление кортежа t
Обновление кортежа t t2 —
— t3 Отмена выполнения транзакции
— г —
Рис. 15.3. Транзакция А обновляет незафиксированное изменение в момент t2, но ре-
зультаты этого обновления утрачиваются в момент t3
В первом примере (см. рис. 15.2) транзакция А в момент t2 получает доступ к неза-
фиксированным результатам обновления (иногда называемым незафиксированным из-
менением). Затем это обновление в момент t3 отменяется. В результате транзакция А вы-
полняется, исходя из ошибочного предположения, что кортеж t имеет значение, которое
он имел в момент 12, тогда как на самом деле он сохранил свое прежнее значение, кото-
рое имел в момент tl. В итоге в результате выполнения транзакции А будет получен не-
568
Часть IV. Управление транзакциями
верный результат. Кроме того, следует учитывать, что откат транзакции В может про-
изойти не по вине транзакции В, а, например, в результате сбоя системы. (К этому вре-
мени выполнение транзакции А может быть уже завершено, а потому сбой системы не
приведет к откату транзакции А.)
Второй пример, приведенный на рис. 15.3, иллюстрирует еще более неприятный
случай. В момент t2 транзакция А вновь оказывается зависимой от незафиксированно-
го изменения. Более того, в момент t3 все ее результаты фактически утрачиваются,
поскольку откат транзакции В приводит к восстановлению исходного состояния кор-
тежа t, которое он имел в момент tl. Это еще один вариант проблемы потери резуль-
татов обновления.
Проблема несогласованной обработки данных
На рис. 15.4 показаны транзакции А и В, которые обрабатывают кортежи, содержа-
щие сведения об остатках на счетах (АСС). При этом транзакция А суммирует текущие
остатки на счетах, а транзакция В выполняет перевод суммы в $10 со счета 3 на счет 1.
Полученный в итоге выполнения транзакции А результат $110, очевидно, неверен, и
если он будет помещен в базу данных, то она окажется в противоречивом состоянии1.
В таком случае говорят, что транзакция А выполняет несогласованную обработку дан-
ных, в результате чего получается противоречивый результат. Обратите внимание на
следующее отличие этого примера от предыдущего: здесь не идет речь о зависимости
транзакции А от незафиксированных результатов транзакции В, так как последняя вы-
полнила и зафиксировала все свои обновления до того, как транзакция А считала зна-
чение остатка для счета АСС 3.
15.3. Блокировка
Как упоминалось в разделе 15.1, описанные в предыдущем разделе проблемы могут
быть разрешены с помощью механизма управления параллельным выполнением процес-
сов, называемого блокировкой. Основная идея очень проста: в случае, когда при вы-
полнении некоторой транзакции необходимо иметь гарантии, что определенный объект
базы данных (обычно это кортеж) не будет непредсказуемо изменен без ведома данной
транзакции (как это имело место выше), требуемый объект блокируется. Эффект вы-
полнения блокировки состоит в том, что доступ к объекту со стороны других транзакций
запрещается, а это позволяет предотвратить его неконтролируемое изменение. В резуль-
тате установившая блокировку транзакция сможет выполнять всю необходимую обра-
ботку, имея полную гарантию, что обрабатываемый объект будет оставаться в неизмен-
ном состоянии настолько долго, насколько потребуется.
Ниже работа механизма блокировки описана более подробно.
1. Прежде всего предположим, что в системе поддерживается два типа блокировок: экс-
клюзивная блокировка, или Х-блокировка, не допускающая совместного доступа, и
разделяемая блокировка, или S-блокировка, разрешающая совместный доступ.
I В отношении этой возможности (т.е. записи результатов в базу данных) предполагается,
что не существует никаких ограничений целостности, запрещающих подобную запись.
Глава 15. Параллельность
569
АСС 1 40 АСС 2 50 ACC 3 30
Транзакция А Время Транзакция В
Извлечение кортежа ACC 1: tl —
sum = 40 | —
Извлечение кортежа ACC 2: t2 —
sum = 90 | —
— t3 Извлечение кортежа АСС 3:
— t4 Обновление кортежа АСС 3:
— 1 30 20
— 1 t5 Извлечение кортежа АСС 1:
— t6 Обновление кортежа АСС 1:
— I 40 -> 50
— 1 t7 Фиксация результатов транзакции
Извлечение кортежа АСС 3: t8
sum = 110 (а не 120) г
Рис. 15.4. Транзакция А получила противоречивый результат
Замечание. X- и S-блокировки иногда называют блокировками для записи и чте-
ния соответственно. Здесь предполагается, что возможны только X- и S-блокировки,
хотя в разделе 15.8 приводятся примеры блокировок других типов. Кроме того, предпо-
лагается, что единственным типом “блокируемого объекта” являются кортежи, хотя
примеры других типов таких объектов описаны, опять же, в разделе 15.8.
2. Если транзакция А заблокировала кортеж t без возможности взаимного доступа (X-
блокировка), то запрос другой транзакции В на блокировку этого же кортежа t бу-
дет отменен.
3. Если транзакция А заблокировала кортеж t с возможностью взаимного доступа (S-
блокировка), то:
запрос со стороны некоторой транзакции В на выполнение Х-блокировки корте-
жа t будет отвергнут;
запрос со стороны некоторой транзакции В на выполнение S-блокировки кортежа
t будет принят (т.е. для транзакции В также будет установлена S-блокировка кор-
тежа t).
Эти правила можно наглядно представить в виде матрицы совместимости типов бло-
кировок, показанной на рис. 15.5. Эта матрица интерпретируется следующим образом. Рас-
смотрим некоторый кортеж t и предположим, что транзакция А блокирует кортеж t раз-
личными типами блокировки (что обозначено в заголовках столбцов соответственно сим-
волами S и X, тогда как отсутствие блокировки — прочерком). Предположим также, что
некоторая транзакция В запрашивает блокировку кортежа t, тип которой на рис. 15.5 указан
570
Часть IV. Управление транзакциями
в первом слева столбце матрицы. (Для полноты картины в таблице также приведен случай
отсутствия блокировки.) В остальных ячейках матрицы символ N отмечает конфликтную
ситуацию (запрос со стороны транзакции В не может быть удовлетворен, и эта транзакция
переводится в состояние ожидания), a Y— допустимую ситуацию (запрос со стороны
транзакции В удовлетворяется). Очевидно, что данная матрица является симметричной.
X S — X N N Y S N Y Y — Y Y Y
Рис. 15.5. Матрица совместимости для X- и S-блокировок
Теперь следует ввести понятие протокол доступа к данным (или протокол блоки-
ровки), который с помощью описанных выше X- и S-блокировок позволит избежать
возникновения проблем, обсуждавшихся в разделе 15.22.
1. Прежде чем считать какой-либо кортеж, транзакция должна установить для него S-
блокировку.
2. Прежде чем обновить какой-либо кортеж, транзакция должна установить для него
Х-блокировку. Если транзакция уже установила для кортежа S-блокировку (что
возможно в случае последовательного выполнения операций Retrieve и Update),
необходимо расширить S-блокировку до уровня Х-блокировки.
Замечание. В транзакциях запросы на установку блокировки обычно задаются не-
явным образом; например, запрос на выборку кортежа подразумевает неявный за-
прос на установку для него S-блокировки, а запрос на обновление кортежа — неяв-
ный запрос на установку для него Х-блокировки. При этом под термином
“обновление” (как и ранее) подразумеваются, помимо операций UPDATE, также опе-
рации INSERT (вставка) и DELETE (удаление). При строгом описании протокола
имеют место небольшие отличия, связанные с выполнением операций вставки и
удаления, однако здесь они опущены.
3. Если запрашиваемая со стороны транзакции В блокировка отвергается из-за конфликта
с блокировкой, уже установленной со стороны транзакции А, то транзакция В перево-
дится в состояние ожидания. Причем транзакция В будет находиться в состоянии ожи-
дания до тех пор, пока не будет снята блокировка, установленная ранее транзакцией А.
Замечание. Система обязательно должна гарантировать, что транзакция В не бу-
дет находиться в состоянии ожидания бесконечно долго (иногда эту ситуацию
называют зависанием). Самым простым способом получения подобной гарантии
является организация обработки запросов на блокировку по принципу “первым
поступил — первым обработан”.
4. Х-блокировки сохраняются вплоть до конца выполнения установившей их транзак-
ции (до ее фиксации (COMMIT) или отката (ROLLBACK)). S-блокировки также обычно
сохраняются вплоть до окончания транзакции, однако в этом случае следует учесть
замечания, изложенные в разделе 15.7.
2 Описываемый здесь протокол является примером протокола двухфазной блокировки (более
подробно он рассматривается в разделе 15 6)
Глава 15. Параллельность
571
15.4. Устранение трех проблем параллельности
Теперь можно вновь вернуться к рассмотрению трех проблем параллельности, опи-
санных в разделе 15.2, и проанализировать, как они решаются с помощью механизма
блокировок, предложенного в предыдущем разделе.
Проблема потери результатов обновления
На рис. 15.6 приведена новая версия процесса, представленного на рис. 15.1, которая из-
менена в соответствии с требованиями протокола блокировки, описанного в разделе 15.3.
Операция обновления для транзакции А в момент t3 не будет выполнена, поскольку она явля-
ется неявным запросом на установку Х-блокировки для кортежа t. Однако этот запрос всту-
пает в конфликт с S-блокировкой, уже установленной для данного кортежа транзакцией В. В
результате транзакция А будет переведена в состояние ожидания. По аналогичным причинам
транзакция В будет переведена в состояние ожидания в момент t4. Хотя в этом случае резуль-
таты обоих обновлений утрачены не будут, решение данной проблемы с помощью механизма
блокировки окажется возможным только при решении другой, вновь возникшей проблемы.
Эта новая проблема называется взаимной блокировкой и обсуждается в разделе 15.5.
Транзакция А Время Транзакция В
Извлечение кортежа t Ф Ф tl —
(установка S-блокировки для t) Ф 1 —
— ф t2 Извлечение кортежа t
— Ф 1 (установка S-блокировки для t)
Обновление кортежа t ф t3 —
(запрос Х-блокировки для кортежа t) ф —
Ожидание ф —
Ожидание t4 Обновление кортежа t
Ожидание Ф (запрос Х-блокировки для кортежа t)
Ожидание Ф Ожидание
Ожидание Ф Ожидание
Рис. 15.6. Хотя обновления не утрачиваются, в момент t4 возникает взаимная блокировка
Проблема зависимости от незафиксированных результатов
На рис. 15.7 и 15.8 приведены измененные версии примеров, представленных на
рис. 15.2 и 15.3 соответственно. Они демонстрируют чередование выполнения операций
транзакций согласно описанному выше протоколу блокировки. Операция транзакции А в
момент t2 (извлечение на рис. 15.7 и обновление на рис. 15.8) выполнена не будет. Суть
в том, что она сопровождается выдачей неявного запроса на блокировку кортежа t и этот
запрос вступает в конфликт с Х-блокировкой, уже установленной для данного кортежа
транзакцией В. В результате транзакция А будет переведена в состояние ожидания, про-
должающееся до тех пор, пока выполнение транзакции В не будет закончено (до фикса-
ции или отката транзакции В). При этом установленная транзакцией В блокировка будет
572
Часть IV. Управление транзакциями
снята и транзакция А сможет продолжить свое выполнение. Причем теперь транзакция А
будет иметь дело уже с некоторым зафиксированным значением (либо существовавшим
до начала выполнения транзакции В в случае ее отката, либо полученным после выпол-
нения транзакции В). В любом случае транзакция А больше не зависит от незафиксиро-
ванных результатов выполнения параллельной транзакции.
Транзакция А Время Транзакция В
— Ф tl Обновление кортежа t
— 4 1 (установка Х-блокировки для t)
Извлечение кортежа t ф t2 —
(установка S-блокировки для t) 4 —
Ожидание 4 —
Ожидание t3 Окончание или отмена выполнения
Ожидание Итог: извлечение кортежа t (установка S-блокировки для t) 4 t4 4 4 (отмена Х-блокировки для t)
Рис. 15.7. Транзакция А не может получить доступ к незафиксированным результатам
изменения кортежа t в момент t2
Транзакция А Время Транзакция В
— 4 4 tl Обновление кортежа t
— 4 1 (установка Х-блокировки для t)
Обновление кортежа t ф t2 —
(установка Х-блокировки для t) 4 —
Ожидание 4 —
Ожидание t3 Окончание или отмена выполнения
Ожидание Итог: обновление кортежа t (установка Х-блокировки для t) 4 t4 4 4 (отмена Х-блокировки для t)
Рис. 15.8. Транзакция А не может обновить незафиксированный результат изменения
кортежа t в момент t2
Проблема несогласованной обработки данных
На рис. 15.9 приведена измененная версия примера, представленного на рис. 15.4. В новой
версии чередование операций транзакций осуществляется в соответствии с протоколом бло-
кировки, описанным в разделе 15.3. Операция обновления транзакции В в момент t6 выпол-
нена не будет. Причина в том, что она предусматривает неявный запрос на установку X-
блокировки для кортежа АСС 1, который вступает в конфликт с S-блокировкой этого кортежа,
уже установленной транзакцией А. В результате транзакция В переводится в состояние ожида-
Глава 15. Параллельность
573
ния. Аналогично этому операция выборки транзакции А в момент t7 также выполнена не бу-
дет. Суть в том, что она сопровождается выдачей неявного запроса на установку S-
блокировки для кортежа АСС 3, а этот запрос вступает в конфликт с Х-блокировкой, уже уста-
новленной для данного кортежа транзакцией В. В результате транзакция А также переводится
в состояние ожидания. Можно сделать вывод, что хотя механизм блокировки и помогает ре-
шить исходную проблему (а именно — проблему несогласованной обработки данных), одно-
временно он приводит к возникновению другой проблемы (а именно — проблемы взаимной
блокировки, которая обсуждается в следующем разделе).
АСС 1 АСС 2 АСС 3
40 50 30
Транзакция А Время Транзакция В
Извлечение кортежа АСС 1: Ф Ф tl
(установка S-блокировки для Ф —
кортежа АСС 1) Ф —
sum = 40 Ф 1 —
Извлечение кортежа АСС 2: 4- t2 —
(установка S-блокировки для Ф —
кортежа АСС 2) Ф —
sum =90 Ф 1 —
— ф t3 Извлечение кортежа АСС 3:
— ф (установка S-блокировки для
— ф кортежа АСС 3)
— ф —
— t4 Обновление кортежа АСС 3:
— Ф (установка Х-блокировки для
— Ф кортежа АСС 3)
— Ф 1 30 -> 20
— ф t5 Извлечение кортежа АСС 1:
— Ф (установка S-блокировки для
— Ф 1 кортежа АСС 1)
— ф t6 Обновление кортежа АСС 1:
— Ф (установка Х-блокировки для
— Ф кортежа АСС 1)
— Ф Ожидание
Извлечение кортежа АСС 3: t7 Ожидание
(установка S-блокировки для Ф Ожидание
кортежа АСС 3) Ф Ожидание
Ожидание Ф Ожидание
Ожидание Ф Ожидание
Рис. 15.9. Проблема несогласованной обработки данных устраняется, но в .мо.мент t7
возникает другая проблема — взаимная блокировка
/
574
Часть IV. Управление транзакциями
15.5. Взаимная блокировка
Как было показано выше, механизм блокировки можно использовать для разрешения
трех основных проблем, возникающих при параллельной обработке кортежей транзак-
циями. К сожалению, использование блокировок приводит к возникновению другой про-
блемы — взаимной блокировке транзакций. Выше были приведены два примера по-
добных ситуаций. На рис. 15.10 показана обобщенная схема возникновения данной про-
блемы, на которой rl и г2 представляют любые блокируемые объекты, необязательно
являющиеся кортежами базы данных (подробности приводятся в разделе 15.8), а выра-
жения типа “блокировка... без совместного доступа” обозначают любые операции уста-
новки блокировки (без совместного доступа), заданные как явно, так и неявно.
Транзакция А Время Транзакция В
— 4 —
— 4 —
Блокировка rl без совместного tl —
доступа г —
— 4 —•
— t2 Блокировка г2 без совместного
— 4 доступа
—• 4 —
Блокировка г2 без совместного t3 —
доступа 4 —
Ожидание 4 —
Ожидание t4 Блокировка rl без совместного
Ожидание 4 доступа
Ожидание 4 Ожидание
Ожидание 4 Ожидание
Рис. 15.10. Схема возникновения взаимной блокировки
Взаимная блокировка имеет место в том случае, когда две или более транзакций од-
новременно находятся в состоянии ожидания, причем для продолжения работы каждая
из них ожидает прекращения выполнения другой транзакции3. На рис. 15.10 показана
взаимная блокировка для двух транзакций, однако, в принципе, возможны ситуации вза-
имной блокировки с участием трех, четырех и более транзакций. Тем не менее прове-
денные с системой System R эксперименты показали, что на практике ситуации взаимной^
блокировки с участием более двух транзакций почти никогда не встречаются [15.4]. 7
Желательно, чтобы при возникновении взаимной блокировки система могла обнару-
жить ее и найти из нее выход. Для обнаружения ситуации взаимной блокировки следует
организовать поиск замкнутых петель в графе ожидания (т.е. в графе, представляющем
транзакции, которые ожидают окончания выполнения других транзакций; см. упр. 15.4).
Устранение взаимной блокировки заключается в выборе одной из участвующих 1в ней
транзакций (т.е. той, которая входит в состав петли на графе ожидания) в качестве жерт-
вы и ее откате. В результате будут сняты все установленные ею блокировки и выполне-
ние других транзакций можно будет продолжить.
^Иногда в литературе ситуация взаимной блокировки упоминается под названием “тупико-
вая ситуация ”.
Глава 15. Параллельность
575
Замечание. На практике не все существующие системы контролируют появление
именно ситуаций взаимных блокировок. Например, в некоторых из них организуется
простой хронометраж выполнения транзакций и решение о возникновении ситуации вза-
имной блокировки принимается в каждом случае, когда транзакция не завершает свою
работу в пределах некоторого заранее предписанного ей интервала времени.
Обратите внимание, что транзакция-жертва признается “неудачной” и ее откат вы-
полняется не по ее собственной вине. В одних системах предусмотрен автоматический
перезапуск этой транзакции в предположении, что обстоятельства, которые привели к
возникновению взаимной блокировки, вновь не повторятся. В других системах в про-
грамму, связанную с остановленной транзакцией, просто посылается сообщение об
имевшей место ситуации взаимной блокировки, после чего вся остальная обработка
ошибки возлагается на саму эту программу. С точки зрения прикладного программиста,
первый из подходов, безусловно, предпочтительнее. Тем не менее решать данную про-
блему всегда рекомендуется, учитывая точку зрения пользователя.
15.6. Упорядочиваемость
В предыдущих разделах были описаны основные положения, необходимые для объ-
яснения ключевого понятия упорядочиваемость (serializability), под которым понимает-
ся некий обобщенный критерий правильности выполнения заданного набора транзак-
ций. Согласно этому критерию выполнение заданного множества транзакций считается
корректным, если оно является упорядоченным, т.е. если при его выполнении будет по-
лучен такой же результат, как и при последовательном выполнении этих же транзакций.
Ниже приведено обоснование данного утверждения.
1. Отдельные транзакции считаются корректными, если при их выполнении база дан-
ных переходит из одного непротиворечивого состояния в другое непротиворечивое
состояние.
2. Значит, последовательное выполнение транзакций в некотором произвольном по-
рядке также является корректным. Порядок выполнения транзакций может быть
произвольным, поскольку отдельные транзакции независимы одна от другой.
3. Чередующееся выполнение операций отдельных транзакций также можно считать
корректным, если полученные результаты будут эквивалентны тем, которые были
бы достигнуты при последовательном выполнении этих же транзакций; в таком
случае данная последовательность операций считается упорядоченной.
Возвращаясь к приведенным выше примерам из раздела 15.2 (см. рис. 15.1-15.4), мож-
но отметить следующее: проблема в каждом случае заключалась в том, что чередующееся
выполнение операций отдельных транзакций не было упорядочено, т.е. не было эквива-
лентно выполнению либо сначала транзакции А, а затем транзакции В, либо сначала тран-
закции В, а затем транзакции А. Основной смысл предложенного выше механизма блоки-
ровки заключался в принудительном обеспечении упорядоченности. На рис. 15.7 и 15.8 че-
редование выполняющихся операций эквивалентно выполнению сначала транзакции В, а
затем транзакции А. На рис. 15.6 и 15.9 показана ситуация взаимной блокировки, для устра-
нения которой следует отменить одну из двух транзакций с последующим ее перезапуском.
Если отменить транзакцию А, чередование выполнения операций вновь станет эквивалент-
ным выполнению сначала транзакции В, а затем транзакции А.
576
Часть IV. Управление транзакциями
Терминология. Для заданного набора транзакций любой порядок выполнения их опе-
раций (чередующийся или какой-либо иной) называется графиком запуска. Выполне-
ние транзакций по одной без чередования их операций называется последовательным
графиком, а любой другой порядок выполнения— чередующимся или непоследова-
тельным графиком. Два графика называются эквивалентными, если при их выполнении
будет получен один результат, независимо от исходного состояния базы данных. Таким
образом, график запуска является корректным (т.е. упорядоченным), если он эквивален-
тен некоторому последовательному графику запуска.
Необходимо подчеркнуть, что при выполнении двух разных последовательных гра-
фиков запуска одного и того же набора транзакций, в принципе, можно получить совер-
шенно разные результаты. Поэтому и выполнение двух различных чередующихся графи-
ков для этого набора транзакций может привести к различным результатам, которые, тем
не менее, будут восприняты, как корректные. Предположим, например, что транзакция А
содержит операцию “добавить 1 к х”, а транзакция В — “удвоить значение х” (где х —
некоторый элемент базы данных). Допустим также, что начальное значение х равно 10.
Тогда при последовательном выполнении сначала транзакции А, а затем транзакции В
будет получен результат х=22, а при последовательном выполнении сначала транзакции
В, а затем транзакции А, будет получен результат х=21. Оба результата являются одина-
ково верными, а любой график запуска, эквивалентный выполнению либо сначала тран-
закции А, а затем транзакции В, либо сначала транзакции В, а затем транзакции А, также
будет верным (см. упр. 15.3).
Концепция упорядочиваемости впервые была предложена Есвараном (Eswaran) в
[15.5] (хотя и под другим названием). В его работе также доказана важная теорема, по-
лучившая название теорема двухфазной блокировки4. Кратко ее можно сформулиро-
вать следующим образом.
Если выполнение всех транзакций подчиняется протоколу двухфазной блокиров-
ки, то все возможные чередующиеся графики запуска этих транзакций будут
упорядоченными.
При этом требования, выдвигаемые протоколом двухфазной блокировки, заклю-
чаются в следующем.
1. До выполнения каких-либо операций с некоторым объектом (например, с кортежем
базы данных) транзакция должна блокировать этот объект.
2. После первого же снятия блокировки некоторого объекта транзакция теряет право
устанавливать какие-либо новые блокировки.
В соответствии с требованиями этого протокола выполнение любой транзакции
должно включать две последовательные фазы: фазу установки блокировок (фазу роста) и
фазу снятия блокировок (фазу сжатия).
Замечание. На практике вторая фаза часто сводится к единственной операции фикса-
ции (или отката) в конце транзакции. Поэтому протокол блокировки, описанный выше, в
разделе 15.3, можно рассматривать как строго соответствующий определению двухфаз-
ного протокола.
4 Двухфазная блокировка не имеет ничего общего с двухфазной фиксацией.
Глава 15. Параллельность
577
Понятие упорядочиваемости существенно облегчает понимание этой довольно запутанной
области знаний. В дополнение к уже сказанному следует добавить еще несколько коммента-
риев. Пусть I является чередующимся графиком, включающим некоторый набор транзакций
Tl, Т2, ..., Тп. Если I является упорядоченным графиком, то существует некоторый последо-
вательный график S, включающий тот же набор транзакций Tl, Т2,..., Тп, такой, что график I
будет эквивалентен графику S. В этом случае график S называется упорядочением графика Е.
Как уже было показано ранее, график S необязательно является уникальным, т.е. некоторый
чередующийся график I может иметь несколько упорядочений.
Пусть Ti и Т j — некоторые транзакции из множества транзакций Tl, Т2, ..., Тп. Не теряя
общности рассуждений, предположим, что в упорядочении S транзакция Ti предшествует
транзакции Tj. Следовательно, чередующийся график запуска I должен иметь такой эффект,
как если бы транзакция Ti выполнялась перед транзакцией Tj. Иначе говоря, неформальная,
но очень полезная характеристика упорядочиваемости может быть выражена следующим об-
разом. Если А и В являются двумя произвольными транзакциями некоторого упорядоченного
графика запуска, то либо транзакция А логически предшествует транзакции В, либо транзакция
В логически предшествует транзакции А. Иначе говоря, либо транзакция В имеет доступ к
результатам выполнения транзакции к, либо транзакция А имеет доступ к результатам
выполнения транзакции В. (Если в транзакции А выполняется обновление кортежей р, q,
..., г и транзакция В использует эти кортежи в качестве входных данных, то либо все доступ-
ные ей кортежи будут обновлены транзакцией А, либо все доступные ей кортежи будут нахо-
диться в том состоянии, в котором они были до выполнения транзакции А, т.е. транзакция В
никогда не сможет иметь доступ к “смеси” кортежей в разных состояниях.) И наоборот, если
результат выполнения транзакций не соответствует тем результатам, которые были бы полу-
чены при последовательном выполнении транзакции А, а затем транзакции В, либо при после-
довательном выполнении транзакции В, а затем транзакции А, то данный график является не-
упорядоченным и, следовательно, неверным.
В заключение стоит подчеркнуть, что если выполнение некоторой транзакции А не являет-
ся двухфазным (т.е. не удовлетворяет требованиям протокола двухфазной блокировки), то
всегда можно построить другую транзакцию В, которая при чередующемся выполнении с
транзакцией А приведет к графику запуска, который не будет упорядоченным, и потому будет
неверным. В настоящее время для снижения требований к используемым ресурсам и, следо-
вательно, повышения производительности и пропускной способности системы в реальных
СУБД обычно допускается применение не двухфазных транзакций, а транзакций с “ранним
снятием блокировки” (выполняемым до фиксации транзакции) с последующей установкой
дополнительных блокировок. Однако необходимо понимать, что использование таких тран-
закций сопряжено с большим риском. Действительно, при выполнении транзакции А по про-
токолу, отличному от двухфазного, предполагается, что в системе в текущий момент не суще-
ствует никакой другой чередующейся с ней транзакции В, обращающейся к тем же самым
данным (в противном случае в системе возможно получение ошибочных результатов).
15.7. Уровни изоляции
Грубо говоря, термин уровень изоляции используется для описания степени вме-
шательства параллельно выполняющихся транзакций в работу некоторой заданной
транзакции. Однако для гарантированной упорядоченности используемых графиков за-
578
Часть IV. Управление транзакциями
пуска нельзя допускать никакого постороннего вмешательства! Иначе говоря, уровень
изоляции должен быть максимальным. Тем не менее, как уже отмечалось в конце преды-
дущего раздела, в реальных системах по различным причинам обычно допускаются
транзакции, которые работают на уровне изоляции ниже максимального.
Замечание. Уровень изоляции обычно рассматривается как некоторое свойство тран-
закции. В действительности нет никаких причин, по которым транзакция в одно и то же
время не могла бы работать с различными уровнями изоляции для разных частей базы
данных. Однако из соображений простоты здесь уровень изоляции будет рассматривать-
ся всего лишь как некоторое свойство транзакции.
Теоретически можно определить по крайней мере пять уровней изоляции. Однако в [15.9],
а также в стандарте языка SQL их всего четыре, тогда как СУБД DB2 фирмы IBM поддержи-
вает только два уровня. Вообще говоря, чем выше уровень изоляции, тем меньше степень
возможного взаимного влияния транзакций (и ниже уровень параллельности), и чем ниже
уровень изоляции, тем больше степень возможного взаимного влияния транзакций (и выше
уровень параллельности работ в системе). В качестве примера рассмотрим два уровня изоля-
ции, поддерживаемых СУБД DB2. Они называются уровнями стабильности курсора и по-
вторяемости считывания. Уровень повторяемости считывания (ПС) является максималь-
ным уровнем изоляции; причем если все транзакции выполняются на этом уровне, то графики
запуска являются упорядоченными (выше в настоящей главе по умолчанию полагалось, что
все транзакции выполняются именно на этом уровне изоляции). Уровень стабильности кур-
сора (СК) для транзакции Т1 характеризуется следующими особенностями:
транзакция адресуется некоторому кортежу t5;
это действие сопровождается установкой блокировки для кортежа t;
адресуемость кортежу t отменяется без его обновления;
в результате уровень Х-блокировки не достигается;
подобная блокировка может быть снята без необходимости ожидания окончания
выполнения транзакции.
Обратите внимание, что в этом случае другая транзакция Т2 уже сможет выполнить
обновление кортежа t и зафиксировать изменения. Если транзакция Т1 вновь обратится к
кортежу t, эти изменения окажутся ей доступны, что в конечном счете может вызвать
перевод базы данных в противоречивое состояние. В противоположность этому при ис-
пользовании уровня изоляции ПС все блокировки кортежей (а не только Х-блокировки)
должны сохраняться до окончания выполнения транзакции, поэтому упомянутой выше
проблемы не возникает.
Здесь следует сделать важные дополнения.
1 . Описанная проблема — не единственная из числа проблем, которые могут возникнуть
на уровне изоляции СК; просто ее легче всего объяснить. Однако она, к сожалению, по-
зволяет сделать вывод, что уровень изоляции ПС необходим только в тех сравнительно
5 Эта операция выполняется посредством установки курсора в положение, соответствую-
щее требуемому кортежу (подробнее об этом речь шла в главе 4); отсюда и название уровня
изоляции: ‘‘уровень стабильности курсора”. Следует уточнить, что в СУБД DB2 блокировка Т1,
установленная для кортежа t, является блокировкой для обновления (U-блокировкой), а не разде-
ляемой блокировкой (S-блокировкой) [4.20].
Глава 15. Параллельность
579
маловероятных случаях, когда данная транзакция дважды обращается к одному и тому
же кортежу. Тем не менее существуют весомые аргументы в защиту повсеместного ис-
пользования уровня изоляции ПС вместо уровня СК. Дело в том, что выполнение тран-
закции на уровне СК не является двухфазным, а потому (как разъяснялось в предыду-
щем разделе) упорядоченность используемых в этом случае графиков не гарантируется.
В качестве контраргумента следует указать тот факт, что на уровне изоляции СК в рабо-
те системы достигается более высокий уровень параллельности в сравнении с уровнем
изоляции ПС (такая ситуация возможна, но вовсе не обязательна).
2 . Реализация, поддерживающая любой иной уровень изоляции, кроме максимально-
го, обычно включает те или иные средства явного управления уровнем параллель-
ности. Обычно для этого используется явное указание операторов блокировки
LOCK, что позволяет разработчикам создавать свои приложения таким образом,
чтобы гарантировать необходимую безопасность и при отсутствии гарантий со
стороны самой системы. Например, в СУБД DB2 для этого предусмотрен оператор
LOCK TABLE, который позволяет в приложениях с уровнем изоляции СК выполнить
явную установку эксклюзивной блокировки данных, помимо тех блокировок, кото-
рые система DB2 автоматически устанавливает для принудительного достижения
этого уровня. (Обратите внимание, что в стандарте SQL нет никаких механизмов
явного управления параллельностью; см. раздел 15.9.)
В заключение следует отметить, что предшествующая характеристика уровня повто-
ряемости считывания как уровня максимальной изоляции относится только к реализации
уровня ПС в СУБД DB2. К сожалению, в стандарте языка SQL тот же термин,
“повторяемость считывания”, используется для описания уровня изоляции, который на-
ходится ниже максимального уровня (см. раздел 15.9).
15.8. Блокировка намерения
До сих пор в этой главе предполагалось, что блокировке подвергается отдельный
кортеж. Однако, в принципе, не существует никаких ограничений на блокировку боль-
ших или меньших единиц данных, например всей переменной-отношения, всей базы
данных или (пример противоположного характера) отдельного атрибута внутри заданно-
го кортежа. Уровень блокируемых объектов определяется степенью детализации бло-
кировки [15.9], [15.10]. Как обычно, здесь наблюдается компромисс между степенью
детализации и параллельностью: чем мельче объекты детализации, тем выше уровень
параллельности в системе; чем крупнее объекты детализации, тем меньше блокировок
можно будет установить, а значит потребуется контролировать. В результате снизятся
соответствующие накладные расходы (т.е. потребуется меньше необходимых действий).
Например, если транзакция устанавливает Х-блокировку для всей переменной-
отношения в целом, нет необходимости устанавливать Х-блокировки для отдельных кор-
тежей этой переменной-отношения, что в результате приводит к уменьшению общего
количества установленных блокировок. С другой стороны, никакая другая параллельно
выполняющаяся транзакция не сможет установить никаких других блокировок для этой
переменной-отношения или ее кортежей.
Предположим, что транзакция Т устанавливает Х-блокировку для некоторой пере-
менной-отношения R. Получив от транзакции Т подобный запрос, система должна быть
способна проверить наличие блокировок, установленных ранее другими транзакциями
580
Часть IV. Управление транзакциями
для любых кортежей этой переменной-отношения R. И если хотя бы одна подобная бло-
кировка была установлена, то запрос транзакции Т выполнить в данный момент будет
невозможно. Но как система сможет обнаружить конфликт такого рода? Очевидно, что
крайне нежелательно проверять в каждом из кортежей переменной-отношения R наличие
установленной для него блокировки со стороны какой-либо другой транзакции. Не менее
нежелательна и тотальная проверка всех установленных в системе блокировок, не явля-
ется ли какая-то из них блокировкой некоторого кортежа отношения R. Вместо этого
можно ввести еще один протокол, а именно — протокол блокировки намерения, в со-
ответствии с которым, прежде чем транзакции будет разрешено запросить установку
блокировки для кортежа, она должна будет установить блокировку (называемую блоки-
ровкой намерения^ подробности приводятся ниже) на всю переменную-отношение, в ко-
торой этот кортеж находится. Тогда обнаружить рассмотренную выше конфликтную си-
туацию будет значительно проще, поскольку проверку существования блокировок кор-
тежей можно будет выполнять на уровне переменных-отношений.
Как уже упоминалось, установка X- и S-блокировок имеет смысл как для отдельных
кортежей, так и для переменных-отношений в целом. В соответствии с [15.8] и [15.9] мож-
но ввести три типа блокировки намерения, которые имеют смысл для переменных-
отношений в целом, но не для отдельных кортежей: разделяемая блокировка намерения
(Intent Shared — IS), эксклюзивная блокировка намерения (Intent exclusive — IX) и раз-
деляемая эксклюзивная блокировка намерения (Shared Intent exclusive — SIX). Ниже
приводятся неформальные определения всех этих видов блокировок (предполагается, что
транзакция Т устанавливает блокировку рассматриваемого типа для переменной-отношения
R), причем для полноты изложения приводятся также определения S- и Х-блокировок.
IS-блокировка. Транзакция Т намеревается установить S-блокировки для отдель-
ных кортежей переменной-отношения R, чтобы получить гарантию стабильности
состояния этих кортежей в процессе их обработки.
IX-блокировка. В дополнение к действиям, описанным выше в определении IS-
блокировки, транзакция Т сможет обновлять отдельные кортежи переменной-
отношения R и, следовательно, устанавливать для них Х-блокировки.
S-блокировка. Транзакция Т допускает параллельное считывание данных из пе-
ременной-отношения R, но запрещает их обновление. Сама транзакция Т не имеет
права обновлять какие-либо кортежи переменной-отношения R.
SIX-блокировка. В определении этой блокировки комбинируются возможности
S- и IX-блокировок, т.е. транзакция Т допускает параллельное считывание данных
из переменной-отношения R, но запрещает их обновление. В дополнение к этому
транзакция Т имеет право обновлять отдельные кортежи переменной-отношения R,
для которых устанавливаются Х-блокировки.
Х-блокировка. Транзакция Т не допускает никакого параллельного доступа к пе-
ременной-отношению R. Сама транзакция Т либо может, либо не может обновлять
произвольные кортежи переменной-отношения R.
Формальные определения этих пяти типов блокировки можно дать с помощью пред-
ставленной на рис. 15.11 матрицы совместимости, которая является расширенной верси-
ей матрицы, обсуждавшейся выше, в разделе 15.3.
Глава 15. Параллельность
581
X SIX IX S IS —
X N N N N N Y
SIX N N N N Y Y
IX N N Y N Y Y
S N N N Y Y Y
IS N Y Y Y Y Y
— Y Y Y Y Y Y
Рис. 15.11. Матрица совместимости, расширенная блокировками намерения
Теперь можно дать более точную формулировку протокола блокировки намерения.
1. Прежде чем некоторой транзакции будет разрешено сделать запрос на установку S-
блокировки для определенного кортежа, она должна установить либо IS-
блокировку, либо блокировку более сильного типа для той переменной-отношения,
в которой данный кортеж содержится.
2. Прежде чем некоторой транзакции будет разрешено сделать запрос на установку X-
блокировки для определенного кортежа, она должна установить либо IX-
блокировку, либо блокировку более сильного типа (см. ниже) для той переменной-
отношения, в которой данный кортеж содержится.
(Однако следует отметить, что это все еще далеко не полное определение. Подробности
можно найти в комментарии к [15.9].)
Упомянутое в приведенном выше определении понятие относительной силы блокиро-
вок можно пояснить с помощью диаграммы приоритетов, представленной на рис. 15.12.
Блокировка типа L2 называется более сильной (т.е. находится на диаграмме приоритета
выше) по отношению к блокировке типа L1 тогда и только тогда, когда в матрице совмес-
тимости для любой конфликтной ситуации (N), отмеченной в некоторой строке столбца
блокировки типа L1, пометка (N) присутствует в той же строке столбца блокировки типа L2
(см. рис. 15.11). Обратите внимание на то, что за-
прос установки блокировки, который отвергается
некоторым типом блокировки, обязательно будет
отвергнут и более сильным типом блокировки
(таким образом, неявно подразумевается, что всегда
можно использовать более сильные типы блокиров-
ки вместо того типа, который строго необходим в
данном конкретном случае). Обратите внимание, что
ни S-, ни IX-блокировки не являются более сильны-
ми по отношению одна к другой.
Стоит отметить, что на практике блокировки
уровня переменных-отношений, требуемые прото-
колом блокировки намерения, как правило, уста-
навливаются неявным образом. Например, для
транзакции, выполняющей только операции чте-
ния, система может неявно установить IS-блокировку для каждой переменной-
отношения, к которой данная транзакция обращается. Однако для транзакции обновле-
ния, вероятно, потребуется установить уже 1Х-блокировки. Тем не менее в системе также
должна быть предусмотрена возможность явной установки блокировок с помощью раз-
Рис. 15.12. Диаграмма приоритета
различных типов блокировки
582
Часть IV. Управление транзакциями
ного рода операторов блокировки (LOCK). Это позволит транзакциям в случае необходи-
мости явно устанавливать S-, X- и SIX-блокировки на уровне переменных-отношений.
Например, подобный оператор явной установки блокировок поддерживается СУБД DB2
(хотя это и не требуется стандартом языка SQL).
Наконец, необходимо сделать замечание о методе эскалации блокировок, который
реализован во многих системах и представляет собой попытку сбалансировать между со-
бой противоположные требования: поддержки высокого уровня параллельности обра-
ботки и снижения накладных расходов на управление блокировками. Основная идея за-
ключается в том, что когда система достигает некоторого заранее заданного порога, она
автоматически заменяет множество мелких блокировок одной крупной блокировкой.
Например, множество отдельных S-блокировок уровня кортежа могут быть заменены IS-
блокировкой той переменной-отношения, которой эти кортежи принадлежат. На практи-
ке такое решение часто оказывается весьма полезным.
15.9. Средства языка SQL
В стандарте языка SQL не предусмотрена явная поддержка каких-либо функций блоки-
ровки (фактически понятие блокировки в нем вообще не упоминается). Однако реализация
подобных средств необходима для получения гарантий исключения конфликтных ситуаций
между транзакциями, выполняющимися параллельно. Точнее говоря, требуется, чтобы об-
новления, выполняемые некоторой транзакцией Т1, не были доступны любой другой транзак-
ции Т2 до тех и обязательно до тех пор, пока не будет завершено выполнение транзакции Т1.
Фиксация транзакции открывает доступ ко всем обновлениям, выполненным данной транзак-
цией. Откат транзакции приводит к тому, что все выполненные ею обновления отменяются.
Замечание. Сказанное выше относится к случаю, когда все транзакции выполняются
на уровне изоляции READ COMMITTED (чтение зафиксированного), REPEATABLE READ
(повторяемое чтение) и SERIALIZABLE (упорядочиваемость). К транзакциям, выполняе-
мым на уровне изоляции READ UNCOMMITTED (чтение незафиксированного), применяются
особые соглашения, допускающие “некорректное чтение” (об этом речь идет ниже), но
только в режиме READ ONLY (только чтение); подробности приводятся в главе 14.
Уровни изоляции
В главе 14 уже упоминался оператор языка SQL SET TRANSACTION, предназначенный
для указания определенных характеристик запускаемой на выполнение транзакции. Од-
ной из таких характеристик является уровень изоляции. Существуют следующие уровни
изоляции: READ COMMITTED (чтение зафиксированного), REPEATABLE READ (повторяемое
чтение) и SERIALIZABLE (упорядочиваемость)6. По умолчанию устанавливается уровень
SERIALIZABLE, однако, если задан один из трех остальных уровней, при реализации все-
гда можно использовать более высокий уровень, где выражение “более высокий” подра-
зумевает следующее соотношение уровней: SERIALIZABLE > REPEATABLE READ > READ
COMMITTED > READ UNCOMMITTED.
6 В данном случае ключевое слово SERIALIZABLE является не совсем удачным, поскольку
этот термин подразумевает упорядочиваемость графиков запуска, а не транзакций. Более удач-
ным был бы вариант TWO PHASE, который означает выполнение транзакции (возможно, прину-
дительное) в соответствии с требованиями протокола двухфазной блокировки.
Глава 15. Параллельность
583
Если все транзакции выполняются на уровне изоляции SERIALIZABLE (принимаемом
по умолчанию), то график выполнения любого множества параллельных транзакций с
чередованием их операций будет гарантированно упорядоченным. Однако если некото-
рая транзакция выполняется на более низком уровне изоляции, то упорядоченность гра-
фика может быть нарушена самыми разными способами. В данном стандарте указаны
три особых случая нарушения упорядочиваемости.
Некорректное чтение. Допустим, что транзакция Т1 обновила данные в некото-
рой строке, затем транзакция Т2 считала эту строку, после чего был выполнен от-
кат транзакции Т1. В результате транзакция Т2 будет работать с данными, которые
больше не существуют и в определенном смысле никогда не существовали
(поскольку в действительности транзакция Т1 так и не была выполнена).
Неповторяемое чтение. Допустим, что транзакция Т1 считывает некоторую стро-
ку, затем транзакция Т2 ее обновляет, после чего транзакция Т1 вновь считывает
эту же строку. В результате транзакция Т1 считает два совершенно разных значе-
ния одной и той же строки.
Чтение фантомов. Допустим, что транзакция Т1 считывает множество всех
строк, удовлетворяющих некоторому заданному условию (например, строки всех
поставщиков из Парижа). Допустим также, что транзакция Т2 вставляет в таблицу
новую строку, которая удовлетворяет этому же условию. Если транзакция Т1
вновь повторит ту же операцию выборки, что и раньше, то ею будет обнаружена
ранее отсутствовавшая строка — “фантом” (phantom).
Различные уровни изоляции определяются в терминах приведенных выше случаев
нарушения упорядоченности. Соответствующие определения схематически представле-
ны на рис. 15.13.
Уровень изоляции Некорректное чтение Неповторяемое чтение Чтение фантомов
READ UNCOMMITTED Y Y Y
READ COMMITTED N Y Y
REPEATABLE READ N N Y
SERIALIZABLE N N N
Рис. 15.13. Уровни изоляции языка SQL
Возникает очевидный вопрос: “Каким же образом система сможет предотвратить по-
явление фантомов?”. Для этого в ней должна быть предусмотрена блокировка пути дос-
тупа к данным. Если в приведенном выше примере с поставщиками из Парижа путем
доступа к данным служит индекс по городам поставщиков, то система должна будет за-
блокировать строку этого индекса, относящуюся к Парижу. Благодаря такой блокировке
фантомы возникнуть не смогут, поскольку для их появления потребуется обратиться к
данному пути доступа (т.е. в приведенном примере — к конкретному значению индекса).
Более подробно этот вопрос рассматривается в [14.12].
В заключение следует повторить, что определения уровня изоляции REPEATABLE
READ в стандарте языка SQL и в СУБД DB2 являются совершенно разными. На самом
деле уровню REPEATABLE READ в СУБД DB2 соответствует уровень SERIALIZABLE в
стандарте языка SQL.
584
Часть IV. Управление транзакциями
15.10. Резюме
В этой главе описывались способы управления параллельностью. Вначале рас-
сматривались три проблемы, возникающие из-за отсутствия такого управления при чере-
дующемся выполнении параллельных транзакций, а именно: потеря результатов об-
новления, зависимость от незафиксированных результатов и несогласованная об-
работка данных. Все эти проблемы возникают из-за того, что график запуска не являет-
ся упорядоченным, т.е. он не эквивалентен некоторому последовательному графику за-
пуска этих же транзакций.
Наиболее распространенным методом разрешения указанных проблем является ис-
пользование механизма блокировки. Существует два основных типа блокировок: раз-
деляемая (S-блокировка) и эксклюзивная (Х-блокировка). Если транзакция устанав-
ливает S-блокировку для некоторого объекта, то другие транзакции также смогут ус-
тановить S-блокировку для этого же объекта, однако установить для него X-
блокировку им не удастся. Если одна транзакция устанавливает Х-блокировку для не-
которого объекта, то никакая другая транзакция не сможет установить для этого объ-
екта никакой другой блокировки. Специальный протокол использования этих блоки-
ровок позволяет устранить упомянутую выше проблему утраты результатов обновле-
ния и другие возможные проблемы. В соответствии с данным протоколом S-
блокировка устанавливается для всех считываемых объектов, а Х-блокировка— для
всех обновляемых объектов, причем все установленные блокировки сохраняются до
окончания выполнения транзакции. С помощью этого протокола можно обеспечить
упорядоченность графика выполнения транзакций.
Описанный протокол является более строгой (и более общей) формой протокола
двухфазной блокировки. В теореме двухфазной блокировки утверждается, что ес-
ли выполнение всех транзакций подчиняется этому протоколу, то любой из возмож-
ных графиков запуска будет упорядоченным. При построении такого графика запуска
гарантируется, что если А и В являются двумя транзакциями данного графика, то либо
транзакция А получит доступ к результатам выполнения транзакции В, либо транзакция
В получит доступ к результатам выполнения транзакции А. К сожалению, применение
протокола двухфазной блокировки способно привести к возникновению ситуации вза-
имной блокировки. Для ее устранения следует выбрать одну из конфликтующих
транзакций в качестве транзакции-жертвы и отменить ее с выполнением отката всех
внесенных ею изменений.
В общем случае нельзя гарантировать безопасность выполнения набора транзакций,
если используемый график не полностью упорядочен. Однако в некоторых системах для
повышения их производительности и пропускной способности предусмотрена возмож-
ность чередующегося выполнения нескольких транзакций с некоторым установленным
уровнем изоляции, что на самом деле является не совсем безопасным решением. В этой
главе был описан один такой “небезопасный уровень”, т.е. уровень стабильности кур-
сора (с точки зрения терминологии, принятой в СУБД DB2, хотя в стандарте языка SQL
аналогичный уровень называется READ COMMITTED).
Далее вкратце было рассмотрено понятие степень детализации блокировок и
связанная с ним идея блокировки намерения. Предполагается, что перед установ-
кой транзакцией блокировки определенного типа для некоторого элемента, напри-
мер для кортежа базы данных, ей следует установить соответствующую блокировку
Глава 15. Параллельность
585
намерения для “родительского” объекта этого элемента (в случае кортежа — для пе-
ременной-отношения, в которой кортеж содержится). На практике блокировки на-
мерения обычно устанавливаются так же, как S- и Х-блокировки кортежей, т.е. не-
явным образом. Однако рекомендуется предусмотреть оператор типа LOCK для яв-
ной установки (в случае необходимости) блокировок более сильных, чем те, кото-
рые устанавливаются системой неявно.
Наконец, в этой главе были кратко описаны средства управления параллельно-
стью, предусмотренные в языке SQL. В стандарте языка SQL средства явной уста-
новки блокировки не предусмотрены вовсе, однако в нем поддерживаются различ-
ные уровни изоляции (SERIALIZABLE, REPEATABLE READ, READ COMMITTED, READ
UNCOMMITTED), которые в СУБД обычно реализуются средствами неявного автома-
тического блокирования.
В заключение этой части книги следует сделать краткое замечание о важности
ограничений целостности. Корректность базы данных в широком понимании озна-
чает то, что она не противоречит никаким известным ограничениям целостности.
Отсюда понятно, что для системы без поддержки таких ограничений целостности не
имеет смысла говорить о корректности ее базы данных. В главе 14 уже шла речь о
том, что восстановление означает возврат к предыдущему корректному состоянию,
а в этой главе упоминалось о том, что параллельность (или, точнее, управление па-
раллельностью) означает, что при использовании упорядоченного графика запуска
база данных переводится каждой транзакцией из одного корректного состояния в
другое корректное состояние. Отсюда следует, что понятие целостности является
более фундаментальным, чем понятие восстановления или параллельности. Дейст-
вительно, понятие целостности имеет очень глубокий смысл даже в однопользова-
тельской системе.
Упражнения
15.1. Дайте определение понятия упорядочиваемости.
15.2. Дайте подробное описание:
а) протокола двухфазной блокировки;
б) теоремы двухфазной блокировки.
15.3. Пусть даны транзакции Tl, Т2 и ТЗ, которые выполняют следующие операции:
Т1 : добавить 1 к А;
Т2 : удвоить значение А;
ТЗ: вывести значение А на экран, а затем поместить в А значение 1
(здесь А — некоторый объект базы данных).
а) Допустим, что транзакции Tl, Т2 и ТЗ выполняются параллельно. Перечислите все
возможные результаты их выполнения, если начальное значение А равно нулю.
б) Допустим, что транзакции Tl, Т2 и ТЗ имеют показанную ниже внутреннюю
структуру.
586
Часть IV. Управление транзакциями
Т1 Т2 ТЗ
R1: Считать значение А в tl tl := tl + 1 U1: Поместить в А зна- чение tl R2: Считать значение А в t2 t2 := t2 * 2 U2: Поместить в А зна- чение t2 R3: Считать значение А в t3 Вывести значение t3 на экран U3: Поместить в А значе- ние 1
Сколько возможных графиков запуска существует, если эти транзакции выполня-
ются без каких-либо блокировок?
в) Существуют ли какие-либо чередующиеся графики запуска, которые для задан-
ного начального значения А {нуль) приводят к получению “корректного” ре-
зультата, но не допускают упорядочения?
г) Существуют ли какие-либо графики запуска, которые действительно допускают
упорядочение, но не могут быть реализованы, если все три транзакции подчи-
няются протоколу двухфазной блокировки?
15.4. Ниже приведена последовательность выполнения различных событий в графике
запуска с транзакциями Tl, Т2, И2 и объектами базы данных А, В, Н.
Время tO
Время tl (Tl) : RETRIEVE А ;
Время t2 (Т2) : RETRIEVE В ;
- (Tl) : RETRIEVE С ;
- (Т4) : RETRIEVE D ;
- (Т5) : RETRIEVE А ;
- (Т2) : RETRIEVE Е ;
- (Т2) : UPDATE Е ;
- (ТЗ) : RETRIEVE F ;
- (Т2) : RETRIEVE F ;
- (Т5) : UPDATE A ;
- (Т1) : COMMIT ;
- (Тб) : RETRIEVE A ;
- (Т5) : ROLLBACK ;
- (Тб) : RETRIEVE C ;
- (Тб) : UPDATE C ;
- (Т7) : RETRIEVE G ;
- (ТЗ) : RETRIEVE H ;
- (T9) : RETRIEVE G ;
- (T9) : UPDATE G ;
- (ТВ) : RETRIEVE E ;
- (Т7) : COMMIT ;
- (T9) : RETRIEVE H ;
- (ТЗ) : RETRIEVE G ;
- (Т10) : RETRIEVE A ;
- (T9) : UPDATE H ;
- (Тб) : COMMIT ;
- (ТП) : RETRIEVE C ;
Глава 15. Параллельность
587
(Т12) : RETRIEVE D
(Т12) : RETRIEVE С
(Т2) : UPDATE F ;
(Т11) : UPDATE С ;
(Т12) : RETRIEVE A
(Т10) : UPDATE A ;
(Т12) : UPDATE D ;
(Т4) : RETRIEVE G
Время tn .......
Предположим, что для выполнения оператора RETRIEVE R (считать R) требуется (в
случае успеха) установить S-блокировку для объекта R, а для выполнения операто-
ра UPDATE R (обновить R) требуется (в случае успеха) установить для объекта R X-
блокировку. Допустим, что все блокировки сохраняются до конца выполнения
транзакции. Возникнет ли ситуация взаимной блокировки к моменту tn?
15.5. Еще раз обратимся к проблемам параллельности, представленным на рис. 15.1-
15.4. Что произойдет в каждом из этих случаев, если все транзакции будут вы-
полняться на уровне изоляции “Повторяемость считывания”, а не на уровне
“Стабильность курсора”?
15.6. Дайте формальные и неформальные определения пяти типам блокировок: X, S, IX,
IS, SIX.
15.7. Сформулируйте понятие относительной силы блокировок и нарисуйте соответст-
вующую диаграмму их приоритета.
15.8. Сформулируйте определение протокола блокировки намерения, а также поясните
основное назначение этого протокола.
15.9. В стандарте языка SQL определяются три проблемы параллельности: некоррект-
ное чтение, неповторяемое чтение и чтение фантомов. Как они соотносятся с
тремя проблемами параллельности, описанными в начале этой главы (потери ре-
зультатов обновления, зависимости от незафиксированных результатов и несогла-
сованной обработки данных)?
15.10. Кратко опишите механизм реализации многовариантного протокола управления
параллельностью, обсуждаемого в комментарии к [15.1].
Список литературы
В этом списке следовало бы также упомянуть работы [14.2], [14.10] и особенно
[14.12] из главы 14.
15.1. Bayer R., Heller М., Reiser A. Parallelism and Recovery in Database Systems // ACM
TODS. — June, 1980. — 5, № 2.
Как уже говорилось в главе 14, новые прикладные области (например, проекти-
рование и разработка программного и аппаратного обеспечения) часто выдвига-
ют сложные требования к обработке данных, которые нельзя полностью удовле-
творить с помощью классических схем управления выполнением транзакций,
описанных в этой и предыдущей главах. Основная проблема заключается в том,
что сложные транзакции в этих прикладных областях могут продолжаться в те-
588
Часть IV. Управление транзакциями
чение часов или даже дней вместо нескольких миллисекунд, что типично для
большинства традиционных систем обработки данных. Это может привести к
следующим последствиям.
1 . Полный откат транзакции к самому началу может вызвать потерю слишком
большого объема уже проделанной работы, что совершенно неприемлемо.
2 . Использование обычных блокировок может иметь следствием появление чрез-
мерных задержек, вызванных ожиданием снятия блокировок требуемых эле-
ментов, что также неприемлемо.
В этой работе описывается один из методов устранения подобных недостатков (см.
также [15.7], [15.11]—[15.13], [15.17]), а именно— метод управления параллельно-
стью, называемый многовариантной блокировкой (multi-version locking; иначе
может называться многовариантным считыванием (multi-version read)), который
уже используется в нескольких программных продуктах. Основное преимущество
этого метода заключается в том, что операции считывания выполняются без выну-
жденного ожидания, т.е. любое количество операций считывания и одна операция
записи могут выполняться для одного и того же объекта одновременно. Точнее го-
воря, выполняются следующие правила.
Операция чтения всегда выполняется без задержки (как только что говорилось).
Операции чтения никогда не задерживают выполнение операций обновления.
Откат транзакций, выполняющих только чтение, не имеет смысла и никогда не
осуществляется.
Ситуация взаимной блокировки может возникнуть только между транзакциями
обновления.
Указанные преимущества особенно важны для распределенных систем (см. гла-
ву 20), в которых на выполнение обновления данных может потребоваться значи-
тельное время, а потому выполнение запросов, включающих только операции чте-
ния, может чрезмерно затянуться (и наоборот). Основную идею данного метода
можно сформулировать следующим образом.
Если транзакция Т2 пытается выполнить операцию считывания объекта, для ко-
торого в данный момент выполняется обновление в пределах транзакции Т1, то
транзакции Т2 предоставляется доступ к предварительно зафиксированному
варианту этого объекта. Такой вариант обычно хранится в каком-то особом
месте системы (как правило, в журнале регистрации) и предназначается для
восстановления последнего состояния системы.
Если транзакция Т2 пытается выполнить операцию обновления объекта, кото-
рый в данный момент считывается транзакцией Т1, то транзакции Т2 предос-
тавляется доступ к этому объекту, тогда как транзакции Т1 предоставляется
доступ к некоторому варианту этого объекта (который в действительности яв-
ляется предварительным вариантом).
Если транзакция Т2 пытается выполнить операцию обновления объекта, кото-
рый в данный момент обновляется транзакцией Т1, то транзакция Т2 переходит
Глава 15. Параллельность
589
в состояние ожидания7 (таким образом, как отмечалось выше, в системе может
возникнуть ситуация взаимной блокировки, для устранения которой потребует-
ся принудительный откат одной из транзакций).
Конечно, этот метод предусматривает наличие соответствующих элементов управ-
ления, необходимых для получения гарантий, что каждая транзакция всегда будет
иметь дело с непротиворечивым состоянием базы данных.
15.2. Berenson Н. et al. A Critique of ANSI SQL Isolation Levels // Proc. 1995 ACM
SIGMOD Int. Conf, on Management of Data. — San Jose, Calif., May, 1995.
В этой статье критически оценивается предпринятая в стандарте SQL попытка оха-
рактеризовать уровни изоляции на основе нарушений упорядочиваемости (см. раз-
дел 15.9). “[Эти] определения не способны должным образом охарактеризовать не-
сколько широко распространенных уровней изоляции, включая стандартные способы
реализации блокировок для упомянутых уровней.” В частности, в этой статье под-
черкивается, что данный стандарт не способен запретить некорректное считывание
(которое определяется, как вероятность того, что две транзакции, Т1 и Т2, смогут вы-
полнить обновление одной и той же строки до завершения какой-либо из них).
Похоже, что это действительно так, поскольку в данном стандарте некорректное
считывание не запрещено явным образом. Вот несколько перефразированных ци-
тат из этой работы.
“Выполнение параллельных транзакций на уровне изоляции SERIALIZABLE га-
рантированно является упорядоченным.” Иначе говоря, если все транзакции
выполняются на уровне изоляции SERIALIZABLE, в реализации требуется за-
претить операции некорректного считывания, поскольку они будут нарушать
упорядоченность графика.
“Четыре уровня изоляции гарантируют, что... никакие обновления не будут ут-
рачены.” Это утверждение на самом деле является лишь благим пожеланием,
поскольку сами определения четырех уровней изоляции не дают подобных га-
рантий. Однако оно указывает на то, что создатели стандарта предполагают за-
прещение операций некорректного считывания.
“Изменения, выполненные одной транзакцией, не могут быть восприняты дру-
гими транзакциями [за исключением транзакций на уровне READ UNCOMMITTED]
до тех пор, пока ее выполнение не будет зафиксировано.” Что в данном контек-
сте означает слово восприняты? Может ли транзакция обновить часть
“неаккуратно считываемых данных” без их “восприятия”?
Замечание. Все эти замечания взяты из работы [4.19].
15.3. Bernstein Р.А., Goodman N. Timestamp-Based Algorithms for Concurrency Control in
Distributed Database Systems 11 Proc. 6th Intern. Conf, on Very Large Data Bases. —
Montreal, Canada, October, 1980.
В работе рассматриваются некоторые методы управления параллельностью, в
основу которых положена не блокировка, а временные отметки. Основная идея
заключается в том, что если транзакция А начинает выполняться раньше тран-
7 Иначе говоря, конфликты могут происходить только между операциями обновления и для
их устранения используется механизм блокировки. Однако для устранения конфликтов, безуслов-
но, могут использоваться и другие методы, например временные отметки [15.3J.
590
Часть IV. Управление транзакциями
закции В, то система ведет себя так, как будто выполнение транзакции А полно-
стью завершилось еще до начала выполнения транзакции В (как это имеет место
в последовательном графике запуска). Таким образом, для транзакции А будут
недоступны любые обновления, выполняемые транзакцией В. Кроме того, она не
сможет обновить объект, уже считанный транзакцией В. Подобная схема управ-
ления может быть организована следующим образом. Для каждого запроса к ба-
зе данных система сравнивает временную отметку транзакции этого запроса с
временной отметкой транзакции, выполнившей последнее считывание или об-
новление запрашиваемого кортежа. В случае конфликта транзакция запроса мо-
жет быть перезапущена с новой временной меткой (так же, как и в случае с оп-
тимистическими методами [15.14]).
Как следует из заголовка этой работы, данная методика была изначально создана
в контексте распределенной системы (где использование блокировки сопряжено
с возникновением нежелательных накладных расходов из-за отправки сообще-
ний для проверки и установки блокировок). Однако такая методика почти навер-
няка не годится для нераспределенных систем. Кроме того, существует доста-
точно скептическое отношение к практичности ее использования даже для рас-
пределенных систем. Одной очевидной проблемой является то, что каждый кор-
теж должен содержать временную метку последней транзакции, которая считы-
вала данные этого кортежа (а также временную метку последней транзакции, ко-
торая обновляла данные этого кортежа). В таком случае подразумевается, что
каждая операция чтения становится операцией записи! Действительно, в [14.12]
утверждается, что такая схема на самом деле является частным случаем схем оп-
тимистического метода управления параллельностью [15.14], для которых, в
свою очередь, характерны собственные проблемы.
15.4. Biasgen M.W., Gray J.N., Mitoma М., Price T.G. The Convoy Phenomenon // ACM
Operating Systems Review. — April, 1979. — 13, № 2.
Проблема образования верениц возникает при использовании механизма блоки-
ровок для интенсивно применяемых элементов данных. Примером может служить
установка блокировки перед выполнением операции записи в журнал регистрации
в системах с приоритетным планированием.
Замечание. Здесь понятие планирования относится к проблеме распределения ма-
шинных циклов среди выполняемых транзакций, а не к чередованию операций, при-
надлежащих различным транзакциям, что обсуждалось ранее в настоящей главе.
Эта проблема может быть пояснена следующим образом. Пусть транзакция Т уста-
навливает блокировку некоторых интенсивно используемых элементов данных,
после чего выполнение этой транзакции прекращается системным планировщиком,
т.е. транзакция переходит в состояние ожидания, например из-за того, что время,
отведенное ей для выполнения, истекло. Такая ситуация способствует образованию
вереницы транзакций, каждая из которых ожидает продолжения своего выполне-
ния и уже успела установить блокировку некоторых элементов интенсивно исполь-
зуемых данных. Когда транзакция Т выйдет из подобного состояния ожидания, она
должна будет завершить обработку и снять блокировку используемых ею элемен-
тов данных. Однако именно из-за того, что заблокированными являются интенсив-
но используемые данные, велика вероятность того, что транзакция Т выйдет из со-
Глава 15. Параллельность
591
стояния ожидания слишком рано, еще до того, как другая транзакция завершит ра-
боту с другим требуемым транзакции Т элементом данных. Поэтому транзакция Т
не сможет продолжить выполнение своих операций и уже по собственной инициа-
тиве переведет себя в состояние ожидания.
Суть проблемы заключается в том, что в большинстве случаев (но не во всех) пла-
нирование является частью функций базовой операционной системы, а не СУБД,
поэтому оно организуется на основе совершенно других допущений. По наблюде-
ниям авторов этой работы однажды образовавшаяся вереница проявляет тенден-
цию к стабильности. В результате система оказывается в состоянии постоянного
“переполнения блокировками” и большинство машинных циклов затрачивается на
обработку переключений, а не на выполнение какой-либо полезной работы. В ка-
честве возможного решения этой проблемы, помимо замены способа планирова-
ния, можно предложить установку блокировок в произвольном порядке, а не на
основе схемы “первым поступил — первым обработан”.
15.5. Eswaran К.Р., Gray J.N., Lorie R.A., Traiger I.L. The Notions of Consistency and
Predicate Locks in a Data Base System // CACM. — November, 1976. — 19, № IL
В этой работе впервые предложено строгое теоретическое описание основ управ-
ления параллельностью.
15.6. Franaszek Р., Robinson J.T. Limitations on Concurrency in Transaction Processing //
ACM TODS. — March, 1985. — 10, № 1.
См. комментарий к [15.14].
15.7. Franaszek P., Robinson J.T., Thomasian A. Concurrency Control for High Contention
Environments // Ibid. — 1992. — 17, № 2.
В статье делается заявление, что в будущем системы обработки транзакций, веро-
ятно, будут обеспечивать гораздо большую степень параллельности, чем совре-
менные системы (по разным причинам). Поэтому в них будут гораздо чаще возни-
кать конфликтные ситуации на уровне данных. Затем авторы представляют
“несколько концепций управления параллельностью [без использования блокиров-
ки] и методов планирования транзакций, которые применимы к средам с большим
количеством конфликтных ситуаций”. Преимущества такого подхода подтвержда-
ются экспериментами с различными имитационными моделями.
15.8. Gray J.N. Experience with the System R Lock Manager. IBM San Jose Research
Laboratory internal memo, 1980.
Эта работа представляет собой набор заметок, а не законченную статью, причем
они в настоящее время уже несколько устарели. Тем не менее в ней содержится
несколько интересных утверждений.
Использование блокировок связано с накладными расходами в размере 10%
при работе с интерактивными транзакциями и в размере 1% при работе с пакет-
ными транзакциями.
Желательно поддерживать разные уровни детализация блокировок.
Приветствуется автоматическая эскалация уровня блокировок.
Ситуации взаимной блокировки очень редко возникают на практике и никогда
не включают более двух транзакций. Почти все ситуации взаимной блокировки
(97%) можно устранить с помощью U-блокировок, что и предусмотрено в
592
Часть IV. Управление транзакциями
СУБД DB2, но не в системе System R. (В определении предполагается, что U-
блокировки совместимы с S-блокировками, но не с другими U-блокировками и,
конечно, не с Х-блокировками. Более подробные сведения приводятся в [4.20].)
Уровень изоляции ПС (повторяемости считывания) более эффективен и безопа-
сен, чем уровень СК (стабильности курсора).
15.9. Gray J.N., Lorie R.A., Putzolu G.R. Granularity of Locks in a Large Shared Data Base // Proc.
1st Intern. Conf, on Very Large Data Bases. — Framingham, Mass., September, 1975.
В статье впервые описана концепция блокировки намерения. Как объясняется в
разделе 15.8, понятие “уровень детализации блокировок” относится к размеру бло-
кируемых объектов. Поскольку разные транзакции, очевидно, имеют разные ха-
рактеристики и требования, желательно, чтобы в системе существовал целый на-
бор различных уровней детализации (что, в принципе, реализовано во многих сис-
темах). В этой статье представлена методика воплощения нескольких уровней де-
тализации блокировок на основе механизма блокировки намерения.
Поскольку в данной главе было дано весьма упрощенное описание протокола
блокировки намерения, ниже он будет рассмотрен несколько подробнее. Во-
первых, стоит отметить, что блокируемыми объектами могут быть не только пе-
ременные-отношения и кортежи, как предполагалось прежде. Во-вторых, типы
блокируемых объектов могут в общем случае не обладать строгой иерархиче-
ской структурой. Присутствие индексов или других структур доступа будет лишь
означать, что систему объектов следует рассматривать как ориентированный
ациклический граф. Например, база данных поставщиков и товаров может со-
держать как хранимую переменную-отношение товаров Р, так и индекс, напри-
мер ХР, построенный для атрибута #Р этой переменной-отношением. Для выбор-
ки кортежей переменной-отношения Р следует открыть всю базу данных, а затем
либо перейти непосредственно к этому отношению и выполнить последователь-
ный поиск, либо использовать индекс ХР для прямого перехода к искомым кор-
тежам переменной-отношения Р. Таким образом, кортежи переменной-
отношения Р в этом графе имеют два “родительских” объекта, Р и ХР, для каждо-
го из которых “родительским” объектом является база данных.
Теперь формулировку этого протокола можно представить в более обобщенной форме.
При установке Х-блокировки для данного объекта для всех его дочерних объек-
тов неявным образом устанавливается Х-блокировка.
При установке S- или SIX-блокировки для данного объекта для всех его дочер-
них объектов неявным образом устанавливается S-блокировка.
Прежде чем транзакция сможет потребовать установить S- или IS-блокировку
для заданного объекта, она должна установить IS-блокировку (или более силь-
ную) по крайней мере для одного из его родительских объектов.
Прежде чем транзакция сможет потребовать установить Х-, IX- или SIX-
блокировку для заданного объекта, она должна установить IX-блокировку (или
более сильную) для всех родительских объектов этого объекта.
Прежде чем транзакция получит право отменить блокировку данного объекта,
она должна отменить все блокировки, установленные ею для дочерних объек-
тов данного объекта.
Глава 15. Параллельность
593
На практике использование этого протокола не сопровождается слишком больши-
ми накладными расходами, как это может показаться на первый взгляд, поскольку
в любой заданный момент транзакция, весьма вероятно, уже будет обладать почти
всеми необходимыми ей блокировками. Например, IX-блокировка для всей базы
данных, вероятно, будет установлена непосредственно во время инициализации
программы и эта блокировка будет сохраняться для всех транзакций, выполняемых
на протяжении всей работы данной программы.
15.10. Gray J.N., Lorie R.A., Putzolu G.R., Traiger I.L. Granularity of Locks and Degrees of
Consistency in a Shared Data Base // Proc. IFIP TC-2 Working Conf, on Modeling in
Data Base Management Systems (ed. G. M. Nijssen). — Amsterdam, Netherlands:
North-Holland; New York, N.Y.: Elsevier Science, 1976.
В статье впервые введено понятие уровня изоляции (под названием степень не-
противоречивости).
15.11. Harder Т., Rothermel К. Concurrency Control Issues in Nested Transactions H The
VLDB Journal. — January, 1993. — 2, № 1.
Как уже объяснялось в главе 14, несколькими различными авторами была предло-
жена идея вложенных транзакций. В этой статье предлагается соответствующий
набор протоколов блокировки для подобных транзакций.
15.12. Jordan J.R., Banerjee J., Batman R.B. Precision Locks // Proc. 1981 ACM SIGMOD int.
Conf, on Management of Data. — Ann Arbor, Mich., April-May, 1981.
Точная блокировка является схемой блокировки на уровне кортежей, которая га-
рантирует блокировку только нужных кортежей (для достижения упорядочиваемо-
сти), включая фантомы. На самом деле эта форма блокировки называется блоки-
ровкой предикатов [15.5]. Она основана на следующих действиях. Во-первых, на
проверке запросов на обновление с целью выяснения, удовлетворяет ли вставляе-
мый или удаляемый кортеж предыдущему запросу на выборку в некоторой парал-
лельной транзакции. Во-вторых, на проверке запросов на выборку с целью выясне-
ния, удовлетворяет ли вставляемый или удаляемый в некоторой параллельной
транзакции кортеж данному запросу на выборку. Эта схема не только элегантна, но
и, как заявляют ее авторы, обладает более высокой производительностью, чем
обычные методы (в которых блокируется чрезмерно много объектов).
15.13. Korth H.F., Speegle G. Formal Aspects of Concurrency Control in Long-Duration Transaction
Systems Using the NT/PV Model // ACM TODS. — September, 1994. — 19, № 3.
Как уже отмечалось в литературе (см., например, [14.3], [14.9], [14.15] и [14.16]),
упорядочиваемость часто рассматривается как чрезмерно строгое требование, ко-
торое накладывается на некоторые виды систем обработки транзакций, особенно в
новых прикладных областях, включающих взаимодействие с людьми, а значит, и
транзакции большой длительности. В данной статье представлена новая модель
обработки транзакций NT/PV (nested transactions with predicates and views), позво-
ляющая решить эти проблемы. В статье также показано, что стандартная модель
обработки транзакций с упорядочиванием является лишь частным случаем; после
дается определение “новых и более полезных классов корректности”. Здесь утвер-
ждается, что новая модель обеспечивает “необходимую основу для решения про-
блем, связанных с долговременными транзакциями”.
594
Часть IV. Управление транзакциями
15.14. Kung H.T., Robinson J.T. On Optimistic Methods for Concurrency Control // ACM
TODS. — June, 1981. — 6, № 2.
Схемы блокировки рассматриваются как пессимистические в случае, когда делает-
ся предположение (худшее из возможных) о том, что все данные, необходимые для
заданной транзакции, могут также потребоваться для параллельно выполняемой
транзакции, а поэтому их следует заблокировать. В оптимистических схемах (или
схемах сертификации или подтверждения) делается противоположное допущение
о том, что такие конфликтные ситуации весьма маловероятны. Поэтому в рассмат-
риваемых схемах допускается беспрепятственное выполнение всех транзакций. И
только во время фиксации проверяется наличие конфликтных ситуаций. Если та-
кие конфликты имели место, то вызвавшие их транзакции перезапускаются. Ника-
кие обновления не записываются в базу данных до успешного завершения проце-
дуры фиксации, поэтому при повторном запуске транзакций не требуется отменять
какие-либо операции обновления.
Позднее в [15.6] было показано, что при некоторых разумных предположениях оп-
тимистические методы демонстрируют некоторые присущие им преимущества по
сравнению с традиционными методами блокировки для некоторого уровня парал-
лельности (т.е. некоторого числа одновременно выполняемых транзакций), кото-
рый они способны поддерживать. Предполагается, что оптимистические методы
могут быть наиболее полезны в системах с большим количеством параллельных
процессоров. (В [14.12], наоборот, утверждается, что оптимистические методы в
общем случае на самом деле хуже методов блокировки в некоторых “горячих” си-
туациях, т.е. в ситуациях, когда объект данных обновляется очень часто и несколь-
кими различными транзакциями. Более подробную информацию о методах, эффек-
тивных при работе в подобных ситуациях, можно найти в [15.15].)
15.15. O’Neil Р.Е. The Escrow Transactional Method П ACM TODS.— December,
1986.— 11, №4.
Рассмотрим следующий весьма простой пример. Предположим, что в базе данных
содержится объект данных ТС, представляющий “имеющуюся на руках
наличность”, и допустим, что почти каждая транзакция в системе обновляет дан-
ные в объекте ТС с некоторым уменьшением их значения (соответствующим неко-
торому текущему платежу). Объект ТС представляет собой пример “горячей точ-
ки”, т.е. элемента базы данных, который используется большинством транзакций в
системе. Образно говоря, при традиционной блокировке “горячая точка” может
очень скоро превратиться в узкое место всей системы, а потому было бы весьма
неразумно использовать традиционную блокировку в таких ситуациях. Если на-
чальное значение ТС равно 10 миллионам долларов, а каждая отдельная транзакция
приводит к ее уменьшению в среднем на 10 долларов, то в целом может быть вы-
полнено около миллиона таких транзакций. Причем для этого потребовалось бы
выполнить в произвольном порядке около миллиона операций вычитания. В таком
случае действительно вовсе нет необходимости в использовании традиционной
блокировки для ТС. Вместо этого достаточно убедиться, что текущее значение дос-
таточно велико для успешного выполнения данной операции вычитания, а затем
выполнить обновление значения. (Если выполнение такой транзакции не будет ус-
пешно завершено, то последнюю операцию вычитания следует отменить.)
Глава 15. Параллельность
595
Метод депонирования применяется в ситуациях, подобных описанной выше,
т.е. когда обновления имеют некоторую конкретную, а не произвольную форму.
В такой системе должен быть определен особый вид оператора обновления
(например, “уменьшить на х тогда и только тогда, когда текущее значение боль-
ше, чем х”). В этом случае обновление можно было бы выполнить, помещая
уменьшенное значение х в некоторый третий объект-депонент, для его извлече-
ния оттуда в конце выполнения транзакции. Если транзакция фиксируется, из-
влеченное значение помещается в х, если же выполняется откат транзакции, вос-
станавливается исходное значение х.
В статье описывается несколько ситуаций, в которых можно использовать метод
депонирования. Одним из примеров коммерческого продукта, в котором поддер-
живается данный метод, является информационная система IMS Fast Path фирмы
IBM. Следует отметить, что этот метод может рассматриваться как особый случай
оптимистического управления параллельностью [15.14] (обратите внимание, одна-
ко, что именно специфичность, т.е. применение специальных операторов обновле-
ния, и является важнейшим условием).
15.16. Papadimitriou С. The Theory of Database Concurrency Control. — Rockville, Md.:
Computer Science Press, 1986.
Учебное пособие, в котором особое внимание уделяется формальной теории.
15.17. Salem К., Garcia-Molina G., Shands J. Altruistic Locking // ACM TODS.— March,
1994, — 19, № 1.
В этой статье предлагается расширение протокола двухфазной блокировки, в
соответствии с которым транзакция Т1, завершившая работу с заблокирован-
ным элементом данных (который не может быть разблокирован из-за ограни-
чений протокола двухфазной блокировки), все же “возвращает” этот элемент
системе, тем самым позволяя некоторой транзакции Т2 установить для него
блокировку. В этом случае говорят, что транзакция Т2 “идет вслед за” транзак-
цией Т1. Здесь определены протоколы, например сокрытия от транзакции об-
новлений, которые выполняются следующими за ней транзакциями. Показано,
что альтруистическая блокировка (этот термин происходит от того факта, что
“возвращение” данных приносит пользу другим транзакциям, а не транзакции-
донору) обеспечивает более высокую степень параллельности, чем обычный
протокол двухфазной блокировки, особенно когда некоторые из транзакций
продолжаются достаточно долго.
Ответы к некоторым упражнениям
15.3.
а) Существует шесть возможных корректных результатов, соответствующих шес-
ти возможным последовательным графикам запуска.
Исходно : А = О
Т1-Т2-ТЗ : А = 1
Т1-ТЗ-Т2 : А = 2
Т2-Т1-ТЗ : А = 1
596
Часть IV. Управление транзакциями
Т2-ТЗ-Т1 : A = 2
T3-T1-T2 : A = 4
T3-T2-T1 : A = 3
Конечно, не все шесть полученных результатов отличаются один от другого.
Фактически в данном примере так получилось потому, что благодаря природе
транзакции ТЗ возможные правильные результаты независимы от начального
состояния базы данных.
б) Существует 90 возможных графиков запуска, отличных один от другого, кото-
рые можно представить в приведенном ниже символическом виде. (Здесь Ri,
Rj, Rk обозначают операции извлечения Rl, R2, R3, причем необязательно в той
же последовательности. Аналогично Up, Uq, Ur обозначают операции обновле-
ния Ul, U2, U3, необязательно в той же последовательности.)
Ri-Rj-Rk-Up-Uq-Ur : 3 * 2 * 1 * 3 * 2 * 1 = 36 вариантов
Ri-Rj-Up-Rk-Uq-Ur : 3 * 2 * 2 * 1 * 2 * 1 = 24 вариантов
Ri-Rj-Up-Uq-Rk-Ur : 3 * 2 * 2 * 1 * 1 * 1 = 12 вариантов
Ri-Up-Rj-Rk-Uq-Ur : 3*1*2*1*2*1=12 вариантов
Ri-Up-Rj-Uq-Rk-Ur : 3 * 1 * 2 * 1 * 1 * 1 = 6 вариантов
Всего =90 вариантов
в) Да. Например, график запуска R1-R2-R3-U3-U2-U1 приводит к тому же ре-
зультату (единица) для заданного начального значения (нуль), что и два из
шести возможных последовательных графиков запуска. (Упражнение. Про-
верьте это утверждение.) Однако следует понимать, что “корректность” по-
лученного результата является всего лишь счастливой случайностью и след-
ствием того, что исходное значение было равно 0, а не какому-то другому
числу. В качестве примера обратной ситуации рассмотрите случай, когда ис-
ходное значение равно 10. Будет ли показанный выше график запуска давать
один из действительно корректных результатов? (Какими в этом случае бу-
дут действительно корректные результаты?) Если нет, то график запуска
R1-R2-R3-U3-U2-U1 не допускает упорядочения.
г) Да. Например, график запуска R1-R3-U1-U3—R2-U2 является упорядоченным (он
эквивалентен последовательному графику запуска Т1-Т2-ТЗ), но не может быть
получен, если выполнение транзакций Tl, Т2 и ТЗ подчиняется двухфазному
протоколу блокировки. В этом случае для выполнения операции R3 потребуется
установить S-блокировку для элемента А с согласия транзакции ТЗ. Тогда опе-
рация U1 в транзакции Т1 не будет выполняться до тех пор, пока не будет снята
блокировка, а это не произойдет до завершения выполнения транзакции ТЗ
(действительно, при достижении операции U3 транзакции ТЗ и Т1 попадут в си-
туацию взаимной блокировки).
Это упражнение прекрасно иллюстрирует следующий очень важный момент.
Пусть для данного набора транзакций и начального состояния базы данных задано
множество всех возможных графиков запуска (ALL), содержащих эти транзакции,
множество всех графиков запуска (CORRECT), которые гарантированно приводят к
Глава 15. Параллельность
597
корректному финальному состоянию или, по крайней мере, могут привести к нему
для некоторого начального состояния, множество всех допускающих упорядочи-
вание графиков запуска (SERIALIZABLE), а также множество всех графиков запуска
(PRODUCIBLE), которые приводят к корректному результату при использовании
двухфазного протокола блокировки. Тогда в общем случае будет верно следующее
утверждение (здесь знак “<” обозначает “подмножество”).
PRODUCIBLE < SERIALIZABLE < CORRECT < ALL
15.4. В момент tn ни одна из транзакций не выполнит никакой полезной работы! Дело в
том, что имеет место ситуация взаимной блокировки, включающая транзакции Т2,
ТЗ, T9 и Т8. Кроме того, транзакция Т4 находится в состоянии ожидания (ожидает)
завершения выполнения транзакции T9, транзакция Т12 ожидает завершения вы-
полнения транзакции Т4, а транзакции Т10 и Т11 ожидают завершения выполнения
транзакции Т12. Эту ситуацию можно представить с помощью приведенного на
рис. 15.14 графа ожидания, узлы которого представляют собой транзакции, а на-
правленные от узла Ti к узлу Tj ребра указывают на то, что транзакция Ti нахо-
дится в состоянии ожидания завершения выполнения транзакции Tj. Возле стрелок
размещены названия объектов базы данных с указанием в скобках уровня блоки-
ровки, в котором они находятся в состоянии ожидания.
15.5. Для задач, приведенных на рис. 15.1-15.3, уровень изоляции стабильности курсора
обладает тем же эффектом, что и уровень повторяемости считывания (обратите
внимание, однако, что для СУБД DB2 это утверждение не применимо к уровню
стабильности курсора из-за того, что в этой СУБД вместо S-блокировок использу-
ются U-блокировки [4.20]). Что касается проблемы несогласованной обработки
данных (см. рис. 15.4), то уровень изоляции стабильности курсора не позволяет
разрешить эту проблему. Дело в том, что транзакция А должна выполняться на
уровне повторяемости считывания для того, чтобы сохранить все свои блокировки
до завершения выполнения транзакции, иначе будет получен неверный результат.
(Конечно, если система поддерживает такой режим, то в качестве альтернативного
варианта можно было бы с помощью транзакции А полностью заблокировать всю
переменную-отношение счетов, установив некоторую явно заданную блокировку.
Это решение можно было бы использовать как для уровня стабильности курсора,
так и для уровня повторяемости чтения.)
15.6. См. раздел 15.8. Обратите внимание на то, что формальные определения даются с
помощью матрицы совместимости типов блокировок (см. рис. 15.11).
15.9. В этой главе были рассмотрены три проблемы параллельности, а именно: пробле-
мы потери результатов обновления, зависимости от незафиксированных резуль-
татов и несогласованной обработки данных.
Потеря результатов обновления. Согласно стандарту языка SQL требуется, что-
бы при любых обстоятельствах проблема потери результатов обновления нико-
гда не возникала.
Зависимость от незафиксированных результатов. Это всего лишь иное назва-
ние проблемы некорректного чтения.
Несогласованная обработка данных. Этим термином обозначаются как пробле-
ма неповторяемости чтения, так и проблема чтения фантомов.
598
Часть IV. Управление транзакциями
Рис. 15.14. Граф ожидания для упр. 15.4
15.10. Приведенное ниже краткое описание взято из [20.15]. Прежде всего в системе
должны выполняться следующие условия.
1. Для каждого объекта данных необходимо поддерживать стек зафиксирован-
ных версий (каждый элемент стека дает значение объекта и идентификатор
транзакции, которая создала это значение, т.е. каждый элемент стека содер-
жит указатель на соответствующий элемент журнала регистрации). Стек ор-
ганизован в обратном хронологическом порядке, при котором последний
элемент находится сверху.
2. Необходимо поддерживать список идентификаторов транзакций для всех за-
фиксированных транзакций (список фиксации).
В момент начала выполнения транзакции система предоставляет ей закрытую ко-
пию списка фиксации. Операции чтения объекта направляются к последней вер-
сии объекта, полученной с помощью транзакции из этого закрытого списка. А
операции обновления выполняются с фактическим текущим состоянием объекта
данных (вот почему все еще необходимо выполнять проверку конфликта
“обновление/обновление”). После фиксации транзакции система обновляет спи-
сок фиксации и стеки версий объектов данных.
Глава 15. Параллельность
599
Часть V
Дополнительные аспекты
В части II этой книги было сказано, что реляционная модель является основой совре-
менной технологии баз данных, и это действительно так. Но это только основа, и, поми-
мо описанной в части II реляционной модели, в технологии баз данных есть много дру-
гих компонентов. Как студентам, так и профессионалам необходимо освоить множество
дополнительных концепций и технологий, чтобы полностью овладеть этой областью
знаний (последнее вполне очевидно из обсуждений в частях III и IV данной книги). Те-
перь нам предстоит сосредоточить внимание на ряде важных тем, которые будут рас-
сматриваться в такой последовательности.
Защита данных (глава 16)
Оптимизация (глава 17)
Отсутствующая информация (глава 18)
Наследование типов (глава 19)
Распределенные базы данных (глава 20)
Поддержка принятия решений (глава 21)
Хронологические базы данных (глава 22)
Логические системы управления базами данных (глава 23)
Выбранная последовательность глав носит несколько произвольный характер, однако
при их написании предполагалось, что эти главы (может быть, не все) будут изучаться
именно в таком порядке.
601
Глава
Защита данных
16.1. Введение
Вопросы защиты данных часто рассматриваются вместе с вопросами поддержки
целостности данных (по крайней мере, в неформальном контексте), хотя на самом деле
это совершенно разные понятия. Термин защита (security) относится к защищенности
данных от несанкционированного доступа, изменения или умышленного разрушения, а
целостность — к точности или достоверности данных. Эти термины можно опреде-
лить и несколько иначе.
Под защитой данных подразумевается предотвращение доступа к ним со сторо-
ны несанкционированных пользователей.
Под поддержанием целостности данных подразумевается предотвращение их
разрушения при доступе со стороны санкционированных пользователей.
Иначе говоря, защита данных означает получение гарантий, что пользователям раз-
решено выполнять те действия, которые они пытаются выполнить, а поддержание цело-
стности означает получение гарантий, что действия, которые пользователи пытаются
выполнить, будут корректны.
Между этими понятиями есть, конечно, некоторое сходство, поскольку как при обес-
печении защиты данных, так и при обеспечении поддержки их целостности система вы-
нуждена проверять, не нарушаются ли при выполняемых пользователем действиях неко-
торые установленные ограничения. Эти ограничения формулируются (обычно админист-
ратором базы данных) на некотором подходящем языке и сохраняются в системном ка-
талоге. Причем в обоих случаях СУБД должна каким-то образом отслеживать все вы-
полняемые пользователем действия и проверять их соответствие установленным ограни-
чениям. В данной главе речь пойдет о защите данных, а вопросы целостности уже рас-
сматривалась в главах 8 и др.
Замечание. Основная причина, по которой эти две темы обсуждаются раздельно, со-
стоит в том, что целостность данных является фундаментальным понятием, тогда как
защита данных — понятием вторичным.
Общие соображения
Среди многочисленных аспектов проблемы защиты данных необходимо выделить
следующие.
Правовые, общественные и этические аспекты (например, имеет ли некоторое ли-
цо юридическое право запрашивать, скажем, информацию о выделенном клиенту
кредите).
602
Часть V. Дополнительные аспекты
Физические условия (например, запирается ли помещение с компьютерами или
терминалами либо же оно охраняется другим способом).
Организационные вопросы (например, каким образом на предприятии, являю-
щемся владельцем системы, принимается решение о том, кому разрешено иметь
доступ к тем или иным данным).
Вопросы управления (например, как в случае организации защиты системы от не-
санкционированного доступа по схеме паролей обеспечивается секретность ис-
пользуемых паролей и как часто они меняются).
Аппаратные средства защиты (например, имеет ли используемое вычислительное
оборудование встроенные функции защиты, подобные ключам защиты хранимой
информации или привилегированному режиму управления).
Возможности операционной системы (например, стирает ли используемая опера-
ционная система содержимое оперативной памяти и дисковых файлов после пре-
кращения работы с ними).
Аспекты, имеющие отношение непосредственно к самой СУБД (например, под-
держивает ли используемая СУБД концепцию владельца данных).
По очевидным причинам обсуждение этой обширной темы в данной главе будет ог-
раничено, в основном, вопросами, относящимися к последнему пункту приведенного
выше списка.
В современных СУБД обычно поддерживается один из двух (иногда оба) широко
распространенных подходов к организации защиты данных, а именно — избирательный
(discretionary) или мандатный (mandatory) подход. В обоих случаях единица данных или
“объект данных”, для которых организуется система защиты, может выбираться из ши-
рокого диапазона от всей базы данных до конкретных компонентов отдельных кортежей.
Различия между двумя указанными подходами состоят в следующем.
В случае избирательного контроля каждому пользователю обычно предоставля-
ются различные права доступа (иначе называемые привилегиями или полномо-
чиями) к разным объектам. Более того, разные пользователи, как правило, обла-
дают разными правами доступа к одному и тому же объекту. (Например, пользо-
вателю U1 может быть разрешен доступ к объекту А, но запрещен доступ к объекту
В, тогда как пользователю U2 может быть разрешен доступ к объекту В, но запре-
щен доступ к объекту А.) Поэтому избирательные схемы характеризуются значи-
тельной гибкостью.
В случае мандатного контроля, наоборот, каждому объекту данных назначается
некоторый классификационный уровень, а каждому пользователю присваивает-
ся некоторый уровень допуска. В результате право доступа к объекту данных по-
лучают только те пользователи, которые имеют соответствующий уровень допус-
ка. Мандатные схемы обычно имеют иерархическую структуру и поэтому являют-
ся более жесткими. (Если пользователь U1 имеет доступ к объекту А, но не имеет
доступа к объекту В, то в схеме защиты объект В должен будет располагаться на
более высоком уровне, чем объект А, а значит, не может существовать никакого
пользователя U2, который будет иметь доступ к объекту В, но не будет иметь дос-
тупа к объекту А.)
Глава 16. Защита данных
603
Избирательные схемы подробно обсуждаются ниже, в разделе 16.2, а мандатные схе-
мы — разделе 16.3.
Независимо от того, какая схема используется (избирательная или мандатная), все
решения относительно предоставления пользователям прав на выполнение тех или иных
операций с теми или иными объектами должны приниматься исключительно управлен-
ческим персоналом. Поэтому все эти вопросы выходят за пределы компетенции самой
СУБД, и все, что она способна сделать в данной ситуации, — привести в действие реше-
ния, которые будут приняты на другом уровне. Исходя из этих соображений, можно от-
метить следующее.
1 . Принятые организационные решения должны быть доведены до сведения системы
(т.е. представлены как выражения некоторого подходящего случаю языка описания
требований) и быть ей постоянно доступны (посредством их сохранения в систем-
ном каталоге).
2 . Очевидно, что в системе должны существовать определенные средства провер-
ки поступающих запросов на получение доступа по отношению к установлен-
ным правилам защиты. (Здесь под понятием “запрос на получение доступа”
подразумевается конкретная комбинация запрашиваемой операции, запраши-
ваемого объекта и запрашивающего пользователя.) Обычно такая проверка
выполняется подсистемой защиты СУБД, которая иногда также называется
подсистемой авторизации.
3 . Для принятия решения о том, какие именно установленные ограничения защиты
применимы к данному запросу на получение доступа, система должна быть спо-
собна установить источник этого запроса, т.е. суметь опознать запрашивающего
пользователя. Поэтому при подключении к системе от пользователя обычно требу-
ется ввести не только свой идентификатор (чтобы указать, кто он такой), но и па-
роль (чтобы подтвердить, что он именно тот, за кого себя выдает). Предполагается,
что пароль известен только системе и тем лицам, которые имеют право применять
данный идентификатор пользователя1.
Кстати, в отношении последнего пункта следует заметить, что один и тот же иденти-
фикатор может совместно применяться произвольным количеством разных пользовате-
лей, входящих в состав некоторой группы. Таким образом, система может поддерживать
группы пользователей, обеспечивая одинаковые права доступа для всех ее членов, на-
пример для всех работников расчетного отдела. Кроме того, операции добавления новых
пользователей в группу или их удаления из нее можно выполнять независимо от опера-
ций задания привилегий доступа для этой группы. Обратите внимание, однако, что ме-
стом хранения информации о принадлежности пользователей к группам также является
системный каталог (или, возможно, сама база данных). В этой связи следует обратить
1 Проверка того, что пользователь действительно является тем, за кого себя выдает, назы-
вается аутентификацией. Попутно отметим, что в настоящее время, помимо простой про-
верки пароля, существуют более сложные методы аутентификации пользователей с применени-
ем различных биометрических устройств (считывателей отпечатков пальцев, сканеров сетчат-
ки глаз, измерителей геометрических параметров рук, устройств проверки голоса, распознавания
подписи и т.д.). Они могут быть эффективно использованы для проверки тех "личных характе-
ристик, которые нельзя подделать или украсть ” [16.3].
604
Часть К Дополнительные аспекты
внимание на работу [16.9], в которой описывается система с вложенными пользователь-
скими группами. Вот цитата из этой работы: “Способность классифицировать пользова-
телей в виде иерархии групп представляет собой мощный инструмент администрирова-
ния больших систем с тысячами пользователей и объектов”.
16.2. Избирательная схема управления
доступом
Повторяя сказанное выше, следует еще раз отметить, что во многих СУБД поддер-
живается либо избирательная, либо мандатная схема управления доступом, либо оба
эти типа одновременно. Однако точнее все же будет сказать, что в действительности в
большинстве СУБД поддерживается только избирательная схема доступа и лишь в не-
которых— только мандатная. Поскольку на практике избирательная схема доступа
встречается гораздо чаще, основное внимание в этой главе уделяется именно ей.
Как уже отмечалось, для определения избирательных ограничений защиты необхо-
димо использовать некоторый язык. По вполне очевидным причинам гораздо легче ука-
зать то, что разрешается, чем то, что не разрешается. Поэтому в подобных языках
обычно поддерживается определение не самих ограничений защиты, а полномочий, ко-
торые по своей сути противоположны ограничениям защиты (т.е. они разрешают какие-
либо действия, а не запрещают их). Дадим краткое описание языка определения полно-
мочий, воспользовавшись следующим примером2.
AUTHORITY SA3
GRANT RETRIEVE ( S#, SNAME, CITY ), DELETE
ON S
TO Jim, Fred, Mary ;
/* Разрешить выборку атрибутов ( S#, SNAME, CITY ) и удаление */
/* данных из таблицы поставщиков пользователям Джим, Фред и Мэри */
Этот пример иллюстрирует тот факт, что в общем случае полномочия доступа вклю-
чают четыре компонента.
1. Имя (в данном примере— SA3). Устанавливаемые полномочия будут зарегистри-
рованы в системном каталоге под этим именем.
2. Одна или более привилегий, задаваемых в предложении GRANT (в нашем примере
это привилегия RETRIEVE (только для некоторых атрибутов) и привилегия DELETE).
3. Задаваемое в предложении ON имя переменной-отношения, к которой применя-
ются полномочия (в нашем примере это переменная-отношение S).
4. Один или более имен пользователей (точнее, идентификаторов пользователей),
которым предоставляются указанные привилегии по отношению к переменной-
отношению, задаваемой с помощью фразы ТО.
2 В исходном варианте языка Tutorial D [3.3] не предусмотрено никаких средств определения
полномочий, однако используемый в данном разделе гипотетический язык можно рассматривать
как ‘‘выдержанный в духе " языка Tutorial D.
Глава 16. Защита данных
605
Ниже приводится общий синтаксис оператора определения полномочий.
AUTHORITY <имя полномочий
GRANT <список привилегий
ON <имя переменной-отношения?
ТО <список идентификаторов пользователей ;
Пояснения. В приведенном выше определении смысл параметров <имя полномо-
чий^ <список привилегий», <имя переменной-отношения? и <список идентифика-
торов пользователей понятен из их названий. Добавим только, что значение ALL в
данном контексте может применяться для обозначения сразу всех известных пользова-
телей. В качестве элементов списка в параметре <список привилегий разрешается
применять следующие значения.
RETRIEVE [ (<список имен атрибутов>) ]
INSERT [ {<список имен атрибутов?) ]
UPDATE [ (<список имен атрибутов>) ]
DELETE
ALL
Смысл привилегий RETRIEVE (выборка), INSERT (вставка), UPDATE (обновление) и
DELETE (удаление) очевиден без дополнительных разъяснений3. Если при указании при-
вилегии RETRIEVE определен список атрибутов, то она применяется только к заданным
атрибутам. Списки имен атрибутов в определениях привилегий INSERT и UPDATE имеют
тот же смысл. Спецификация ALL является сокращенной записью предоставления всех
привилегий — RETRIEVE (по всем атрибутам), INSERT (по всем атрибутам), UPDATE (по
всем атрибутам) и DELETE.
Замечание. Для простоты здесь игнорируется проблема необходимости некоторых
особых привилегий для выполнения общих реляционных операций присвоения. Мы так-
же ограничим рассмотрение операциями манипулирования данными, хотя на практике,
конечно, существует много других операций, для которых следовало бы проверять нали-
чие соответствующих полномочий (например, определение и удаление переменных-
отношений, а также определение и удаление самих полномочий). Подробное рассмотре-
ние этих полномочий опускается для экономии места.
Что произойдет, если пользователь попытается выполнить с объектом операцию,
не имея на это необходимых полномочий? В простейшем случае достаточно просто
отвергнуть эту попытку (конечно, предоставив пользователю соответствующее ди-
агностическое сообщение). На практике такой вариант применяется наиболее часто,
поэтому его можно понимать как используемый по умолчанию. Однако в более
сложных ситуациях может оказаться полезным применить некоторое другое дейст-
вие, например завершить выполнение программы или заблокировать клавиатуру
пользователя. Также может иметь смысл фиксация всех подобных попыток в специ-
альном журнале регистрации (т.е. проведение отслеживания угроз}. Впоследствии
эти данные могут оказаться полезным для выявления попыток обнаружения брешей
3 Хотя и не вполне, поскольку наличие привилегии RETRIEVE необходимо также в случае
ссылки на некоторый объект (например, в определении представления или ограничения целост-
ности), а не только для выполнения операции выборки.
606
Часть V. Дополнительные аспекты
в системе защиты, а также следов возможного нелегального проникновения в систе-
му (подробнее вопросы контрольного слежения за процессами в системе обсужда-
ются в конце этого раздела).
Безусловно, необходимо также предусмотреть способ отмены существующих пол-
номочий.
DROP AUTHORITY <имя полномочий ;
В частности, для нашего примера он может выглядеть следующим образом.
DROP AUTHORITY SA3 ;
Для простоты изложения предположим, что при удалении некоторой переменной-от-
ношения автоматически удаляются и все полномочия, предоставленные по отношению к ней.
Ниже представлено несколько примеров определения полномочий, большинство из
которых не нуждается в дополнительных объяснениях.
1. AUTHORITY ЕХ1
GRANT RETRIEVE ( P#, PNAME, WEIGHT )
ON P
TO Jacques, Anne, Charley ;
Пользователи Jacques, Anne и Charley получают право доступа к указанному
“вертикальному подмножеству” данных в базовой переменной-отношении Р. Таким об-
разом, это пример предоставления полномочий, не зависящих от значения данных.
2. AUTHORITY ЕХ2
GRANT RETRIEVE, UPDATE (SNAME, STATUS), DELETE
ON LS
TO Dan, Misha ;
Упоминаемая здесь переменная-отношение LS является представлением (представ-
лением “поставщиков из Лондона”; см. рис. 9.4 в главе 9). Пользователи Dan и Misha
получают доступ к “горизонтальному подмножеству” данных в базовой переменной-
отношении S. Это пример предоставления полномочий, зависящих от значений
данных. Обратите внимание, что хотя пользователи Dan и Misha могут удалить
(DELETE) некоторые кортежи поставщиков (через представление LS), они не могут
вставить (INSERT) их, а также не имеют права обновлять (UPDATE) атрибуты S# и CITY.
3. VAR SSPPR VIEW
(S JOIN SP JOIN (P WHERE CITY = 'Rome') { P# } )
{ ALL BUT P#, QTY } ;
AUTHORITY EX3
GRANT RETRIEVE
ON SSPPR
TO Giovanni ;
Это еще один пример полномочий, зависящих от значения данных: пользователь
Giovanni получает доступ к информации о поставщиках, но только о тех, которые
поставляют детали, хранящиеся в Риме.
Глава 16. Защита данных
607
4. VAR SSQ VIEW
SUMMARIZE SP PER S { S# } ADD SUM (QTY) AS SQ ;
AUTHORITY EX4
GRANT RETRIEVE
ON SSQ
TO Fidel ;
Пользователь Fidel получает право просматривать итоговые данные по каждому
поставщику, но не имеет доступа к данным о каждой поставке в отдельности. Та-
ким образом, пользователь Fidel сможет просматривать в базе только статистиче-
ски обработанные данные.
5. AUTHORITY ЕХ5
GRANT RETRIEVE, UPDATE (STATUS)
ON S
WHEN DAY () IN ('Mon', 'Tue', 'Wed', 'Thu', 'Fri')
AND NOW () > TIME '09:00:00'
AND NOW () < TIME '17:00:00'
TO Purchasing ;
Здесь синтаксис определения полномочий расширен предложением WHEN, позволяю-
щим задать некоторые “контекстные элементы управления”. Дополнительно предпо-
лагается, что система предоставляет две встроенные функции (получения названия
текущего дня недели DAY() и текущего времени NOW()), которые не имеют аргумен-
тов. Данное определение полномочий гарантирует, что значение статуса поставщика
может быть изменено любым пользователем из группы Purchasing (работники отде-
ла приема заказов) только в рабочие дни и в рабочее время. Это пример так называе-
мого контекстно-зависимого полномочия, поскольку поступивший запрос на доступ
будет или не будет нарушать установленные ограничения в зависимости от состояния
контекста (в данном случае это комбинация дня недели и времени суток).
Ниже приводятся примеры других встроенных функций, которые могут быть по-
лезны при определении контекстно-зависимых полномочий.
DATE() Возвращает текущую дату
USER() Возвращает идентификатор пользователя, выдавшего запрос
TERMINAL () Возвращает идентификатор терминала, с которого поступил запрос
С концептуальной точки зрения несколько полномочий объединяются одно с другим
по принципу связи логических утверждений с помощью оператора OR (Или). Иначе гово-
ря, поступивший запрос на получение доступа (включающий комбинацию запрашивае-
мой операции, запрашиваемого объекта и имени запрашивающего пользователя) прини-
мается тогда и только тогда, когда он удовлетворяет хотя бы одному из существующих
полномочий. Например, если в одном определении полномочий утверждается, что поль-
зователю Nancy разрешается считывать сведения о цвете деталей, а в другом определе-
нии указывается, что этот же пользователь имеет право доступа к сведениям о весе дета-
лей, это не значит, что ему разрешается считывать сведения о цвете и весе деталей одно-
временно (для этого потребуется определить дополнительное полномочие).
608
Часть К Дополнительные аспекты
В заключение необходимо отметить следующее: выше предполагалось, хотя явно ни-
где не заявлялось, что пользователи могут выполнять только те действия, которые им по-
зволено выполнять предоставленными полномочиями. Все, что не позволено явным об-
разом, неявно запрещено!
Модификация запроса
Для иллюстрации некоторых представленных выше идей целесообразно описать ас-
пекты защиты данных, реализованные в университетском прототипе системы Ingres, а
также особенности используемого в ней языка запросов QUEL. В этой реализации был
принят довольно интересный подход к решению проблем защиты, заключающийся в
том, что любой запрос на языке QUEL перед выполнением автоматически модифициро-
вался таким образом, чтобы предотвратить любые возможные нарушения установленных
ограничений защиты. В качестве примера предположим, что пользователю U разрешено
считывать данные только о тех деталях, которые хранятся в Лондоне. Это ограничение
описывается следующим выражением.
DEFINE PERMIT RETRIEVE ON Р ТО U
WHERE P.CITY = 'London'
(Оператор DEFINE PERMIT будет подробно описан ниже.) Теперь предположим, что
пользователь U вводит приведенный ниже запрос на языке QUEL.
RETRIEVE ( P.P#, Р.WEIGHT )
WHERE P.COLOR = 'Red'
Используя приведенное выше “разрешение” (PERMIT) для комбинации переменной-
отношения Р и пользователя U, сохраняемое в системном каталоге, СУБД INGRES авто-
матически преобразует приведенный выше запрос в запрос следующего вида.
RETRIEVE ( P.P#, Р.WEIGHT )
WHERE Р.COLOR = 'Red'
AND P.CITY = 'London'
Безусловно, модифицированный подобным образом запрос едва ли сможет нарушить
установленное ограничение защиты. Обратите внимание, что процесс модификации про-
исходит совершенно “незаметно”, т.е. пользователь U никак не информируется о том, что
фактически система выполнила запрос, который несколько отличается от исходного. Де-
ло в том, что сокрытие этой информации может быть само по себе достаточно важным
(например, пользователю U не следует даже знать о том, что существуют детали, которые
хранятся не в Лондоне).
Кратко описанный выше процесс модификации запроса полностью идентичен ме-
тоду, используемому для реализации представлений [8.20], а также (особенно в случае
прототипа системы Ingres) ограничений целостности [9.15]. Таким образом, важное
преимущество данного подхода заключается в том, что его достаточно просто реали-
зовать (в основном, благодаря тому, что необходимый для этого программный код уже
присутствует в системе). Другое его преимущество — сравнительно высокая эффек-
тивность, так как увеличение накладных расходов (по крайней мере, частично), свя-
занных с реализацией ограничений защиты, приходится на время компиляции, а не на
время выполнения программы. Еще одно преимущество данного подхода состоит в
Глава 16. Защита данных
609
том, что при его использовании отсутствуют определенные неудобства, свойственные
подходу, реализованному в языке SQL, когда для одного пользователя требуется зада-
вать разные привилегии при обращении к разным частям одной и той же переменной-
отношения (см. раздел 16.6).
Единственный недостаток этого подхода заключается в Том, что не всем ограниче-
ниям защиты можно придать столь простую форму. В качестве простейшего обратного
примера предположим, что пользователю U запрещен доступ к переменной-отношению
Р. Тогда любая достаточно простая “модифицированная” форма приведенного выше оп-
ределения полномочий на выборку данных непременно создаст иллюзию, что перемен-
ной-отношения Р просто не существует. В результате система обязательно выдаст сооб-
щение об ошибке приблизительно следующего содержания: “Вам не разрешен доступ к
указанной переменной-отношению”. (Или, вероятно, система просто скроет истину и
лукаво сообщит: “Такой переменной-отношения не существует”.)
В общем виде синтаксис оператора определения полномочий DEFINE PERMIT вы-
глядит так.
DEFINE PERMIT <список названий операторов >
ON <имя переменной-отношения> [ ( <список имен атрибутов> )
ТО Идентификатор пользователе
[ AT <список имен терминалов> ]
[ FROM Иреме ТО Иреме ]
[ ON <день> ТО <день> ]
[ WHERE Логическое выражение> ]
Таким образом, концептуально синтаксис оператора определения полномочий DEFINE
PERMIT очень похож на синтаксис оператора определения полномочий AUTHORITY, за ис-
ключением того, что он разрешает указание дополнительных условий в предложении
WHERE. Ниже приведен пример подобного определения.
DEFINE PERMIT APPEND, RETRIEVE, REPLACE
ON S ( S#, CITY)
TO Joe
AT TTA4
FROM 9:00 TO 17:00
ON Sat TO Sun
WHERE S.STATUS <50
AND S.S# = SP.P#
AND SP.P# = P.P#
AND P.COLOR = 'Red'
Замечание. Операторы добавления (APPEND) и замены (REPLACE) являются аналогами
операторов вставки (INSERT) и обновления (UPDATE) соответственно.
Контрольное слежение
Важно понимать, что неуязвимых систем защиты не бывает. Настойчивый потенци-
альный нарушитель всегда сможет преодолеть все установленные системы контроля,
особенно если за это ему будет предложено достаточно высокое вознаграждение. Поэто-
му при работе с очень важными данными или при выполнении ответственных операций
610
Часть К Дополнительные аспекты
возникает необходимость организации контрольного слежения за происходящими в
системе событиями. Пусть, например, противоречивость полученных результатов вызы-
вает подозрение, что имело место злонамеренное искажение информации, хранящейся в
базе данных. В этом случае для прояснения ситуации могут использоваться записи кон-
трольного слежения, что позволит либо подтвердить тот факт, что все процессы нахо-
дятся под контролем, либо обнаружить вмешательство и установить нарушителя.
Метод контрольного слежения предусматривает использование особого файла или
базы данных, в которую СУБД автоматически помещает сведения обо всех операциях,
выполненных пользователями при работе с основной базой данных. В одних системах
данные контрольного слежения могут физически записываться в файл системного
журнала, используемого для восстановления (см. главу 14), в других системах эти све-
дения помещаются в отдельный файл. В любом случае пользователям должен быть
предоставлен механизм доступа к информации контрольного слежения, желательно с
помощью средств обычного языка реляционных запросов (конечно, при условии, что
эти запросы санкционированы!). Типичная запись в файле контрольного слежения
может содержать такую информацию:
сам запрос (исходный текст запроса);
имя терминала, с которого была затребована операция;
имя пользователя, затребовавшего операцию;
дата и время запуска операции;
переменные-отношения, кортежи и атрибуты, вовлеченные в процесс выполнения
операции;
исходные значения измененных данных;
новые значения измененных данных.
Как уже упоминалось, даже сам факт, что в системе осуществляется контрольное
слежение, в определенных ситуациях способен отпугнуть потенциального нарушителя.
16.3. Мандатная схема управления доступом
Методы мандатного управления доступом применяются к тем базам данных, в которых
хранимая информация имеет достаточно статичную и жесткую структуру, что свойственно,
например, некоторым правительственным или военным организациям. Как отмечалось
выше, основная идея состоит в том, что каждому объекту данных присваивается некоторый
классификационный уровень (или требуемый гриф секретности, например “Секретно”,
“Совершенно секретно”, “Для служебного пользования” и т.д.), а каждому пользователю
предоставляется уровень допуска с градациями, аналогичными существующим классифи-
кационным уровням. Предполагается, что эти уровни образуют строгую иерархическую
систему (например, “Совершенно секретно” > “Секретно” > “Для служебного пользования”
и т.д.). Тогда исходя из этих положений можно сформулировать два очень простых прави-
ла, впервые предложенных Беллом и Ла-Падулой [16.1].
1 . Пользователь i может получить доступ к объекту j только в том случае, если его
уровень допуска больше классификационного уровня объекта j или равен ему
(“ограничение простой защиты”).
Глава 16. Защита данных
611
2 . Пользователь i может модифицировать объект j только в том случае, если его уро-
вень допуска равен классификационному уровню объекта j (“ограничение звания”).
Первое правило достаточно очевидно, тогда как второе требует дополнительных
разъяснений. Прежде всего, следует отметить, что иначе второе правило можно сформу-
лировать так: “Любая информация, записанная пользователем i, автоматически приобре-
тает классификационный уровень, который равен уровню допуска пользователя i”. По-
добное правило необходимо, например, для того, чтобы предотвратить запись секретных
данных, выполняемую пользователем с уровнем допуска “Секретно”, в файл с меньшим
уровнем классификации, что нарушит всю систему секретности.
Замечание. В отношении только операций собственно “записи” (INSERT) во втором
правиле достаточно было бы потребовать, чтобы уровень допуска пользователя i был
меньше классификационного уровня объекта j или равен ему, и именно это правило час-
то приводится в литературе. Но тогда пользователи могли бы записывать то, что потом
сами не смогли бы прочесть! (Хотя бывает так, что кое-кто с трудом может прочесть да-
же собственный рукописный текст... Возможно, более слабый вариант второго правила
все-таки не совсем нереалистичен.)
Особенно большое внимание методам мандатного управления доступом стало уделяться в
начале 1990-х годов. Дело в том, что согласно требованиям Министерства обороны США лю-
бая используемая в этом ведомстве СУБД должна непременно поддерживать схему мандат-
ного управления доступом. Поэтому разработчикам СУБД пришлось вступить в соперничест-
во за скорейшую разработку методов такого управления. Обязательные требования к этой
схеме были изложены в двух важных публикациях Министерства обороны, неформально по-
лучивших название “Оранжевая” книга (Orange Book) [16.19] и “Сиреневая” книга
(Lavender Book) [16.20]. В “оранжевой” книге перечислен набор требований защиты для неко-
торой “надежной вычислительной базы” (Trusted Computing Base— ТСВ), а в “сиреневой”
книге дается интерпретация этих требований в отношении систем баз данных.
Определенные в [16.19], [16.20] методы мандатного управления доступом на самом де-
ле являются частью более общей классификации уровней защиты, которые в очень сжатой
форме излагаются ниже. Прежде всего, в этих документах определяется четыре класса
безопасности — D, С, В и А. Грубо говоря, класс D среди них наименее безопасен, класс
С — более безопасен, чем класс D, и т.д. Говорят, что класс D обеспечивает .минимальную,
класс С — избирательную, класс В —мандатную и класс А — проверенную защиту.
Избирательная защита. Класс С делится на два подкласса, С1 и С2 (где подкласс
С1 менее безопасен, чем подкласс С2), каждый из которых поддерживает избира-
тельное управление доступом в том смысле, что управление доступом осуществля-
ется по усмотрению владельца данных (точно так, как описано выше, в разделе 16.2).
В соответствии с требованиями класса С1 необходимо отделить владение от дос-
тупа, т.е. наряду с поддержкой концепции совместного доступа к данным поль-
зователям разрешается иметь собственные защищенные данные.
В соответствии с требованиями класса С2 необходимо дополнительно организо-
вать поддержку учетных записей, построенную на основе использования проце-
дуры регистрации в системе, контрольного слежения и изоляции ресурсов.
Мандатная защита. Класс В включает требования к методам мандатного управ-
ления доступом и делится на три подкласса — В1, В2 и ВЗ (где В1 является наи-
менее, а ВЗ — наиболее безопасным подклассом).
612
Часть V. Дополнительные аспекты
В соответствии с требованиями класса В1 необходимо организовать “защиту с
использованием меток” (это значит, что каждый объект данных в системе дол-
жен иметь пометку о присвоенном ему классификационном уровне —
“Секретно”, “Для служебного пользования” и т.д.). Дополнительно требуется
поддержка неформальных операторов определения требований защиты.
В соответствии с требованиями класса В2 дополнительно требуется поддержка
формальных операторов определения требований защиты. Кроме того, необходимо
обеспечить обнаружение и исключение каналов утечки информации. Таким кана-
лом может быть, например, возможность логического вывода ответа на недопус-
тимый запрос из ответа на допустимый запрос (см. раздел 16.4) или возможность
раскрытия секретных сведений на основании времени, которое затрачивается на
выполнение некоторых допустимых запросов (см. комментарии к [16.12]).
В соответствии с требованиями класса ВЗ необходимо дополнительно обеспе-
чить поддержку контрольного слежения и восстановления данных, а также на-
значить администратора защиты системы.
Проверенная защита. Класс А является наиболее безопасным, и согласно его
требованиям необходимо математическое доказательство того, что выбранный
механизм защиты является приемлемым и обеспечивает адекватную поддержку
установленных ограничений защиты (!).
В настоящее время некоторые коммерческие СУБД поддерживают мандатную схему
защиты уровня В1. Кроме того, они обычно поддерживают избирательную схему защиты
уровня С2.
Терминология. СУБД, в которых поддерживается мандатная схема защиты, часто на-
зывают системами с многоуровневой защитой [16.13], [16.16], [16.21] (см. следующий
подраздел). В этом же смысле иногда используется термин надежная система [16.17],
[16.19], [16.20].
Многоуровневая защита
Допустим, что требуется применить идеи мандатной схемы управления доступом к
переменной-отношению поставщиков S. Для определенности и простоты будем считать,
что единицей данных, на уровне которой требуется контролировать доступ, является от-
дельный кортеж этой переменной-отношения. Тогда каждый кортеж должен быть отме-
чен соответствующим классификационным уровнем, например так, как показано на
рис. 16.1. (Здесь значение 4 в столбце CLASS означает уровень “Совершенно секретно”,
3 — “Секретно”, 2 — “Для служебного пользования”.)
S S# SNAME STATUS CITY CLASS
S1 Smith 20 London 2
S2 Jones 10 Paris 3
S3 Blake 30 Paris 2
S4 Clark 20 London 4
S5 Adams 30 Athens 3
Рис. 16.1. Переменная-отношение S с присвоенными значениями классификационного уровня
Глава 16. Защита данных
613
Теперь предположим, что пользователи U1 и U2 имеют уровни доступа 3 (“Секретно”)
и 2 (“Для служебного пользования”) соответственно. Тогда переменная-отношение S для
этих пользователей будет выглядеть по-разному! Запрос на выборку сведений обо всех
поставщиках со стороны пользователя U1 возвратит четыре кортежа с данными о по-
ставщиках с номерами 'S1', ' S2', 'S3' и 'S5'. Аналогичный запрос со стороны пользо-
вателя U2 возвратит два кортежа с данными о поставщиках с номерами 'S1' и 'S3'. Бо-
лее того, в результатах выполнения обоих запросов будут отсутствовать сведения о по-
ставщике с номером ' S4'.
Разобраться в приведенных выше утверждениях можно, применив метод модифика-
ции запроса. Рассмотрим приведенный ниже запрос (“Получить сведения о поставщиках
из Лондона”).
S WHERE CITY = 'LONDON'
Система модифицирует этот запрос и приводит его к следующему виду.
S WHERE CITY = 'LONDON' AND CLASS < <уровень доступа пользователя?
Аналогичные соображения будут справедливы и по отношению к операциям об-
новления. Например, пользователь U1 не знает о существовании кортежа для постав-
щика с номером ' S4', а потому приведенная ниже команда INSERT может показаться
ему вполне законной.
INSERT INTO S RELATION { TUPLE { S# S# ( 'S4' ),
SNAME NAME ( 'Baker' ),
STATUS 25,
CITY 'Rome' } } ;
Система не должна отвергать команду INSERT, поскольку в этом случае пользователь
U1 в конечном счете узнает о существовании поставщика с номером 'S4'. Такую коман-
ду система примет, но модифицирует ее и приведет к следующему виду.
INSERT INTO S RELATION { TUPLE { S# S# ( 'S4' ),
SNAME NAME ( 'Baker' ),
STATUS 25,
CITY 'Rome',
CLASS CLASS ( 3 ) } } ;
Обратите внимание, что в данном случае первичным ключом для переменной-отношения
поставщиков является уже не атрибут {S#}, а комбинация атрибутов {S#,CLASS}.
Замечание. Для простоты предполагается, что существует только один потенциаль-
ный ключ, который в этом случае можно рассматривать как первичный ключ.
Еще о терминологии. Модифицированная указанным образом переменная-отношение
поставщиков является примером многоуровневой переменной-отношения. Та особен-
ность, что “одни и те же” данные по-разному выглядят для разных пользователей, назы-
вается полиреализацией. В приведенном выше примере с оператором INSERT запрос на
извлечение данных о поставщике с номером ' S4' возвратит разные результаты для поль-
зователя с правом доступа к совершенно секретным материалам и для пользователя U1,
614
Часть V. Дополнительные аспекты
имеющего лишь право доступа к секретным материалам. Третий результат, отличный от
двух предыдущих, будет предоставлен пользователю U2, обладающему правом доступа к
материалам для служебного пользования.
Операторы обновления (UPDATE) и удаления (DELETE) обрабатываются системой ана-
логично (здесь мы не будем обсуждать их, поскольку более подробно они рассматрива-
ются в некоторых работах, перечисленных в списке литературы для этой главы).
Вопрос. Как вы думаете, не нарушают ли эти идеи упомянутый выше принцип ин-
формации? Обоснуйте свой ответ.
16.4. Статистические базы данных
Замечание. Большая часть материала, приведенного в этом и следующем разделах, в
несколько отличной форме сначала была опубликована в [16.4].
Статистической (в приведенном здесь контексте) называется база данных, в кото-
рой допускаются запросы с обобщением данных (суммированием, вычислением сред-
него значения и т.д.), но не допускаются запросы по отношению к элементарным дан-
ным. Например, в статистической базе данных разрешается выдача запроса “Какова
средняя зарплата программистов?”, тогда как выдача запроса “Какова зарплата про-
граммиста Мэри?” запрещена.
Проблема статистических баз данных заключается в том, что иногда с помощью ло-
гических заключений на основе выполнения разрешенных запросов можно вывести от-
вет, который прямо может быть получен только с помощью запрещенного запроса. Как
указывается в [16.6], “Обобщенные значения содержат следы исходной информации, и
она может быть восстановлена злоумышленником после соответствующей обработки
этих обобщенных значений. Такой процесс называется логическим выводом конфиден-
циальной информации". Следует отметить, что эта проблема, к сожалению, становится
все более и более важной по мере того, как использование хранилищ данных (см. гла-
ву 21) получает все большее распространение.
Предположим, что в базе данных содержится только одна переменная-отношение,
STATS, представленная на рис. 16.2. Предположим также для простоты, что все атрибуты
определены на основе примитивных типов данных (т.е. числового и строкового). Далее
предположим, что некоторому пользователю U в этой базе данных разрешено выполнять
только статистические запросы, но он поставил себе целью узнать размер зарплаты ра-
ботника по имени ' Alf'. Наконец предположим, что из других источников пользователь
U узнал, что работник по имени 'Alf' является мужчиной и программистом. Проанали-
зируем представленные ниже запросы.
1. WITH ( STATS WHERE SEX = 'M' AND
OCCUPATION = 'Programmer' ) AS X :
COUNT ( X )
Результат: 1.
2. WITH ( STATS WHERE SEX = 'M' AND
OCCUPATION = 'Programmer' ) AS X :
SUM ( X, SALARY )
Результат: 50 000. |
Глава 16. Защита данных
615
NAME SEX CHILDREN OCCUPATION SALARY TAX AUDITS
Alf M 3 Programmer 50K 10K 3
Bea F 2 Physician 130K 20K 0
Cary F 0 Programmer 56K 18K 1
Dawn F 2 Builder 60K 12K 1
Ed M 2 Clerk 44K 4K 0
Fay F 1 Artist 30K OK 0
Guy M 0 Lawyer 190K OK 0
Hal M 3 Homemaker 44k 2k 0
Ivy F 4 Programmer 64K 10K 1
Joy F 1 Programmer 60K 2-K 1
Рис. 16.2. Переменная-отношение STATS
Очевидно, что защита базы данных была нарушена, хотя пользователь U применил
только разрешенные ему статистические запросы. Как показано в примере, если пользо-
ватель сумеет найти такое логическое выражение, которое позволит ему идентифициро-
вать некоторую личность, то информация о данной личности окажется незащищенной.
По этой причине система должна отвергать любые запросы, для которых кардинальность
обобщаемого множества окажется менее некоторого установленного минимального зна-
чения Ь. Это также означает, что система должна отвергать запросы, кардинальность
обобщаемого множества которых превосходит значение N-b (где N — кардинальность
исходной переменной-отношения). Дело в том, что можно привести еще один пример
нарушения защиты этой базы данных, осуществляемого посредством ввода показанной
ниже последовательности запросов 3-6.
3. COUNT ( STATS )
Результат: 12.
4. WITH ( STATS WHERE NOT ( SEX = 'M' AND
OCCUPATION = 'Programmer' ) ) AS X :
COUNT ( X )
Результат: 11; 12 - 11 = 1.
5. SUM ( STATS, SALARY )
Результат: 728 000.
6. WITH ( STATS WHERE NOT ( SEX = 'M' AND
OCCUPATION = 'Programmer' ) ) AS X :
SUM ( X, SALARY )
Результат: 678 000; 728 000 - 678 000 = 50 000. |
К сожалению, можно легко показать, что для исключения нарушений защиты совершенно
недостаточно определить допустимость запроса просто по значению кардинальности с обоб-
щаемого им множества, которое должно находиться в диапазоне b < с < N - Ь. Еще раз обра-
616
Часть V. Дополнительные аспекты
тимся к примеру на рис. 16.2. Если b = 2, то в таком случае будут разрешены запросы только с
кардинальностью с, находящейся в диапазоне 2 < с < 8. Это значит, что следующее логиче-
ское выражение использовать нельзя.
SEX = 'М' AND OCCUPATION = 'Programmer'
Теперь рассмотрим приведенную ниже последовательность запросов 7-10.
7. WITH ( STATS WHERE SEX = 'М' ) AS X :
COUNT ( X )
Результат: 4.
8. WITH ( STATS WHERE SEX = 'M' AND NOT
( OCCUPATION = 'Programmer' ) ) AS X :
COUNT ( X )
Результат: 3.
На основании запросов 7 и 8 пользователь U может сделать вывод, что существует
только один мужчина-программист, следовательно, его зовут ' Alf' (поскольку поль-
зователь U уже знает из других источников, что сотрудник по имени 'Alf' является
мужчиной и программистом). Зарплата этого сотрудника может быть определена сле-
дующим образом.
9. WITH ( STATS WHERE SEX = 'М' ) AS X :
SUM ( X, SALARY )
Результат: 328 000.
10. WITH ( STATS WHERE SEX = 'M' AND NOT
( OCCUPATION = 'Programmer' ) ) AS X :
SUM ( X, SALARY )
Результат: 278 000; 328 000 - 278 000 = 50 000. |
Логическое выражение SEX = 'М' AND OCCUPATION = 'Programmer' называется тре-
кером (охотником) за индивидуальными данными (individual tracker) для человека по
имени 'Alf' [16.6], поскольку оно позволяет отыскать индивидуальную информацию о
человеке по имени 'Alf'. В общем случае, если пользователю известно некоторое логи-
ческое выражение BE, идентифицирующее некоторого человека I, и если логическое вы-
ражение BE может быть выражено в виде ВЕ1 AND ВЕ2, логическое выражение ВЕ1 AND
NOT ВЕ2 является трекером за индивидуальными данными человека по имени I (при ус-
ловии, что в системе разрешено использовать выражения ВЕ1 и ВЕ1 AND NOT ВЕ2, т.е. оба
они приводят к результату, кардинальность (с) которого находится в диапазоне b < с
< N - Ь). Причина этого заключается в том, что определенное с помощью BE множество
идентично разнице между множеством, определенным с помощью ВЕ1, и множеством,
определенным с помощью BE 1 AND NOT ВЕ2, что наглядно представлено на рис. 16.3.
set ( BE ) = set ( ВЕ1 AND BE2 )
= set (BE1) - set (BE1 AND NOT BE2)
Глава 16. Защита данных
617
Множество, идентифицированное булевым выражением ВЕ1
Множество, идентифицированное булевым выражением ВС 4
AND NOT ВЕ2 Множество, идентифицированное булевым выражением BE1ANDBE2 — т.е. {!}
Множество, идентифицированное
булевым выражением ВЕ2
Рис. 16.3. Трекер за индивидуальными данными ВЕ1 AND NOT ВЕ2
В [16.6] упомянутые здесь идеи обобщены и показано, что практически для лю-
бой статистической базы данных всегда может быть определен общий трекер (в от-
личие от множества индивидуальных трекеров). Общий трекер (general tracker) —
это логическое выражение, которое может быть использовано для поиска ответа на
любой запрещенный запрос, т.е. запрос, включающий недопустимое логическое вы-
ражение. (В противоположность этому индивидуальный трекер работает только на
основе запросов, включающих конкретные запрещенные выражения.) Фактически
оказывается, что любое логическое выражение с результирующим набором данных с
кардинальностью с в диапазоне 2Ь < с < N - 2Ь является общим трекером (здесь b
должно быть меньше, чем N/4, что обычно всегда выполняется на практике). Как
только такой трекер будет найден, сразу же можно будет получить ответ на запрос,
включающий запрещенное логическое выражение BE, что наглядно показано в сле-
дующем примере. (Для определенности рассмотрим случай, в котором кардиналь-
ность результирующего множества логического выражения BE меньше Ь. Случай,
когда b больше N - Ь, обрабатывается аналогично.) Обратите внимание, что по оп-
ределению Т является общим трекером тогда и только тогда, когда NOT Т также яв-
ляется общим трекером.
Пример. Предположим снова, что b = 2; тогда общим трекером будет любое логиче-
ское выражение с кардинальностью результирующего множества с в диапазоне 4 < с <
б. Еще раз предположим, что пользователю U известно из внешних источников, что со-
трудник по имени 'Alf' является мужчиной и программистом, т.е. запрещенное логиче-
ское выражение BE выглядит так, как показано ниже.
SEX = 'М' AND OCCUPATION = 'Programmer'
Допустим также, что пользователь U хочет узнать размер зарплаты сотрудника
'Alf'. В этом случае общий трекер придется применить дважды: сначала, чтобы удо-
стовериться, что BE действительно идентифицирует сотрудника по имени 'Alf' (этапы
2-4), а затем непосредственно для того, чтобы определить размер зарплаты сотрудни-
ка 'Alf' (этапы 5-7).
Этап 1. Попробуем найти выражение для общего трекера Т. В качестве первого
приближения выберем следующее выражение.
AUDITS = О
618
Часть V. Дополнительные аспекты
Этап 2. С помощью выражений Т и NOT Т определим общее количество сотрудни-
ков, сведения о которых содержатся в базе данных.
WITH ( STATS WHERE AUDITS = 0 ) AS X :
COUNT ( X )
Результат: 5.
WITH ( STATS WHERE NOT ( AUDITS = 0 ) ) AS X :
COUNT ( X )
Результат: 5; 5 + 5 = 10.
Теперь легко видеть, что выбранное выше выражение Т действительно оказалось
общим трекером.
Этап 3. Найдем результат сложения общего количества сотрудников в базе данных
с количеством сотрудников, для которых удовлетворяется неразрешенное выраже-
ние BE, для чего используем выражения BE OR Т и BE OR NOT Т.
WITH ( STATS WHERE ( SEX = 'M' AND
OCCUPATION = 'Programmer'
OR AUDITS = 0 ) AS X :
COUNT ( X )
Результат: 6.
WITH ( STATS WHERE ( SEX = 'M' AND
OCCUPATION = 'Programmer'
OR NOT ( AUDITS = 0 ) ) AS X :
COUNT ( X )
Результат: 5; 6 + 5 = 11.
Этап 4. Из полученных выше результатов можно сделать заключение, что количе-
ство сотрудников, которые удовлетворяют логическому выражению BE, равно еди-
нице (результат этапа 3 минус результат этапа 2), т.е. логическое выражение BE
единственным образом идентифицирует сотрудника по имени ' Alf'.
Теперь на этапах 5 и 6 повторим запросы, использованные на этапах 2 и 3, но вме-
сто функции COUNT укажем функцию SUM.
Этап 5. С помощью выражений Т и NOT Т найдем размер зарплаты всех сотрудников.
WITH ( STATS WHERE AUDITS = 0 ) AS X :
SUM ( X, SALARY )
Результат: 438 000.
WITH ( STATS WHERE NOT ( AUDITS = 0 ) ) AS X :
SUM ( X, SALARY )
Результат: 290 000; 438 000 + 290 000 = 728 000.
Глава 16. Защита данных
619
Этап 6. Найдем размер зарплаты сотрудника по имени 'Alf' плюс размер зарпла-
ты всех сотрудников, используя выражения BE OR Т и BE OR NOT Т.
WITH ( STATS WHERE ( SEX = 'M' AND
OCCUPATION = 'Programmer'
OR AUDITS = 0 ) AS X :
SUM ( X, SALARY )
Результат: 488 000.
WITH ( STATS WHERE ( SEX = 'M' AND
OCCUPATION = 'Programmer'
OR NOT ( AUDITS = 0 ) ) AS X :
SUM ( X, SALARY )
Результат: 290 000; 488 000 + 290 000 = 778 000.
Этап 7. Найдем размер зарплаты сотрудника по имени 'Alf', вычитая из общей
суммы (полученной на этапе 5) результат, полученный на этапе 6.
Результат: 50 000. |
Принцип действия общего трекера схематически представлен на рис. 16.4.
set ( BE ) = ( set ( BE OR Т ) + set ( BE OR NOT T ) ) - set ( T OR NOT T )
Множество, идентифицированное выражением Т Множество, идентифицированное выражением NOT Т
Множество, идентифицированное булевым выражением BE —т.е. {1}
Puc. 16.4. Принцип функционирования общего трекера Т
Если исходное предположение оказалось неверным (т.е. Т не является общим трекером),
тогда одно или оба выражения ( BE OR Т ) и ( BE OR NOT Т ) могут оказаться недопусти-
мым. Например, если кардинальности для результирующих наборов для выражений BE и Т
равны р и q соответственно, где р < q и b < q < 2b, то кардинальность результирующего
множества для ( BE OR Т ), которая не может превышать значение р + q, может оказаться
меньше Ь. В такой ситуации необходимо выбрать другой вариант выражения для общего тре-
кера и повторить попытку. В [16.6] предполагается, что на практике не так уж сложно найти
подходящее выражение для общего трекера. В приведенном здесь частном примере исходный
вариант сразу оказался общим трекером (кардинальность его результирующего набора дан-
ных равна 5) и оба запроса на этапе 3 также оказались допустимыми.
Обобщим полученные результаты. “Практически всегда” существует выражение, яв-
ляющееся общим трекером, найти которое так же легко, как и использовать. Действи-
тельно, выражение для общего трекера достаточно быстро можно просто угадать путем
перебора нескольких вариантов [16.6]. Даже в тех случаях, когда выражение для общего
трекера не существует, могут быть найдены, как показано в [16.6], специфические треке-
ры, предназначенные для конкретных запросов. Трудно избежать общего заключения,
что безопасность статистических баз данных остается насущной проблемой.
620
Часть V. Дополнительные аспекты
Что в таком случае можно сделать? Некоторые варианты решения этой проблемы
уже предлагались в литературе, но все же пока нельзя сказать определенно, является
ли какой-либо из них удовлетворительным во всех отношениях. Например, в одном
из вариантов предлагается организовать “обмен данными” (“data swapping”), т.е. об-
мен значениями атрибутов между кортежами, осуществляемый таким образом, что-
бы поддерживалась лишь статистическая точность. При этом даже если злоумыш-
леннику удастся идентифицировать отдельное значение (например, некоторое зна-
чение зарплаты), то у него не будет способа узнать, какому именно кортежу (в на-
шем примере — сотруднику) оно принадлежит. Сложность этого подхода заключа-
ется в необходимости отыскать множество тех записей, между которыми можно бу-
дет организовать обмен значениями соответствующим образом. Подобные затруд-
нения имеют место и при использовании большинства других методов. В данный
момент, видимо, придется согласиться с выводами Деннинга [16.6] о том, что
“методы нарушения защиты данных просты и не связаны с большими расходами.
Поэтому требование обеспечения полной секретности конфиденциальной информа-
ции несовместимо с требованием возможности вычисления точных статистических
показателей для произвольных подмножеств данных в базе. По крайней мере одно
из этих требований должно быть снято прежде, чем можно будет поверить в гаран-
тии обеспечения секретности”.
16.5. Шифрование данных
До сих пор в этой главе подразумевалось, что предполагаемый нелегальный пользо-
ватель пытается незаконно проникнуть в базу данных с помощью обычных средств дос-
тупа, имеющихся в системе. Теперь следует рассмотреть случай, когда он пытается про-
никнуть в базу данных, минуя систему, т.е. физически перемещая часть базы данных или
подключаясь к коммуникационному каналу. Наиболее эффективным методом борьбы с
такими угрозами является шифрование данных, т.е. хранение и передача особо важных
данных в зашифрованном виде.
Для обсуждения основных концепций шифрования данных следует ввести некото-
рые новые понятия. Исходные (незашифрованные) данные называются открытым
текстом. Открытый текст шифруется с помощью специального алгоритма шифро-
вания. В качестве входных данных для такого алгоритма выступают открытый текст и
ключ шифрования, а в качестве выходных — зашифрованная форма открытого тек-
ста, которая называется шифрованным текстом. Детали алгоритма шифрования мо-
гут быть опубликованы или, по крайней мере, могут не утаиваться, но ключ шифрова-
ния обязательно хранится в секрете. Именно зашифрованный текст, непонятный всем,
кто не обладает ключом шифрования, хранится в базе данных и передается по комму-
никационным каналам.
Пример. Пусть в качестве открытого текста дана следующая строка.
AS KINGFISHERS CATCH FIRE
(Здесь для простоты изложения предполагается, что данные состоят только из пробе-
лов и прописных символов.) Кроме того, допустим, что ключом шифрования является
следующая строка.
ELIOT
Глава 16. Защита данных
621
Ниже описывается используемый алгоритм шифрования.
1. Разбейте открытый текст на блоки, длина которых равна длине ключа шифрования.
AS+KI NGFIS HERS+ CATCH +FIRE
(Здесь пробелы обозначены знаком
2. Замените каждый символ открытого текста целым числом в диапазоне 00-26, ис-
пользуя для пробела число 00, для А — число 01, ..., для Z — число 26. В результа-
те получится такая строка цифр.
0119001109 1407060919 0805181900 0301200308 0006091805
3. Повторите п. 2 для ключа шифрования, в результате чего получится следующая
строка цифр.
0512091520
4. Теперь значения, помещенные вместо каждого символа в каждом блоке открытого
текста, просуммируйте с соответствующими значениями, подставленными вместо
символов ключа шифрования, и для каждой суммы из указанных двух значений оп-
ределите и запишите остаток от деления на 27.
0119001109 1407060919 0805181900 0301200308 0006091805
0512091520 0512091520 0512091520 0512091520 0512091520
0604092602 1919152412 1317000720 0813021801 0518180625
5. Замените каждое число в нижней строке п. 4 соответствующим текстовым символом.
FDIZB SSOXL MQ+GT HMBRA ERRFY
Если ключ шифрования известен, то процедура расшифровки в этом примере может
быть выполнена достаточно просто. (Упражнение. Расшифруйте зашифрованный текст в
рассмотренном выше примере.) Вопрос заключается в том, насколько сложно нелегаль-
ному пользователю определить ключ шифрования, обладая открытым и зашифрованным
текстами. В данном простом примере это не очень сложно выполнить, однако вполне
очевидно, что можно разработать и более сложные схемы шифрования. В идеале, схема
шифрования должна быть такой, чтобы усилия, затраченные на ее расшифровку, во мно-
го раз превышали полученные при этом выгоды. (Фактически это замечание применимо
ко всем аспектам проблемы обеспечения безопасности, т.е. стоимость осуществления
попыток взлома системы защиты должна быть значительно выше потенциальной выгоды
от этого.) Предельной целью поиска таких схем следует считать схему, для которой сам
ее разработчик, обладая открытым и зашифрованным вариантами одной и той же части
текста, не в состоянии определить ключ и, следовательно, расшифровать другую часть
зашифрованного текста.
Стандарт шифрования данных
Приведенный выше пример основан на использовании процедуры подстановки:
ключ шифрования применялся для того, чтобы определить, какой символ зашифро-
ванного текста следует подставить вместо данного символа открытого текста. Под-
становка — один из двух основных традиционно используемых методов шифрования,
причем в качестве второго выступает процедура перестановки, когда символы откры-
того текста просто переставляются в некоторой последовательности. Ни один из этих
способов не является безопасным сам по себе, но алгоритмы, построенные на основе
622
Часть К Дополнительные аспекты
их комбинации, способны обеспечить достаточно высокую степень безопасности. Од-
ним из таких алгоритмов является Data Encryption Standard (DES), разработанный
фирмой IBM и принятый в 1977 году в качестве Федерального стандарта шифрования
данных США [16.18].
Согласно этому стандарту открытый текст делится на блоки по 64 бит и каждый блок
шифруется с помощью 64-битного ключа (в действительности этот ключ состоит из
56 бит данных и 8 бит четности, так что существует не 264, а только 256 возможных клю-
чей). Сначала блок шифруется путем перестановки, затем переставленные данные блока
подвергаются обработке посредством подстановки, включающей 16 последовательных
сложных шагов, после этого к данным еще раз применяется обратная начальной проце-
дура перестановки, которая и приводит к получению окончательного результата шифро-
вания. Подстановка на i-м шаге контролируется не самим исходным ключом шифрова-
ния К, а ключом Ki, который вычисляется на основе значений К и i. Более подробно этот
материал излагается в [16.18].
Стандартом шифрования данных предусматривается, что алгоритм расшифровки
идентичен алгоритму шифрования, но ключи Ki применяются в обратном порядке.
Шифрование на основе открытого ключа
В течение многих лет существовало предположение, что стандарт шифрования
данных DES не является абсолютно безопасным. Действительно, после создания
систем с большим количеством высокопроизводительных параллельных процессо-
ров стало ясно, что этот стандарт может быть взломан путем применения одной
лишь “грубой силы”, без использования каких-либо сложных методов расшифровки.
Многие специалисты считают, что по сравнению с самыми современными методами,
построенными на основе использования открытого ключа, стандарт шифрования
данных DES и подобные ему традиционные методы выглядят технологически уста-
ревшими. В методах с использованием открытого ключа внешнему миру доступны
как алгоритм шифрования, так и ключ шифрования, поэтому любой желающий мо-
жет преобразовать открытый текст в зашифрованный. Однако соответствующий
ключ расшифровки хранится в секрете (в методах открытого ключа используются
два ключа: один — для шифрования, другой — для расшифровки). Более того, ключ
расшифровки не может быть просто выведен из ключа шифрования, поэтому лицо,
выполнившее шифрование исходного текста, не сможет его расшифровать без спе-
циального разрешения.
Первоначальная идея использования такого метода принадлежит Диффи (Diffie) и
Хельману (Hellman) [16.7], однако здесь для демонстрации подобных методов будет опи-
сан наиболее известный подход, разработанный Райвестом (Rivest), Шамиром (Shamir) и
Аллеманом (Adleman) [16.15]. В основу этого подхода, названного RSA-схемой (по пер-
вым буквам фамилий его авторов), положены следующие два факта.
1. Существует быстрый алгоритм определения, является ли данное число простым.
2. Не существует быстрого алгоритма разложения данного составного числа (т.е. чис-
ла, которое не является простым) на простые множители.
В [16.10] приведен пример, в котором для определения, является ли число из 130
цифр простым, потребовалось 7 минут вычислений на некотором компьютере, тогда
как для поиска (на том же компьютере) двух простых множителей числа, получаемого
Глава 16. Защита данных
623
умножением двух простых чисел, состоящих из 63 цифр, потребуется около 40 квад-
рильонов лет (1 квадрильон = 1 000 000 000 000 000)4 * * * *.
RSA-схема предусматривает выполнение приведенной ниже последовательности
действий.
1. Выберите два произвольных и разных больших простых числа р и q, а затем вы-
числите их произведение г = р * д.
2. Выберите произвольное большое целое число е, которое является взаимно простым
(т.е. не имеет общих множителей) по отношению к произведению (р-1) * (д-1).
Это целое число е и будет служить ключом шифрования. Замечание. Выбрать чис-
ло е достаточно просто, например для него подойдет любое простое число, которое
больше чисел р и д.
3. Выберите в качестве ключа расшифровки число d, которое является “обратным от-
носительно умножения” на е по модулю (р-1) * (д-1), т.е. такое число, для кото-
рого выполняется следующее соотношение.
d * е = 1 modulo (р - 1) * (g - 1)
Алгоритм вычисления d для заданных чисел е, р и g достаточно прост и полностью
приведен в [16.15].
4. При этом огласке могут быть преданы числа г и е, но не d.
5. Для шифрования части открытого текста Р (который для простоты рассматривается
как целое число, меньшее г) заменим его зашифрованным текстом согласно сле-
дующей формуле.
С - Р modulo г
6. Для расшифровки части зашифрованного текста С замените его открытым текстом
Р, определяемым согласно следующей формуле.
Р = (? modulo г
В [16.15] доказывается работоспособность этой схемы, т.е. возможность расшифров-
ки текста С с использованием числа d для восстановления исходного открытого текста Р.
Однако, как упоминалось ранее, вычисление d для известных чисел г и е (а не р и д)
практически неосуществимо. Поэтому любой пользователь может зашифровать откры-
тый текст, но расшифровать зашифрованный текст смогут только санкционированные
пользователи (т.е. те, кто знают число d).
Для иллюстрации работы этого метода рассмотрим приведенный ниже простой при-
мер, в котором по очевидным причинам используются очень небольшие целые числа.
4 Несмотря на это некоторые сомнения существуют и в отношении RSA-схемы. Работа
[16.10] была опубликована в 1977 году, а в 1990 году Арьену Ленстра (Arjen Lenstra) и Мару Ма-
нассе (Mark. Manasse) удалось успешно разложить на простые множители число из 155 цифр
[16.22]. Они оценили, что выполненные вычисления, в которых участвовала тысяча компьюте-
ров, эквивалентны расчету на одном компьютере со скоростью 1 млн инструкций в секунду в те-
чение 273 лет. Данное число из 155 цифр было девятым числом Ферма: 25I2+1 (обратите внима-
ние, что 512 = 29). См. также работу [16.12], в которой сообщается о совершенно другом — и
успешном — подходе к расшифровке алгоритма RSA.
624
Часть И Дополнительные аспекты
Пример. Пусть р = 3, q = 5; тогда г = 15, а произведение (р-1) * (д-1) = 8. Пусть
е = 11 (простое число, большее р и д). Вычислим d согласно следующей формуле.
d * 11 = 1 modulo 8
В результате получим d = 3.
Теперь допустим, что открытый текст Р состоит из целого числа 13; тогда зашифро-
ванный текст С будет иметь следующий вид.
С = F modulo г
= 1311 modulo 15
= 1 792 160 394 037 modulo 15
= 7
Теперь исходный открытый текст Р может быть получен с помощью обратной
процедуры.
Р = (? modulo г
= 73 modulo 15
= 343 modulo 15
13 I
Поскольку числа е и d взаимно обратны, в методах шифрования на основе открытого
ключа также можно подписывать отсылаемые сообщения, что позволит получателю
иметь уверенность в том, что данное сообщение было получено именно от того лица, ко-
торое объявлено его отправителем (т.е. такая подпись не может быть подделана). Допус-
тим, что пользователи А и В общаются друг с другом с помощью метода шифрования на
основе открытого ключа. Пусть они предали гласности по одному алгоритму шифрова-
ния (с включением в каждый из них соответствующего ключа шифрования), но хранят в
секрете друг от друга алгоритм и ключ расшифровки. Пусть алгоритмы шифрования со-
общений ЕСА и ЕСВ используются для шифрования сообщений, посылаемых пользовате-
лям А и В соответственно, а отвечающими им алгоритмами расшифровки являются алго-
ритмы DCA и DCB. Следует отметить, что алгоритмы шифрования и расшифровки ЕСА и
DCA, как и алгоритмы ЕСВ и DCB, являются взаимно обратными.
Теперь предположим, что пользователь А хочет отослать часть открытого текста Р
пользователю В. Вместо вычисления результата ЕСВ(Р) и отправки его пользователю В
пользователь А сначала применяет для открытого текста Р алгоритм расшифровки DCA, а
затем зашифровывает полученный результат и в зашифрованном виде С передает его
пользователю В.
С = ЕСВ ( DCA ( Р ) )
После получения зашифрованного текста С пользователь В применяет сначала алго-
ритм расшифровки DCB, а затем — алгоритм шифрования ЕСА, что позволяет ему в ре-
зультате получить открытый текст Р.
ЕСА ( DCB ( С ) )
= ЕСА ( DCB ( ЕСВ ( DCA ( Р ) ) ) )
= ЕСА ( DCA ( Р ) ) // поскольку DCB и ЕСВ взаимно исключаются
= Р // поскольку ЕСА и DCA взаимно исключаются
Глава 16. Защита данных
625
Таким образом, пользователь В знает, что полученное им сообщение действи-
тельно пришло от пользователя А, поскольку алгоритм шифрования ЕСА приведет к
получению результата Р, только если в процессе шифрования применялся алгоритм
расшифровки DCA. Причем никто, даже пользователь В, не сможет подделать под-
пись пользователя А.
16.6 . Средства языка SQL
В действующем стандарте языка SQL предусматривается поддержка только избира-
тельного метода управления доступом. Она строится на основе двух более или менее не-
зависимых функций языка SQL. Первая из них является механизмом представлений,
который (как говорилось выше, в главе 8) может быть использован для сокрытия важных
данных от несанкционированных пользователей. Вторая функция называется подсисте-
мой полномочий и позволяет одним пользователям, обладающим определенными пра-
вами доступа, избирательно и динамично предоставлять эти полномочия другим пользо-
вателям, а также отменять предоставленные ими полномочия в случае необходимости.
Ниже эти функции языка SQL обсуждаются более подробно.
Представления и защита данных
Продемонстрируем использование представлений для организации защиты данных с
помощью записи на языке SQL примеров 2-4 из раздела 16.2.
2. CREATE VIEW LS AS
SELECT S.S#, S.SNAME, S.STATUS, S.CITY
FROM S
WHERE S, CITY = 'London' ;
Это представление определяет данные, по отношению к которым будут предостав-
лены некоторые привилегии. Само же предоставление привилегий осуществляется
с помощью операторов GRANT.
GRANT SELECT, UPDATE ( SNAME, STATUS ), DELETE
ON LS
TO Dan, Misha ;
Здесь следует отметить, что, поскольку привилегии задаются с помощью оператора
GRANT, а не с помощью гипотетического оператора CREATE AUTHORITY, привилегиям
в языке SQL имена не присваиваются. (Хотя для ограничений целостности стан-
дарт языка SQL, наоборот, предусматривает присвоение имен. Подробности при-
водятся в главе 8.)
3. CREATE VIEW SSPPR AS
SELECT S.S#, S.SNAME, S.STATUS, S.CITY
FROM S
WHERE EXISTS
( SELECT * FROM SP
WHERE EXISTS
( SELECT * FROM P
626
Часть V. Дополнительные аспекты
WHERE S.S# = SP.S#
AND SP.P# = P.P#
AND P.CITY = 'Rome' ) ) ;
Собственно предоставление привилегий выполняется с помощью следующего опе-
ратора GRANT.
GRANT SELECT ON SSPPR TO Giovanni ;
4. CREATE VIEW SSQ AS
SELECT S.S#, ( SELECT SUM (SP.QTY)
FROM SP
WHERE SP.S# = S.S# ) AS SQ
FROM S ;
Собственно предоставление привилегий выполняется с помощью следующего опе-
ратора GRANT.
GRANT SELECT ON SSQ TO Fidel ;
В примере 5 из раздела 16.2 демонстрируется предоставление контекстно-зависимых
полномочий. В языке SQL поддерживается несколько не имеющих аргументов встроен-
ных функций: CURRENT_USER, CURRENT_DATE, CURRENT_TIME и т.д., каждая из которых, по-
мимо всего прочего, может быть использована и для определения контекстно-зависимых
представлений. (Обратите внимание, что в языке SQL не поддерживается аналог опера-
тора DAY(), используемого в исходном варианте примера 5.) Ниже приводится пример
создания такого представления.
CREATE VIEW S NINE_TO_FIVE AS
SELECT’S.S#, S.NAME, S.STATUS, S.CITY
FROM S
WHERE CURRENT_TIME > TIME '09:00:00'
AND CURRENT_TIME < TIME '17:00:00'
Соответствующий оператор GRANT выглядит так.
GRANT SELECT, UPDATE ( STATUS )
ON S_NINE_TO_FIVE
TO Purchasing ;
Обратите внимание, что представление S_NINE_TO_FIVE демонстрирует очень
странный тип представлений, так как его содержимое меняется со временем, причем
даже в том случае, когда данные в базе вовсе не изменялись. Более того, представле-
ние, в определение которого встроен оператор CURRENT_USER, может (а точнее, скорее
всего, обязательно будет) иметь разное содержание для различных пользователей. Та-
кие “представления” действительно отличаются от традиционных представлений, по-
скольку по сути они являются параметризованными. Предпочтительнее было бы, по
крайней мере концептуально, разрешить пользователям определять собственные
(потенциально параметризованные) функции, оперирующие значениями в виде пере-
менных-отношений, и рассматривать “представления”, подобные S_NINE_TO_FIVE, в
качестве особых случаев таких функций.
Глава 16. Защита данных
627
Как бы там ни было, приведенные выше примеры хорошо иллюстрируют тот факт,
что механизм представлений косвенно обеспечивает важные функции защиты данных
(“косвенно” потому, что этот механизм включен в систему для достижения совсем дру-
гих целей). Более того, значительная часть процедуры контроля прав доступа (в том чис-
ле зависящая от конкретных значений) может быть выполнена еще на этапе компиляции,
а не во время выполнения, что позволяет достичь существенного выигрыша в произво-
дительности. Тем не менее подходу с использованием представлений для организации
защиты также свойственны определенные недостатки. В частности, некоторому пользо-
вателю в одно и то же время могут потребоваться разные права доступа в отношении
разных подмножеств данных одной и той же таблицы. В качестве примера можно при-
вести сложность реализации приложения, в котором пользователю разрешается про-
сматривать и распечатывать данные о деталях из Лондона, и дополнительно разрешается
обновлять данные о некоторых из них (например, только о красных деталях) непосредст-
венно в процессе просмотра.
Операторы GRANT и REVOKE
Механизм представлений языка SQL позволяет концептуально разделять базу дан-
ных на части таким образом, чтобы важная информация была скрыта от несанкциони-
рованных пользователей. Однако этот механизм не позволяет указывать тот набор
операций, которые разрешается применять в отношении данных частей санкциониро-
ванным пользователям. Подобная задача (как было показано выше) решается с помо-
щью оператора GRANT.
Обратите внимание, что в языке SQL создателю любого объекта автоматически пре-
доставляются все привилегии в отношении этого объекта. Например, создателю таблицы
Т автоматически разрешается выбирать (SELECT), вставлять (INSERT), обновлять (UPDATE),
удалять (DELETE) таблицу Т и ссылаться (REFERENCES) на нее (ниже эти привилегии разъ-
ясняются подробнее). Более того, привилегии в каждом случае даются “с правом их пе-
редачи”, т.е. обладатель некоторых полномочий в подобном случае имеет право предос-
тавить их и другим пользователям.
Ниже приводится общий синтаксис оператора GRANT.
GRANT < список привилегий^
ON <объект>
ТО <список идентификаторов пользователей^
[ WITH GRANT OPTION ] ;
Пояснения
Допустимыми значениями параметра <список привилегий^ могут быть ключе-
вые слова USAGE (использование), SELECT (выборка), INSERT (вставка), UPDATE
(обновление), DELETE (удаление) и REFERENCES (ссылка)5. Привилегия USAGE не-
обходима для получения права использования некоторого конкретного SQL-
домена, привилегия REFERENCES — для получения права обращаться к указанной
таблице при задании ограничений целостности. Назначение остальных привиле-
5 После добавления в стандарт в 1996 году понятия “постоянно хранимые модули"
(Persistent Stored Modules — PSM) появилась новая привилегия EXECUTE (выполнение).
628
Часть V. Дополнительные аспекты
гий очевидно. Однако следует отметить, что привилегии INSERT и UPDATE (но не
привилегия SELECT, что весьма странно) могут задаваться для конкретных ука-
занных столбцов таблиц.
Замечание. Также допустимо ключевое слово ALL PRIVILEGES (все привилегии),
но семантика его использования не столь проста, как кажется [4.19].
В качестве значения параметра <объект> может использоваться выражение DOMAIN
<имя домена> или выражение TABLE <имя таблицы>.
Замечание. В данном контексте— в отличие от большинства других случаев —
ключевое слово TABLE (которое на самом деле не является обязательным) относит-
ся как к представлениям, так и к базовым таблицам.
Значением параметра <список идентификаторов пользователей может быть
ключевое слово PUBLIC, обозначающее всех пользователей, которые известны
системе.
Если задана опция WITH GRANT OPTION, значит, перечисленные пользователи на-
деляются особыми полномочиями в отношении указанного объекта— правом
передачи полномочий. Это означает, что им разрешается предоставлять такие же
полномочия другим пользователям. Безусловно, опция WITH GRANT OPTION может
указываться только в том случае, когда задающий оператор GRANT пользователь
сам обладает необходимыми полномочиями.
Если пользователь А наделяет некоторыми полномочиями пользователя В, то впо-
следствии он может отменить эти полномочия пользователя В. Отмена полномочий вы-
полняется с помощью оператора REVOKE с приведенным ниже синтаксисом.
REVOKE [ GRANT OPTION FOR ] <список привилегий^
ON <объекч>
FROM <список идентификаторов пользователей
<опция> ;
Здесь фраза GRANT OPTION FOR означает, что отменяется только право передачи ука-
занных привилегий, предоставленное ранее этим пользователям. Значения параметров
<список привилегий?, <объект> и <список идентификаторов пользователей? аналогич-
ны значениям параметра оператора GRANT. Значениями параметра <опция> могут быть
ключевые слова RESTRICT (отклонить) и CASCADE (каскадно). Ниже приведены некоторые
примеры использования этого оператора.
1. REVOKE SELECT ON S FROM Jacques, Anne, Charley RESTRICT ;
2. REVOKE SELECT, INSERT, UPDATE (SNAME, STATUS), DELETE
ON LS FROM Dan, Misha CASCADE ;
3. REVOKE SELECT ON SSPPR FROM Giovanni RESTRICT ;
4. REVOKE SELECT ON SSQ FROM Fidel RESTRICT ;
Рассмотрим назначение ключевых слов RESTRICT и CASCADE. Допустим, что р являет-
ся некоторой привилегией для некоторого объекта и пользователь А предоставляет при-
вилегию р пользователю В, который, в свою очередь, предоставляет ее пользователю С.
Глава 16. Защита данных
629
Что произойдет, если теперь пользователь А отменит привилегию р для пользователя В?
Если эта отмена состоится, то привилегия р у пользователя С останется “покинутой”, по-
скольку она была производной от привилегии р пользователя В, который уже не обладает
ею. Основное назначение ключевых слов RESTRICT и CASCADE состоит в предотвращении
ситуаций возникновения покинутых привилегий. При задании ключевого слова RESTRICT
запрещается выполнять операцию отмены привилегии, если она приводит к появлению
покинутой привилегии. Ключевое слово CASCADE указывает на необходимость последо-
вательной отмены всех привилегий, производных от отменяемой.
Наконец, при удалении домена, базовой таблицы, столбца или представления автома-
тически будут удалены также все привилегии, предоставленные в отношении этих объек-
тов со стороны всех пользователей.
16.7. Резюме
В этой главе рассматривались различные аспекты проблемы защиты базы данных.
Во введении были показаны различия между понятиями защиты и целостности. Так,
под защитой подразумевается контроль за тем, разрешено ли санкционированным поль-
зователям выполнять предпринимаемые ими действия, тогда как под целостностью по-
нимается проверка корректности этих действий. Иначе говоря, под защитой понимается
защита данных от несанкционированного доступа, изменения или разрушения.
Защита обеспечивается подсистемой защиты СУБД, проверяющей соответствие
всех поступающих запросов существующим ограничениям защиты, которые со-
храняются в системном каталоге. Сначала были рассмотрены избирательные схемы
защиты, в которых доступ к конкретному объекту определялся владельцем объекта.
Для каждого ограничения безопасности в избирательной схеме задаются имя, мно-
жество привилегий (RETRIEVE, UPDATE и т.д.), соответствующая переменная-
отношение (т.е. данные, к которым применимы указанные ограничения) и множест-
во пользователей. Такие правила могут применяться для организации управления
как зависящего, так и не зависящего от конкретных значений, а также для ста-
тистически-обобщенного и контекстно-зависимого управления. Для регистрации
попыток нарушения защиты может использоваться контрольное слежение за вы-
полнением операций. В данной главе было представлено краткое описание метода
реализации избирательной схемы защиты на основе механизма модификации за-
проса. Впервые эта технология была применена в прототипе системы INGRES с ис-
пользованием средств языка QUEL.
Далее кратко рассматривались методы мандатного управления, согласно которым
каждый объект должен обладать некоторым классификационным уровнем (или гри-
фом), а каждому пользователю должен быть присвоен определенный уровень допуска.
Помимо описания правил доступа для такой схемы, кратко рассматривалась классифика-
ция мер безопасности, регламентированная Министерством обороны США [16.19],
[16.20]. Дополнительно приводились идеи создания многоуровневых переменных-
отношений и методы полиреализации.
Затем обсуждались особенности работы со статистическими базами данных. Ста-
тистической называется база данных, которая содержит большое количество отдельных
конфиденциальных сведений и пользователям которой может предоставляться только
некоторая статистически обобщенная информация. Было показано, что защита такой ба-
630
Часть V. Дополнительные аспекты
зы данных легко может быть нарушена с помощью выражений-трекеров. (Этот факт
должен вызывать определенную тревогу в связи с возрастающим интересом к хранили-
щам данных, подробное описание которых приводится в главе 21.)
Также были описаны методы шифрования данных с использованием методов под-
становки и перестановки, приведены разъяснения в отношении стандарта шифрования
данных DES и кратко рассмотрены методы шифрования с помощью открытых ключей.
В частности, был приведен простой пример использования RSA-схемы для данных,
представляющих собой простые числа. Кроме того, была описана концепция применения
цифровых подписей.
После этого были кратко изложены меры безопасности, которые поддерживаются в
стандарте языка SQL. В частности, обсуждалось использование представлений для со-
крытия информации и применение директив GRANT и REVOKE для управления наборами
привилегий, предоставленных конкретным пользователям в отношении различных объ-
ектов базы данных (в основном, это базовые таблицы и представления).
В заключение, вероятно, стоит отметить, что будет мало проку от СУБД, пре-
доставляющей большое количество функций защиты, каждую из которых можно
легко преодолеть. Например, в СУБД DB2 данные базы физически хранятся в
файлах операционной системы. Следовательно, любые механизмы защиты в сис-
теме DB2 были бы совершенно бесполезны, если бы было возможно получить
доступ к этим файлам с помощью обычной программы, использующей обычные
средства операционной системы. Поэтому СУБД DB2 согласованно взаимодейст-
вует с другими параллельно существующими системами (например, с базовой
операционной системой), что дает ей гарантии общей защищенности системы.
Подробное изложение этого аспекта защиты выходит за рамки данной главы, од-
нако указанную особенность все же стоило упомянуть.
Упражнения
16.1. Пусть базовая переменная-отношение STATS выглядит так, как в разделе 16.4.
STATS { NAME, SEX, CHILDREN, OCCUPATION, SALARY, TAX, AUDITS }
PRIMARY KEY { NAME }
Используя гипотетический язык, представленный в разделе 16.2, запишите опреде-
ления ограничений защиты для предоставления перечисленных ниже привилегий:
а) пользователь Ford обладает правом выборки из всего отношения;
б) пользователь Smith обладает правом вставки и удаления данных для всего от-
ношения;
в) каждый пользователь обладает правом выборки кортежа (одного) со своими
личными данными;
г) пользователь Nash обладает правом выборки из всего отношения и правом об-
новления атрибутов SALARY и ТАХ (только);
д) пользователь Todd обладает правом выборки атрибутов USERID, SALARY и ТАХ
(только);
е) пользователь Ward обладает такими же правами выборки, как и пользователь
Todd, а также правом обновления атрибутов SALARY и ТАХ (только);
Глава 16. Защита данных
631
ж) пользователь Pope обладает всеми правами (извлечения, обновления, вставки и
удаления), но только в отношении кортежей с данными о проповедниках;
з) пользователь Jones обладает правом удаления кортежей с данными о лицах, за-
нимающих неспециализированные должности, т.е. должности, которые зани-
мают более 10 работников;
и) пользователь King обладает правом выборки данных о минимальной и макси-
мальной зарплатах для каждого из существующих типов рабочих мест.
16.2. Как следует расширить синтаксис определений полномочий AUTHORITY для вклю-
чения в него средств управления такими операциями, как создание и удаление ба-
зовых переменных-отношений, создание и удаление представлений, создание и
удаление полномочий и т.д.?
16.3. Еще раз обратимся к рис. 16.2 и предположим, что из посторонних источников
получены сведения о том, что персона с именем 'Hal' является домохозяйкой с
двумя детьми. Запишите последовательность статистических запросов, позво-
ляющих определить размер выплачиваемых ею налогов, используя подходящий
индивидуальный трекер. Предположим (как и в разделе 16.4), что в системе не
разрешены запросы, имеющие результирующие множества с кардинальностью
менее 2 или более 8.
16.4. Повторите упр. 16.3, но используя общий трекер вместо индивидуального.
16.5. Расшифруйте приведенный ниже зашифрованный текст, созданный по тому же
принципу, который был использован в примере из настоящей главы для строки
AS KINGFISHERS CATCH FIRE, но с помощью другого 5-символьного ключа шиф-
рования.
F N W A L
J Р V J С
F Р Е X Е
А В W N Е
A Y Е I Р
S U S V D
16.6. Испытайте RSA-схему шифрования на основе открытого ключа с р = 7, g = 5 и
е = 17 для открытого текста Р = 3.
16.7. Какие проблемы реализации или проблемы другого типа могут возникнуть при ис-
пользовании шифрования?
16.8. Используя язык SQL, запишите решения для упр. 16.1.
16.9. Запишите SQL-команды для удаления привилегий, установленных в предыдущем
упражнении.
Список литературы
Обширный обзор методов защиты представлен в книге Кастано [16.2], а более
подробное техническое описание — в книге Деннинга [16.5]. Остальные приведен-
ные здесь ссылки указывают на технические документы или статьи (учебные посо-
бия и научно-исследовательские работы) по различным аспектам проблемы защи-
ты данных, включая несколько журнальных публикаций.
632
Часть V. Дополнительные аспекты
16.1. Bell D.E., La Padula L.J. Secure Computer Systems: Mathematical Foundations and
Model. — MITRE Technical Report M74-244. — May, 1974.
16.2. Castano S., Fugini M., Martella G., Samarati P. Database Security. — New York, N.Y.:
ACM Press/Reading, Mass.: Addison-Wesley. — 1995.
16.3. Daly J. Fingerprinting a Computer Security Code // Computerworld. — July, 1992.
16.4. Date. C.J. Security // Chapter 4 in C. J. Date. An Introduction to Database Systems:
Volume II. — Reading. Mass.: Addison-Wesley, 1983.
16.5. Denning D.E. Cryptography and Data Security. — Reading, Mass.: Addison-Wesley, 1983.
16.6. Denning D.E., Denning P.J. Data Security // ACM Comp. Surv. — September,
1979.— 11,№3.
Прекрасное учебное пособие, посвященное средствам защиты, с описанием
избирательных и мандатных методов управления доступом (здесь они называ-
ются потоковыми методами управления), методов шифрования данных и
контроля возможности логического вывода (эта проблема характерна для ста-
тистических баз данных).
16.7. Diffe W., Hellman М.Е. New Directions in Cryptography // IEEE Trans, on Information
Theory. —November, 1976. — IT-22.
16.8. Fagin R. On an Authorization Mechanism // ACM TODS. — September, 1978. — 3, № 3.
Подробное изложение поправки к [16.11] о некоторых условиях, способных при-
вести к отмене привилегии, которую нельзя отменить с помощью механизма, опи-
санного в [16.11].
16.9. Gagliardi R., Lapis G., Lindsay В. A Flexible and Efficient Database Authorization
Facility // IBM Research Report RJ6826. — May, 1989.
16.10. Gardner M. A New Kind of Cipher That Would Take Millions of Years to Break //
Scientific American. — August, 1977. — 237, № 2.
Прекрасное неформальное введение в теорию шифрования с использованием от-
крытых ключей, хотя выбранное название несколько преувеличено [16.12], [16.22].
16.11. Griffiths Р.Р., Wade B.W. An Authorization Mechanism for a Relational Data Base
System // ACM TODS. — September, 1976. — 1, № 3.
Описание механизмов предоставления (GRANT) и отмены (REVOKE) привилегий,
впервые предложенных для системы System R. Впоследствии эта схема в несколь-
ко измененном виде была включена в стандарт языка SQL.
16.12. Hawkes N. Breaking into the Internet // London Times. — March 18-th, 1996.
Описание “взлома” опытным специалистом в области компьютерных технологий
RSA-схемы посредством измерения продолжительности шифрования сообщений:
“электронный эквивалент определения номера телефона по продолжительности
поворота номеронабирателя”.
16.13. Jajodia S., Sandhu R. Toward a Multilevel Secure Relational Data Model // Proc. 1991
ACM SIGMOD Intern. Conf, on Management of Data. — Denver, Col., June, 1991.
Как объяснялось в разделе 16.3, “многоуровневая структура” в контексте
средств защиты относится к системе, в которой поддерживаются методы ман-
датного управления доступом. В статье утверждается, что вся текущая дея-
тельность в этой области, в основном, выполняется спонтанно, поскольку не
Глава 16. Защита данных
633
существует единого мнения в отношении главных концепций. Кроме того, в
этой работе подчеркивается необходимость разработки формальных принци-
пов многоуровневых систем.
16.14. Lempel A. Cryptology in Transition // ACM Comp. Surv.— December, 1979.— 11,
№ 4 (Special Issue on Cryptology).
Прекрасное учебное пособие по шифрованию и связанным с ним вопросам.
16.15. Rivest R.L., Shamir A., Adleman L. A Method for Obtaining Digital Signatures and
Public-Key Cryptosystems // CACM. — February, 1978. — 21, № 3.
16.16. Smith K., Winslett M. Entity Modeling in the MLS Relational Model 11 Proc. 18th Intern.
Conf, on Very Large Data Bases. — Vancouver, Can., August, 1992.
Аббревиатура MLS в заголовке статьи означает “многоуровневая защита”
(MultiLevel Secure— MLS) [16.13]. В статье внимание акцентируется на смысле
баз данных с такой защитой и предлагается предложение нового типа (BELIEVED
BY) для определения операций выборки и обновления по отношению к некоторому
особому состоянию базы данных, которое воспринимается или “принимается [как
точно соответствующее]” некоторым пользователем. В статье утверждается, что
этот подход поможет разрешить несколько проблем, существовавших при исполь-
зовании прежних подходов [16.21].
16.17. Thuraisingham В. Current Status of R&D in Trusted Database Management Systems //
ACM SIGMOD. — September, 1992. — 21, № 3.
Краткий обзор и обширный набор ссылок на работы о “надежных” или многоуров-
невых системах (по состоянию на начало 1990-х годов).
16.18. U.S. Department of Commerce/National Bureau of Standards. Data Encryption
Standard. — Federal Information Processing Standards Publication 46, January, 1977.
В работе дано определение официального стандарта шифрования данных (Data
Encryption Standard — DES), используемого как федеральными учреждениями
США, так и всеми желающими. Этот алгоритм шифрования/расшифровки (см.
раздел 16.5) может быть реализован и на аппаратном уровне, например в микро-
процессоре. При этом устройства с таким микропроцессором демонстрируют
весьма высокую интенсивность обмена данными. В настоящее время существует
несколько таких коммерческих устройств.
16.19. U.S. Department of Defense. Trusted Computer System Evaluation Criteria
(“Оранжевая” книга). — Document № DoD 5200-28-STD, DoD National Computer
Security Center. — December, 1985.
16.20. U.S. National Computer Security Center. Trusted Database Management System
Interpretation (“Сиреневая” книга).— Document № NCSC-TG-201, Version 1.—
April, 1991.
16.21. Winslett M., Smith K., Qian X. Formal Query Languages for Secure Relational
Databases // ACM TODS. — December, 1994. — 19, № 4.
Продолжение работы [16.16].
16.22. Wolf R. How Safe Is Computer Data? A Lot of Factors Govern the Answer // San Jose
Mercury News. — July 5-th, 1990.
634
Часть К. Дополнительные аспекты
Ответы к некоторым упражнениям
6.1.
a) AUTHORITY AAA
GRANT RETRIEVE ON STATS TO Ford ;
6) AUTHORITY BBB
GRANT INSERT, DELETE ON STATS TO Smith ;
в) AUTHORITY CCC
GRANT RETRIEVE
ON STATS
WHEN USER () = NAME
TO ALL ;
Здесь предполагается, что в качестве идентификаторов пользователей в системе
применяются их имена. Обратите внимание на использование предложения
WHEN и встроенной функции USER().
г) AUTHORITY DDD
GRANT RETRIEVE, UPDATE ( SALARY, TAX )
ON STATS
TO Nash ;
д) AUTHORITY EEE
GRANT RETRIEVE ( USERID, SALARY, TAX )
ON STATS
TO Todd ;
e) AUTHORITY FFF
GRANT RETRIEVE ( USERID, SALARY, TAX ),
UPDATE ( SALARY, TAX )
ON STATS
TO Ward ;
ж) VAR PREACHERS VIEW
STATS WHERE OCCUPATION = 'Preacher' ;
AUTHORITY GGG
GRANT ALL
ON PREACHERS
TO Pope ;
Обратите внимание на необходимость использования представления в данном случае.
з) VAR NONSPECIALIST VIEW
WITH ( STATS RENAME OCCUPATION AS X ) AS Tl,
( EXTEND STATS
ADD COUNT ( Tl WHERE X = OCCUPATION ) AS Y ) AS T2,
( T2 WHERE Y > 10 ) AS T3 :
T3 { ALL BUT Y }
AUTHORITY HHH
Глава 16. Защита данных
635
GRANT DELETE
ON NONSPECIALIST
TO Jones ;
и) VAR JOBMAXMIN VIEW
WITH ( STATS RENAME OCCUPATION AS X ) AS Tl,
( EXTEND STATS
ADD MAX ( Tl WHERE X = OCCUPATION, SALARY ) AS MAXSAL,
MIN ( Tl WHERE X = OCCUPATION, SALARY ) AS MINSAL )
AS T2 :
T2 { OCCUPATION, MAXSAL, MINSAL }
AUTHORITY III
GRANT RETRIEVE ON JOBMAXMIN TO King ;
16.2. Здесь необходимо отметить, что пользователя, который обладает привилегией соз-
дания новой базовой переменной-отношения и действительно создает такую пере-
менную-отношение, следует рассматривать как владельца этого нового объекта. В
языке SQL владелец некоторой базовой переменной-отношения автоматически на-
деляется всеми возможными привилегиями по отношению к нему, включая не
только операции RETRIEVE, INSERT, UPDATE и DELETE, но и право передачи своих
полномочий для данного отношения другим пользователям.
16.3. Индивидуальный трекер для домохозяйки с именем ' Hal' будет иметь следующий вид.
CHILDREN > 1 AND NOT ( OCCUPATION = 'Homemaker' )
Рассмотрим приведенную ниже последовательность запросов.
COUNT ( STATS WHERE CHILDREN > 1 )
Результат: 6.
COUNT ( STATS WHERE CHILDREN > 1 AND NOT
( OCCUPATION = 'Homemaker' )
Результат: 5.
Следовательно, выражение
CHILDREN > 1 AND OCCUPATION = 'Homemaker'
единственным образом идентифицирует домохозяйку с именем 'Hal'.
SUM ( STATS WHERE CHILDREN >1, TAX )
Результат: 48 000.
SUM ( STATS WHERE CHILDREN > 1 AND NOT
( OCCUPATION = 'Homemaker' ), TAX )
Результат: 46 000.
Отсюда следует, что размер налогов для домохозяйки с именем ' Hal' равен 2 000. |
16.4. Общий трекер в этом случае будет иметь следующий вид: SEX = 'F'.
SUM ( STATS WHERE SEX = 'F', TAX )
Результат: 70 000.
636
Часть V. Дополнительные аспекты
SUM ( STATS WHERE NOT ( SEX = 'F' ), TAX )
Результат: 16 000.
Следовательно, общий размер налогов составляет 86 000.
SUM ( STATS WHERE ( CHILDREN > 1 AND
OCCUPATION = 'Homemaker' ) OR
SEX = 'F', TAX )
Результат: 72 000.
SUM ( STATS WHERE ( CHILDREN > 1 AND
OCCUPATION = 'Homemaker' ) OR NOT
( SEX = 'F' ), TAX )
Результат: 16 000.
Сложив два последних результата (88 000) и вычтя из них полученное выше
общее значение налогов (86 000), имеем, что размер налогов для домохозяйки
'Hal' равен 2 000. |
16.5. Открытый текст имеет следующий вид.
1. EYES I DARE NOT MEET IN DREAMS
Какой был использован ключ шифрования?
16.7. Одна из проблем заключается в том, что данные внутри системы, в которой вы-
полняется шифрование, должны обрабатываться в открытом виде (например, что-
бы корректно выполнялись операции сравнения). Поэтому все еще существует
риск прямого доступа к очень важным данным с помощью параллельно работаю-
щих приложений или выявления содержания этих данных в распечатке состояния
памяти, выведенной на внешний носитель. Кроме того, существует несколько тех-
нических проблем, связанных с индексированием зашифрованных данных и веде-
нием для таких данных файла протокола.
a) GRANT SELECT ON STATS TO Ford ;
6) GRANT INSERT, DELETE ON STATS TO Smith ;
в) CREATE VIEW MINE AS
SELECT STATS.*
FROM STATS
WHERE STATS.NAME = CURRENTJJSER ;
GRANT SELECT ON MINE TO PUBLIC ;
Здесь предполагается, что в качестве идентификаторов пользователей приме-
няются их имена. Обратите внимание на использование встроенного оператора
CURRENTJJSER ().
г) GRANT SELECT, UPDATE ( SALARY, TAX ) ON STATS TO Nash ;
д) CREATE VIEW UST AS
SELECT STATS.NAME, STATS.SALARY, STATS.TAX
FROM STATS ;
GRANT SELECT ON UST TO Todd ;
Глава 16. Защита данных
637
16.9.
При использовании языка SQL здесь потребуется применить представление, так
как в нем не поддерживаются особые привилегии на выборку столбцов.
е) GRANT SELECT, UPDATE ( SALARY, TAX ) ON UST TO Ward ;
В этом решении используется то же представление, что и в предыдущем.
ж) CREATE VIEW PREACHERS AS
SELECT STATS.*
FROM STATS
WHERE STATS.OCCUPATION = 'Preacher' ;
GRANT ALL PRIVILEGES ON PREACHERS TO Pope ;
Обратите внимание на использование в данном примере сокращения ALL
PRIVILEGES (все привилегии). (Директива ALL PRIVILEGES означает буквально
не все привилегии, а лишь привилегии для данного объекта, которые один
пользователь может делегировать другому с помощью директивы GRANT.)
з) CREATE VIEW NONSPECIALIST AS
SELECT STX.*
FROM STATS AS STX
WHERE ( SELECT COUNT(*)
FROM STATS AS STY
WHERE STY.OCCUPATION = STX.OCCUPATION ) > 10;
GRANT DELETE ON NONSPECIALIST TO Jones ;
и) CREATE VIEW JOBMAXMIN AS
SELECT STATS.OCCUPATION,
MAX ( STATS.SALARY ) AS MAXSAL,
MIN ( STATS.SALARY ) AS MINSAL
FROM STATS
GROUP BY STATS.OCCUPATION ;
GRANT SELECT ON JOBMAXMIN TO King ;
a) REVOKE SELECT ON STATS FROM Ford RESTRICT ;
6) REVOKE INSERT, DELETE ON STATS FROM Smith RESTRICT ;
в) REVOKE SELECT ON MINE FROM PUBLIC RESTRICT ;
r) REVOKE SELECT, UPDATE ( SALARY, TAX )
ON STATS FROM Nash RESTRICT ;
д) REVOKE SELECT ON UST FROM Todd RESTRICT ;
e) REVOKE SELECT, UPDATE ( SALARY, TAX )
ON UST FROM Ward RESTRICT ;
ж) REVOKE ALL PRIVILEGES ON PREACHERS FROM Pope RESTRICT ;
з) REVOKE DELETE ON NONSPECIALIST FROM Jones RESTRICT ;
и) REVOKE SELECT ON JOBMAXMIN FROM King RESTRICT ;
638
Часть V. Дополнительные аспекты
Глава
Оптимизация
17.1. Введение
Для реляционных систем оптимизация представляет собой как проблему, так и благо-
приятную возможность. Проблема состоит в том, что для достижения приемлемого
уровня производительности оптимизация в подобных системах просто необходима. При-
чем одной из сильных сторон и несомненных достоинств реляционного подхода является
то, что реляционные выражения реализуются и оптимизируются на достаточно высоком
семантическом уровне. В противоположность этому в нереляционных системах, где за-
просы пользователей выражаются на более низком семантическом уровне, любая
“оптимизация” должна выполняться самим пользователем вручную (здесь термин
“оптимизация” взят в кавычки, поскольку обычно он употребляется для обозначения ав-
томатической, а не ручной оптимизации). В подобных системах пользователь (а не сис-
тема) определяет, какие именно низкоуровневые операции должны быть выполнены и в
какой последовательности. И если пользователь принял неправильное решение, то сис-
тема никак не сможет исправить положение. Заметьте также, что для работы в подобных
системах пользователь должен обладать некоторыми навыками в программировании,
иначе он не сможет достаточно полно их применять.
Преимущество автоматической оптимизации заключается в том, что пользователь
может не задумываться над наилучшим способом выражения своих запросов (т.е. над
тем, как следует сформулировать запрос, чтобы система выполнила его с максимальной
производительностью). Но и это далеко не все. Вполне вероятно, что оптимизатор сфор-
мулирует запрос лучше, чем сам пользователь. Для подобного утверждения есть не-
сколько веских причин. Ниже приведены лишь некоторые из них.
1. Хороший оптимизатор— обратите внимание на слово “хороший”!— обладает
большим объемом полезной информации, которая пользователю обычно недоступ-
на. Говоря конкретнее, оптимизатор владеет определенными статистическими
данными, в частности перечисленными ниже:
количество значений в каждом домене;
текущее количество значений в каждой базовой переменной-отношении;
текущее количество различающихся значений для каждого атрибута в базовой
переменной-отношении;
количество вхождений каждого значения в каждом из атрибутов и т.п.
(Вся эта информация хранится в системном каталоге, о чем речь пойдет ниже в
этой главе, в разделе 17.5.) Благодаря наличию таких данных оптимизатор спосо-
бен более точно оценить эффективность любой возможной стратегии реализации
конкретного запроса. Исходя из полученных результатов он сможет выбрать наи-
лучшую стратегию реализации запроса.
Глава 17. Оптимизация
639
2. Если со временем статистические показатели базы данных значительно изменятся
(например, в результате ее физической реорганизации), то при реализации запроса
может оказаться целесообразнее использовать иную стратегию, отличную от при-
менявшейся ранее. Другими словами, возникнет необходимость в повторной опти-
мизации или реоптимизации. В реляционных системах процесс реоптимизации
вполне тривиален и сводится к простой повторной обработке исходного запроса
системным оптимизатором. В нереляционных же системах выполнение реоптими-
зации, как правило, требует переписывания программы и, вполне возможно, может
оказаться вообще невыполнимым.
3. Оптимизатор— это программа, которая по определению более “настойчива”, чем
человек. Оптимизатор способен рассматривать буквально сотни различных стратегий
реализации конкретного запроса, в то время как программист едва ли проанализирует
более трех-четырех возможных стратегий (по крайней мере, достаточно глубоко).
4. В оптимизаторе реализованы знания и опыт “лучших из лучших” программистов, в
результате чего эти знания и опыт становятся доступными для всех. Это позволяет
применять ограниченный набор ресурсов, предоставленный широкому кругу поль-
зователей, наиболее эффективно и экономично.
Приведенные выше соображения служат убедительным доказательством сделанного
в начале данного раздела заявления о том, что оптимизируемость (т.е. возможность оп-
тимизации запросов) является сильной стороной реляционных систем.
Общее назначение оптимизатора состоит в выборе наиболее эффективной стратегии
вычисления реляционного выражения. В этой главе описаны некоторые фундаментальные
принципы и методы, применяемые в процессе оптимизации. После обсуждения вступи-
тельного примера, приведенного в разделе 17.2, в разделе 17.3 предложен обзор принципов
работы оптимизатора. Затем, в разделе 17.4, обсуждается один из важнейших аспектов
процедуры оптимизации — преобразование выражений (или переписывание запроса). Да-
лее, в разделе 17.5, кратко излагается вопрос о статистических показателях базы данных.
В разделе 17.6 дается более подробное описание одного из конкретных методов оптимиза-
ции, известного как декомпозиция запросов. Затем, в разделе 17.7, обсуждается вопрос о
том, как в действительности реализуются некоторые реляционные операторы (например,
оператор JOIN), и кратко описывается использование рассматривавшихся в разделе 17.5
статистических показателей для вычисления стоимостных оценок. И наконец в разделе 17.8
приводится краткое резюме по всему материалу данной главы.
Еще одно вводное замечание. Достаточно часто на данную тему ссылаются, как на
оптимизацию запросов. Однако подобный термин несколько неточен, поскольку выра-
жение, которое нужно оптимизировать (“запрос”), на самом деле может формироваться в
контексте, отличном от интерактивного опроса базы данных. В частности, оно может
быть частью операции обновления, а не операции выборки, понимаемой под запросом.
Более того, сам по себе термин оптимизация является несколько преувеличенным, так
как не существует гарантий, что выбранная стратегия реализации действительно опти-
мальна в любом понимании. На практике под “оптимизированной” стратегией реализа-
ции обычно понимается несколько улучшенный вариант исходного не оптимизированно-
го выражения. (Тем не менее в некоторых немногочисленных случаях можно вполне
обоснованно утверждать, что выбранная стратегия реализации будет действительно оп-
тимальной в определенном смысле [17.31].)
640
Часть V. Дополнительные аспекты
17.2. Пример выполнения оптимизации
Начнем изложение с простого примера (он уже кратко рассматривался в разделе 6.6),
дающего представление о поразительных результатах, которых можно достичь с помо-
щью оптимизации. Рассмотрим следующий запрос: “Определить имена поставщиков де-
тали с номером 'Р2'”. Алгебраическая запись этого запроса такова.
( ( SP JOIN S ) WHERE P# = P# ( 'P2' ) ) { SNAME }
Предположим, что в базе данных содержится информация о 100 поставщиках и 10 000
поставках деталей, из которых только 50 включают партии деталей с номером ' Р2'. Пред-
положим для простоты, что переменные-отношения S и SP сохраняются на диске, как два
отдельно хранимых файла, в каждой записи которых помещается по одному кортежу дан-
ных. В этом случае, если система будет вычислять данное выражение “прямо” (т.е. вообще
без оптимизации), последовательность выполняемых операций будет такой.
1. Соединение переменных-отношений SP и S (по атрибуту Si). При выполнении
этой операции потребуется считать информацию о 10 000 поставках партий дета-
лей и 10 000 раз считать информацию о 100 поставщиках (один раз для каждой по-
ставки деталей). В результате будет получен промежуточный набор данных, со-
держащий 10 000 соединенных кортежей. Этот набор данных записывается на диск
(предположим, что для размещения промежуточного результата в основной
(оперативной) памяти не хватает места).
2. Выборка из полученного на этапе 1 результата кортежей с данными о детали
с номером ' Р2'. На этом этапе выполняется чтение 10 000 соединенных кортежей
обратно в оперативную память, причем полученный результат состоит только из 50
кортежей, которые, по нашему предположению, вполне могут поместиться в опе-
ративной памяти.
3. Выполнение проекции по атрибуту SNAME результата, полученного на эта-
пе 2. На этом этапе формируется результирующий набор исходного запроса (со-
стоящий максимум из 50 кортежей, которые вполне могут быть размещены в
оперативной памяти).
Представленная ниже процедура полностью эквивалентна описанной выше в том
смысле, что она обязательно приведет к тому же конечному результату, но он будет по-
лучен более эффективным способом.
1. Выборка из переменной-отношения SP кортежей с данными только о детали с
номером fP2f. На этом этапе выполняется чтение 10 000 кортежей и создается ре-
зультирующий набор, состоящий только из 50 кортежей, который, как мы предпо-
лагаем, может поместиться в оперативной памяти.
2. Соединение полученного на этапе 1 результата с переменной-отношением S
(по атрибуту Si). На этом этапе выполняется считывание данных обо всех 100 по-
ставщиках (но только один раз, а не по одному разу для каждой поставки партии
деталей, так как данные обо всех поставленных партиях деталей с номером ' Р2'
уже находятся в оперативной памяти). Результат содержит 50 соединенных корте-
жей (которые также помещаются в оперативной памяти).
Глава 17. Оптимизация
641
3. Выполнение проекции по атрибуту SNAME результата, полученного на этапе 2
(аналогично этапу 3 предыдущей последовательности действий). Требуемый ре-
зультат (не более 50 кортежей) помещается в оперативной памяти.
В первой из показанных процедур в целом выполняется 1 030 000 операций ввода-
вывода кортежей, в то время как во второй процедуре выполняется только 10 100 опера-
ций ввода-вывода. Следовательно, совершенно очевидно, что если принять в качестве
меры оценки производительности количество выполненных операций ввода-вывода кор-
тежей, то вторая процедура в 100 раз эффективнее первой. (На практике мерой оценки
производительности служит количество операций ввода-вывода страниц, а не отдельных
кортежей, но для данного примера это уточнение можно игнорировать.) Кроме того,
вполне понятно, что предпочтительнее реализовать данный запрос именно с помощью
второй процедуры, а не первой!
Приведенный пример показывает, что следствием даже незначительных изменений в
алгоритме реализации (выполнения выборки, а затем соединения вместо соединения и
последующей выборки) может быть существенное увеличение производительности.
Производительность повысится еще больше, если переменная-отношение SP будет ин-
дексирована или хеширована по атрибуту Р#. В этом случае количество кортежей, счи-
тываемых на этапе 1 второй процедуры, уменьшится с 10 000 до всего лишь 50, в резуль-
тате чего вся процедура окажется в 7 000 раз эффективнее ее исходного варианта. Ана-
логично этому наличие индекса или хеш-таблицы для атрибута S.S# позволит уменьшить
количество операций ввода-вывода кортежей на этапе 2 со 100 до 50, в результате чего
процедура вычисления запроса окажется более чем в 10 000 раз эффективнее исходного
варианта. Это означает, что если на вычисление исходного варианта реализации запроса
потребуется 3 часа, то оптимизированная версия этого же запроса будет выполнена за
одну секунду. К тому же, безусловно, возможны и многие другие улучшения.
Несмотря на то что приведенный выше пример достаточно прост, он весьма наглядно
демонстрирует необходимость использования оптимизации. Кроме того, он демонстри-
рует вероятные типы улучшений, которые могут применяться на практике. В следующем
разделе используется более систематический подход к решению проблемы оптимизации.
В частности, в нем показано, как общая проблема может быть разделена на последова-
тельность из нескольких более или менее независимых подзадач. Это позволит нам пе-
рейти к рассмотрению отдельных стратегий и приемов оптимизации, обсуждаемых в по-
следующих разделах.
17.3. Оптимизация запросов
Рассмотрим четыре стадии процесса оптимизации запросов, который схематически
представлен на рис. 17.1.
1. Преобразование запроса во внутреннюю форму.
2. Преобразование запроса в каноническую форму.
3. Выбор потенциальных низкоуровневых процедур.
4. Генерация различных вариантов планов вычисления запроса и выбор плана с ми-
нимальными затратами.
Перейдем к подробному рассмотрению каждой стадии процесса оптимизации.
642
Часть V. Дополнительные аспекты
Рис. 17.1. Общая схема процесса оптимизации запроса
Стадия 1. Преобразование запроса во внутреннюю форму
На этой стадии выполняется преобразование запроса в некоторое внутреннее пред-
ставление, более удобное для машинных манипуляций. В результате из рассмотрения
полностью исключаются конструкции сугубо внешнего уровня (например, разнообраз-
ные варианты конкретного синтаксиса используемого языка запросов) и готовится почва
для последующих стадий оптимизации.
Замечание. Обработка представлений (т.е. процесс замены ссылок на представления
выражениями, определяющими соответствующие представления) также выполняется на
этом этапе.
Возникает очевидный вопрос: “Какое формальное представление должно использо-
ваться для внутреннего представления запроса?”. Независимо от того, какой именно ва-
риант формального представления будет выбран, он должен быть достаточно полным,
чтобы допускать представление любых запросов, которые могут быть определены на
внешнем языке системы. Кроме того, выбранный способ формального представления
должен быть нейтральным, насколько это возможно, в том смысле, что он не должен за-
ранее предопределять последующих оптимизационных решений. Чаще всего для внут-
реннего представления запросов используется та или иная модификация абстрактного
синтаксического дерева, которое в этом случае называется деревом запроса. Напри-
мер, на рис. 17.2 показано дерево для запроса, рассматривавшегося выше в этой же главе
(“Определить имена поставщиков детали с номером 'Р2'”).
Глава 17. Оптимизация
643
Окончательный результат
т
Проекция по атрибуту SNAME
т
Выборка кортежей, в которых P# = 'Р2'
т
Соединение по атрибуту S#
т т
sp s
Рис. 17.2. Дерево реализации запроса “Определить имена поставщиков детали с но-
мером ‘Р2’”
Однако для наших целей удобнее всего будет предположить, что для внутреннего
представления запросов используется один из тех формальных методов, с которыми мы
уже знакомы: реляционная алгебра или реляционное исчисление. В этом случае дерево
запроса, подобное представленному на рис. 17.2, можно будет рассматривать просто как
альтернативный схематический вариант представления некоторого выражения, записан-
ного в нотации одного из двух предложенных выше формальных методов (реляционная
алгебра или реляционное исчисление). Предположим, что выбранный формальный
метод — реляционная алгебра. С этого момента будем считать, что внутренним пред-
ставлением дерева запроса, показанного на рис. 17.2, является следующее алгебраиче-
ское выражение.
( ( SP JOIN S ) WHERE P# = P# ( 'P2' ) ) { SNAME }
Стадия 2. Преобразование запроса в каноническую форму
На этой стадии оптимизатор выполняет несколько операций оптимизации, которые
“гарантированно являются хорошими” независимо от реальных значений данных и су-
ществующих путей доступа к ним. Суть в том, что обычно реляционные языки позволя-
ют сформулировать любые запросы (за исключением разве что простейших) нескольки-
ми разными (по крайней мере, внешне) способами. Например, даже простой запрос
“Определить имена поставщиков детали с номером ' Р2на языке SQL может быть за-
писан буквально десятками способов1, не считая таких тривиальных вариантов, как за-
мена А = В на В = А или р AND q на q AND р. Производительность вычисления запроса
не должна зависеть от формы записи запроса, которую выбрал пользователь. Поэтому
следующий этап в обработке запроса — преобразование его внутреннего представления
в некоторую эквивалентную каноническую форму (см. ниже). Назначением данного
преобразования является исключение внешних различий в эквивалентных представлени-
ях запроса и, что более важно, поиск представления запроса, в некотором смысле более
эффективного по сравнению с исходным представлением.
1 Следует заметить, что язык SQL исключительно предрасположен к этому (см. упр. 7.12 в
главе 7, а также [4.18]). Другие языки (например, языки реляционной алгебры или исчисления)
обычно не позволяют создать такое же количество эквивалентных по результату выражений.
Эта излишняя “гибкость” языка SQL на самом деле усложняет жизнь разработчикам (а не поль-
зователям), поскольку существенно усложняет алгоритм оптимизатора.
644
Часть К Дополнительные аспекты
Замечание о канонической форме. Понятие канонической формы является централь-
ным во многих разделах математики и связанных с ней дисциплинах. Каноническая
форма может быть определена следующим образом. Пусть Q — множество объектов
(запросов), и пусть существует понятие об их эквивалентности (а именно: запросы ql и
q2 эквивалентны тогда и только тогда, когда дают идентичные результаты). Тогда под-
множество С множества Q является подмножеством канонических форм для запросов
из множества Q в смысле определенной выше эквивалентности тогда и только тогда, ко-
гда каждому объекту q из множества Q соответствует только один объект с из множества
С. В этом случае говорят, что объект с является канонической формой объекта q. Все
“интересующие” свойства, которыми обладает объект q, также присущи объекту с. По-
этому, чтобы доказать различные “интересующие” результаты, достаточно изучить ме-
нее мощное множество объектов С, а не более мощное множество Q.
Вернемся к основной теме обсуждения. Чтобы преобразовать результаты выполнения
стадии 1 в некоторую эквивалентную, но более эффективную форму, оптимизатор ис-
пользует определенные и хорошо известные правила преобразования, или законы.
Ниже приведен пример такого правила. Здесь выражение
( A JOIN В ) WHERE <выборка из> А
может быть преобразовано в эквивалентное, но более эффективное выражение
( A WHERE <выборка из> А ) JOIN В
Подобное преобразование кратко рассматривалось в разделе 6.6. Кроме того, оно бы-
ло приведено несколько выше, при обсуждении примера в разделе 17.2, который ясно
продемонстрировал, зачем нужны подобные преобразования. Многие другие правила
преобразования описываются ниже, в разделе 17.4.
Стадия 3. Выбор потенциальных низкоуровневых процедур
После преобразования внутренней формы запроса в более подходящую
(каноническую) форму оптимизатор должен решить, как следует выполнять запрос,
представленный в этой канонической форме. На данной стадии принимаются во внима-
ние наличие индексов и других путей доступа, статистическое распределение сущест-
вующих значений данных, физическая кластеризация хранимых данных и т.п. Обратите
внимание, что на стадиях 1 и 2 этим аспектам совсем не уделялось внимания.
Основная стратегия состоит в том, чтобы рассматривать выражение запроса как се-
рию низкоуровневых операций (соединения, выборки и т.п.), которые в определенной
степени зависят одна от другой. Ниже приведен пример такой зависимости. При про-
граммной реализации выполнения проекции обычно требуется, чтобы считываемые кор-
тежи следовали в определенном порядке; это позволит исключить дублирующиеся ре-
зультирующие кортежи. В свою очередь, это означает, что выполняемая непосредствен-
но перед проекцией операция должна выдавать выходные кортежи именно в такой, тре-
буемой последовательности.
Для каждой низкоуровневой операции (а также, возможно, для нескольких часто
встречающихся комбинаций подобных операций) оптимизатор имеет набор низкоуров-
невых процедур реализации. Например, существует набор процедур для реализации
операции выборки: по условию равенства определенному значению потенциального
Глава 17. Оптимизация
645
ключа; на основе индексированного атрибута, по которому выполняется выборка; на ос-
нове хешированного атрибута и т.д. Примеры таких процедур приведены ниже, в разде-
ле 17.7 (см. также [ 17.8]—[ 17.14]).
С каждой процедурой связана и параметризованная формула стоимости, позволяю-
щая оценить стоимость выполнения процедуры (т.е. уровень затрат, требуемых для ее
выполнения). Чаще всего стоимость определяется на основе подсчета количества необ-
ходимых дисковых операций ввода-вывода, но некоторые системы учитывают также
время использования процессора и другие факторы. Эти формулы стоимости применя-
ются на стадии 4. В [ 17.8]—[ 17.14] обсуждаются и анализируются формулы стоимости
для различных процедур реализации при разных исходных предположениях.
Далее, используя сохраняемую в каталоге информацию о состоянии базы данных
(существующие индексы, текущую кардинальность переменных-отношений и т.п.) и све-
дения о взаимозависимостях, упоминавшихся выше, оптимизатор выбирает одну или не-
сколько процедур-кандидатов для каждой низкоуровневой операции в запросе. Этот
процесс обычно называют выбором пути доступа (см. также [17.34], [17.35]).
Замечание. Следует отметить, что в [17.34], [17.35] приведенный термин использует-
ся для ссылки на определенные в данной главе стадии 3 и 4, а не только на стадию 3.
Действительно, на практике очень трудно разграничить, где заканчивается одна стадия и
начинается другая: просто стадия 3 плавно переходит в стадию 4.
Стадия 4. Генерация различных вариантов планов
вычисления запроса и выбор плана с минимальными
затратами
На последней стадии процесса оптимизации создается набор потенциальных планов
запроса, после чего следует выбор лучшего (т.е. наименее дорогого) плана выполнения за-
проса. Каждый план выполнения строится как комбинация некоторого набора процедур
реализации, причем каждой низкоуровневой операции в запросе соответствует одна проце-
дура. Заметьте, что обычно для поступившего запроса вырабатывается множество планов
выполнения запроса (возможно, даже слишком много). На практике, вероятно, не стоит ге-
нерировать все возможные планы запроса, так как одни из них могут быть комбинаторны-
ми версиями других планов выполнения этого же запроса и сам процесс выбора наиболее
дешевого плана может стать чрезмерно дорогостоящим. При выборе плана с наименьшей
стоимостью рекомендуется (возможно, даже необходимо) руководствоваться некоторыми
эвристическими правилами, позволяющими ограничить количество анализируемых планов
запросов разумными пределами [17.55]. Практику ограничения количества запросов ра-
зумными пределами иначе называют сокращением пространства поиска, поскольку ее
можно рассматривать и как уменьшение диапазона (“пространства”) анализируемых опти-
мизатором вариантов (“поиск”) до контролируемых пределов.
Несомненно, для выбора плана с наименьшей стоимостью необходим метод опреде-
ления стоимости любого возможного плана. По сути, стоимость плана — это просто
сумма стоимостей отдельных процедур, входящих в его состав. Поэтому задача оптими-
затора сводится к вычислению формул стоимости для каждой отдельной процедуры. Ос-
новная проблема состоит в том, что стоимость выполнения процедуры зависит от разме-
ра отношения (или отношений), которое эта процедура обрабатывает. Так как все запро-
сы, за исключением самых простых, требуют создания некоторых промежуточных ре-
646
Часть V. Дополнительные аспекты
зультатов выполнения, оптимизатор должен суметь оценить размер этих результатов и
использовать полученные значения при вычислении формул стоимости. К сожалению,
размеры промежуточных наборов данных сильно зависит от конкретных значений хра-
нимых данных, поэтому точная оценка стоимости может оказаться достаточно сложной
проблемой. В [17.3], [17.4] обсуждаются некоторые подходы к решению этой проблемы
и приводятся ссылки на другие направления исследований.
17.4. Преобразование выражений
В этом разделе обсуждаются правила преобразования, которые могут оказаться по-
лезными на стадии 2 процесса оптимизации. Подбор примеров и выяснение, чем
именно эти правила могут быть полезны при оптимизации, оставляются в качестве уп-
ражнений для читателя.
Конечно, читатель должен понимать, что в результате применения к какому-либо вы-
ражению одного правила преобразования может быть получено выражение, к которому
применимо другое правило преобразования. Например, среди исходных запросов нечас-
то встречаются запросы, сформулированные с использованием двух последовательно
выполняемых операций проекции (речь об этом пойдет ниже; см. второе правило из под-
раздела об операциях выборки и проекции). Однако при преобразовании запросов по-
добные выражения достаточно часто возникают как результат применения других пра-
вил преобразования. (В этом смысле очень важным случаем является обработка пред-
ставлений. Например, рассмотрим запрос “Выбрать все названия городов в представле-
нии V”, где представление V определено как проекция переменной-отношения поставщи-
ков по атрибутам S# и CITY.) Иначе говоря, начиная с исходного выражения, оптимиза-
тор будет шаг за шагом применять различные правила преобразования до тех пор, пока
не будет получено выражение, которое согласно встроенным в оптимизатор эвристиче-
ским правилам будет считаться “оптимальным” для рассматриваемого запроса.
Выборки и проекции
Начнем с правил преобразования, которые включают только операции выборки и
проекции.
1. Последовательность операций выборки из одного и того же отношения может быть
заменена единственной операцией выборки из этого отношения (причем условные
выражения всех исходных операций с помощью операций AND объединяются в од-
но условное выражение). Например, выражение
( A WHERE <выборка1> ) WHERE <выборка2>
эквивалентно выражению
A WHERE <выборка1> AND <выборка2>
2. В последовательности операций проекций для одного и того же отношения можно
игнорировать все проекции, кроме последней. Таким образом, выражение
( А { <проекция1> } ) { <проекция2> }
эквивалентно выражению
А { <проекция2> }
Глава 17. Оптимизация
647
Конечно, чтобы исходное выражение имело смысл, каждый атрибут, присутст-
вующий в проекции <проекция2>, обязательно должен присутствовать и в проек-
ции <проекция1>.
3. Операцию выборки из результата операции проекции можно преобразовать в опе-
рацию проекции для результата операции выборки. Например, выражение
( А { <проекция> } ) WHERE <выборка>
эквивалентно выражению
( A WHERE <выборка> ) { <проекция> }
Обратите внимание, что, как правило, операцию выборки целесообразно выполнять
перед операцией проекции, поскольку операция выборки обычно приводит к
уменьшению объема тех данных, которые будут являться входными для операции
проекции. Следовательно, в этом случае уменьшается количество данных, которые
потребуется сортировать для исключения возможных дублирующихся записей, об-
разующихся в процессе выполнения операции проекции.
Распределительный закон
Правило преобразования, которое использовано в примере, приведенном выше, в
разделе 17.2 (преобразование операции соединения с последующей операцией выборки в
операцию выборки с последующей операцией соединения), на самом деле является част-
ным случаем более общего правила, называемого распределительным законом. Говорят,
что унарный оператор f распределяется по бинарной операции О тогда и только тогда,
когда для всех А и В выполняется следующее тождество.
f(AOB)=f(A)Of(B)
Например, в обычной арифметике операция SQRT (извлечение квадратного корня)
распределяется по операции умножения, так как для всех А и В выполняется приведенное
ниже тождество.
SQRT ( А * В ) = SQRT ( А ) * SQRT ( В )
Следовательно, выполняя преобразование выражений, оптимизатор арифметических
выражений всегда может заменить одну часть этого равенства другой. В качестве обрат-
ного примера можно привести утверждение, что операция SQRT не распределяется по
операции сложения, так как в большинстве случаев квадратный корень из суммы А + В
не равен сумме квадратных корней из А и В.
В реляционной алгебре операция выборки распределяется по операциям объедине-
ния, пересечения и вычитания. Она также распределяется по операции соединения, но
лишь тогда и только тогда, когда условие операции выборки состоит (в самом сложном
случае) из двух отдельных условий, соединенных операцией AND — по одному условию
выборки для каждого операнда операции соединения. Для примера, рассматриваемого в
разделе 17.2, сформулированное выше условие соблюдено (условие выборки очень про-
стое и относится лишь к одному из операндов), благодаря чему стало возможным при-
менить распределительный закон для замены рассматриваемого в примере выражения
его более эффективным эквивалентом. Благодаря этому закону операция выборки была
выполнена раньше остальных операций. Предварительное выполнение операций выбор-
648
Часть И. Дополнительные аспекты
ки почти всегда себя оправдывает, так как приводит к существенному уменьшению ко-
личества кортежей, обрабатываемых следующей операцией, а также, возможно, к
уменьшению количества кортежей на выходе этой операции.
Ниже приведено несколько примеров более специфических случаев применения рас-
пределительного закона, на этот раз для операции проекции. Во-первых, операция про-
екции распределяется по операциям объединения и пересечения (но не по операции
вычитания).
( A UNION В ) { С } = А { С } UNION В { С }
( A INTERSECT В ) { С } = А { С } INTERSECT В { С }
Здесь А и В должны иметь одинаковые типы. Во-вторых, эта операция также распре-
деляется по операции соединения, т.е. тождество
( A JOIN В ) { С } = ( А { АС } ) JOIN ( В { ВС } )
справедливо, но только в том случае, если:
множество АС является объединением общих атрибутов отношений А и В, плюс те
атрибуты из множества С, которые имеются только в отношении А;
множество ВС является объединением общих атрибутов отношений А и В, плюс те
атрибуты из множества С, которые имеются только в отношении В.
Эти законы можно использовать для организации предварительного выполнения опе-
раций проекций, что обычно себя оправдывает по тем же причинам, что и в случае опе-
раций выборки.
Коммутативность и ассоциативность
Законы коммутативности и ассоциативности являются двумя еще более важными
и общими правилами преобразования. Говорят, что бинарная операция О является ком-
мутативной тогда и только тогда, когда для всех А и В истинно следующее тождество.
А О В = В О А
Например, в обычной арифметике операции умножения и сложения являются комму-
тативными, а операции деления и вычитания — нет. В реляционной алгебре коммута-
тивными являются операции объединения, пересечения и соединения, а операции вы-
читания и деления таковыми не являются. Например, если запрос включает соединение
двух отношений, А и В, то коммутативность означает, что безразлично, какое из отноше-
ний А и В выбрано в качестве “внешнего” или “внутреннего”. Следовательно, при вычис-
лении данного объединения системе предоставлено право выбора в качестве “внешнего”,
например, меньшего из двух отношений (см. раздел 17.7).
Перейдем к ассоциативности. Принято считать, что бинарная операция О является
ассоциативной, если для всех А, В и С истинно следующее тождество.
АО(ВОС) = (АОВ)ОС
Например, в обычной арифметике произведение и сложение — ассоциативные опе-
рации, а деление и вычитание — нет. В реляционной алгебре ассоциативными являются
операции объединения, пересечения и соединения, а операции вычитания и деления
таковыми не являются. Так, например, если в запросе используется соединение трех от-
Глава 17. Оптимизация
649
ношений, А, В и С, то из законов коммутативности и ассоциативности следует, что не
имеет значения, в каком порядке будет выполняться соединение отношений. Поэтому в
процессе вычисления подобного соединения системе предоставляется право выбора наи-
более эффективной последовательности из всех существующих.
Идемпотентность
Еще одним важным общим правилом является закон идемпотентности. Бинарную
операцию О называют идемпотентной тогда и только тогда, когда для любого А выпол-
няется следующее тождество.
А О А А
Можно ожидать, что применение закона идемпотентности окажется полезным в про-
цессе преобразования выражений. В реляционной алгебре операции объединения, пересе-
чения и соединения являются идемпотентными, а операции деления и вычитания — нет.
Вычисляемые скалярные выражения
Объектом применения законов трансформации являются не только реляционные вы-
ражения. Например, выше уже упоминалось, что некоторые законы трансформации при-
менимы и к арифметическим выражениям. Вот конкретный пример. Вследствие того,
что операция умножения распределяется по операции сложения “+”, выражение
А * В + А * С
можно трансформировать в выражение
А * ( В + С )
Оптимизатор реляционных выражений должен знать о возможности подобных пре-
образований, так как ему приходится иметь дело с вычисляемыми скалярными выраже-
ниями в контексте операций EXTEND и SUMMARIZE.
Следует отметить, что приведенный выше пример иллюстрирует несколько более
общую форму распределительного закона. Выше было дано определение понятия рас-
пределяемое™ по отношению к унарным операциям, распределяемым по бинарным опе-
рациям. Однако в данном случае обе операции, и “+”, являются бинарными. Говорят,
что бинарная операция 5 распределяется по бинарной операции О, если для всех А, В и
С истинно равенство
Аб(ВОС) = (А5В)О(А5С)
(в приведенном выше арифметическом примере 6 представляет операцию а О —
операцию “+”).
Логические выражения
Перейдем к обсуждению логических выражений (иначе называемых булевыми выра-
жениями или условиями), результатами вычисления которых могут быть только значения
истина иложь. Предположим, что А и В — это атрибуты двух различных отношений, то-
гда условие (которое может быть частью запроса)
А > В AND В > 3
650
Часть V. Дополнительные аспекты
абсолютно эквивалентно выражению
А > В AND В > 3 AND А > 3
и потому может быть преобразовано в это выражение.
Данная эквивалентность базируется на том основании, что операция “>” является
транзитивной. Заметьте, что подобное преобразование весьма полезно, так как позволя-
ет системе выполнить дополнительную операцию выборки (по А) до выполнения
“больше чем”-соединения, заданного условием А > В. Повторим сказанное выше. Пред-
варительное выполнение операций выборки чаще всего оправдывает себя,
следовательно, будет полезной и способность системы логически выводить предвари-
тельные операции выборки (что и было реализовано в данном примере).
Замечание. Этот прием реализован в различных коммерческих продуктах, включая
СУБД DB2 (в которой его называют транзитивным замыканием предикатов), а также
СУБД INGRES.
Вот еще один пример. Вследствие того, что операция OR распределяется по операции
AND, логическое выражение
А > В OR ( С = D AND Е < F )
можно преобразовать в выражение
( А > В OR С = D ) AND ( А > В OR Е < F )
Этот пример демонстрирует другой общий закон: “Любое условие может быть пре-
образовано в эквивалентное условие, называемое конъюнктивной нормальной фор-
мой (КНФ)”. Выражение в КНФ в общем случае имеет следующий вид.
Cl AND С2 AND ... AND Cn
Здесь Cl, С2,..., Cn — это логические выражения (называемые конъюнктами), в которых
не используется логическая операция AND. Преимущество КНФ состоит в том, что выражение
в КНФ истинно только в том случае, если истинны все его конъюнкты. И наоборот, выраже-
ние в КНФ ложно, если ложь является результатом вычисления хотя бы одного конъюнкта.
Так как логическая операция AND коммутативна (выражение A AND В эквивалентно выраже-
нию BAND А), оптимизатор может вычислять отдельные конъюнкты в любом порядке, в част-
ности по возрастанию их сложности (начиная с самых простых). Как только будет найден
конъюнкт, результатом вычисления которого является ложь, процесс вычисления выражения
в КНФ можно будет прекратить. Более того, в системах с параллельной обработкой возможно
параллельное вычисление каждого из конъюнктов [ 17.58]—[ 17.61]. Опять же, как только будет
найден первый конъюнкт, результатом вычисления которого является значение ложь, про-
цесс вычисления выражения в КНФ можно будет прекратить.
Из сказанного выше следует, что оптимизатор должен знать, как общие свойства, та-
кие как распределенность, применяются не только к реляционным операциям, но и к
операторам сравнения, например “>”, к логическим операторам, например AND и OR, к
арифметическим операторам, например “+”, и т.п.
Семантические преобразования
Рассмотрим следующее выражение.
( SP JOIN S ) { P# }
Глава 17. Оптимизация
651
Данное соединение относится к соединениям типа внешний ключ — соответствующий
потенциальный ключ. В нем внешнему ключу в переменной-отношении SP ставится в соот-
ветствие потенциальный ключ в переменной-отношении S. Следовательно, каждый кортеж
в переменной-отношении SP связан с определенным кортежем в переменной-отношении S.
Таким образом, из каждого кортежа в переменной-отношении SP в общий результат посту-
пает только значение атрибута Р#. Другими словами, соединение можно вообще не выпол-
нять! Рассматриваемое выражение можно заменить следующим выражением.
SP { P# }
Тем не менее будьте внимательны — подобное преобразование применимо только в
силу семантики (смысла) конкретной ситуации. В общем случае каждый операнд в опе-
рации соединения вносит в соединение кортежи, которые не имеют дополняющих их
кортежей в других операндах и, следовательно, не попадающих в общий конечный ре-
зультат. Поэтому чаще всего преобразования подобного типа будут некорректны. Одна-
ко в рассматриваемом конкретном случае каждый кортеж в переменной-отношении SP
обязательно имеет соответствующий ему кортеж в переменной-отношении S согласно
установленному ограничению целостности (фактически это ограничение ссылочной це-
лостности), которое гласит, что каждая поставка деталей должна быть связана с опреде-
ленным поставщиком. Следовательно, учитывая это замечание, можно утверждать, что в
данном случае рассматриваемое преобразование вполне корректно.
Преобразование, которое является корректным только в силу конкретного установ-
ленного ограничения целостности, называют семантическим преобразованием [17.27],
а оптимизацию, достигаемую в результате подобных преобразований, — семантической
оптимизацией. Семантическую оптимизацию можно определить как процесс преобра-
зования одного запроса в другой, качественно отличный запрос, который, тем не менее,
дает результат, идентичный результату исходного запроса, благодаря тому, что обраба-
тываемые данные удовлетворяют определенному ограничению целостности.
Важно понимать, что, в принципе, любое ограничение целостности может быть ис-
пользовано для семантической оптимизации. Другими словами, этот прием не ограничен
использованием только ограничений целостности. Например, предположим, что в базе
данных поставщиков и деталей установлено ограничение, утверждающее, что все крас-
ные детали должны храниться в Лондоне. Рассмотрим следующий запрос.
Определить всех поставщиков только красных детачей, которые (поставщики) на-
ходятся в там же городе, где хранится хотя бы одна поставчяемая ими детачь.
Это довольно сложный запрос! Но в силу рассмотренного ограничения целостности
его можно привести к такому виду.
Определить всех поставщиков из Лондона, поставляющих только красные детали.
Замечание. Насколько известно автору, лишь немногие современные коммерческие
продукты в должной мере используют идею семантической оптимизации. Однако, в
принципе, семантическая оптимизация способна обеспечивать значительное улучшение
производительности (весьма вероятно, намного превышающее то, которое в настоящее
время может быть достигнуто с помощью любых традиционных приемов оптимизации).
Более подробно идея семантической оптимизации изложена в [17.16], [17.28]—[ 17.30] и
особенно — в [17.27].
652
Часть V. Дополнительные аспекты
Заключительные замечания
В завершение хотелось бы подчеркнуть фундаментальную важность свойства реляци-
онной замкнутости в отношении всех аспектов, обсуждавшихся в этом разделе. Наличие
реляционной замкнутости означает, что можно писать вложенные выражения, а это, в свою
очередь, означает, что единственный запрос может быть представлен единственным выра-
жением вместо некоторой процедуры, состоящей из нескольких выражений, и поэтому нет
необходимости в анализе потоков. Вложенные выражения рекурсивно определяются в тер-
минах подчиненных выражений, что позволяет оптимизатору использовать множество
стратегий вычисления по принципу “разделяй и властвуй” (подробности приводятся ниже,
в этой же главе). И конечно же, при отсутствии свойства реляционной замкнутости не име-
ли бы смысла общие законы, такие как правило дистрибутивности и т.п.
17.5 . Статистические показатели базы данных
На стадиях 3 и 4 общего процесса оптимизации (называемых стадиями выбора пути
доступа) используются статистические показатели базы данных, сохраняемые в ее ка-
талоге (ниже кратко описаны способы их применения). В демонстрационных целях ниже
кратко рассматриваются (с небольшими дополнительными комментариями) некоторые
из основных статистических показателей, используемых в двух коммерческих продук-
тах — СУБД DB2 и INGRES. Приведем некоторые из основных статистических показа-
телей, применяемых в СУБД DB22.
Для каждой базовой таблицы фиксируются следующие показатели:
кардинальность;
количество страниц внешней памяти, занятых таблицей;
доля табличного пространства, занимаемого таблицей.
Для каждого столбца каждой базовой таблицы фиксируются следующие показатели:
количество различных значений в столбце;
второе наибольшее значение в столбце;
второе наименьшее значение в столбце;
десять значений в столбце (только для индексированных столбцов), которые
чаще всего встречаются, а также количество вхождений каждого из этих зна-
чений.
Для каждого индекса фиксируются следующие показатели:
индикатор, указывающий, является ли индекс кластеризованным (т.е. индексом,
в котором логический порядок значений ключа совпадает с физическим поряд-
ком их размещения в таблице);
для кластеризованных индексов — доля индексированной таблицы, находящей-
ся в кластеризующей последовательности;
2 Так как обе названные СУБД поддерживают стандартный язык SQL, при их обсуждении
вместо терминов "переменная-отношение” и "атрибут" будут использоваться термины
"таблица” и "столбец” соответственно Также заметим, что в обеих СУБД предполагается,
что каждая базовая таблица должна отображаться в одну хранимую таблицу.
Глава 17. Оптимизация
653
количество листовых страниц в индексе;
количество уровней в индексе.
Замечание. Перечисленные выше статистические показатели не обновляются при ка-
ждом обновлении базы данных из-за больших накладных расходов, связанных с их вы-
числением. Вместо этого статистические показатели обновляются выборочно, с помо-
щью системной утилиты RUNSTATS, которая запускается по требованию администратора
базы данных, например после реорганизации базы данных. Аналогичное утверждение
применимо и к большинству других коммерческих продуктов, в том числе к системе
INGRES, где соответствующая утилита называется OPTIMIZEDB.
Перечислим некоторые из основных статистических показателей базы данных, нака-
пливаемых в СУБД INGRES.
Замечание. В системе INGRES индекс рассматривается как частный случай хранимой
таблицы. Поэтому приведенные ниже статистические показатели для базовых таблиц и
столбцов вычисляются также для индексов.
Для каждой базовой таблицы фиксируются следующие показатели:
кардинальность;
количество первичных страниц для таблицы;
количество страниц переполнения для таблицы.
Для каждого столбца в каждой базовой таблице фиксируются следующие показатели:
количество различных значений в столбце;
максимальное, минимальное и среднее значения для столбца;
реальные значения в столбце и частота их вхождений.
17.6 . Стратегия по принципу “разделяй и властвуй”
Как уже упоминалось выше, в конце раздела 17.4, реляционные выражения рекурсивно
определяются в терминах подчиненных выражений, что позволяет оптимизатору применять
различные стратегии оптимизации по принципу “разделяй и властвуй”. Заметьте, что исполь-
зование подобных стратегий особенно привлекательно в средах, поддерживающих парал-
лельные вычисления, в частности в распределенных системах, в которых различные части за-
проса могут вычисляться параллельно на разных процессорах [17.58]—[ 17.61]. В данном раз-
деле рассматривается одна из подобных стратегий, получившая название декомпозиция за-
просов. Впервые она была применена в прототипе системы INGRES [17.36], [17.37].
Замечание. Дополнительную информацию об оптимизации в СУБД INGRES
(особенно в ее коммерческой версии, которая в данном контексте несколько отличается
от прототипа системы INGRES) можно найти в работе Куи (Kooi) и Франкфорта
(Frankforth) [17.2], а также в [17.38].
Основная идея метода декомпозиции запросов строится на разбиении запроса со мно-
гими переменными диапазона3 на последовательность запросов меньшего размера обыч-
но с одной или двумя такими переменными диапазона. Требуемая декомпозиция дости-
гается с помощью методов отделения и подстановки кортежей.
3 Напомним, что язык запросов QUEL в системе INGRES использует средства реляционного
исчисления.
654
Часть К. Дополнительные аспекты
Отделение — это процесс удаления из запроса компонента, который имеет толь-
ко одну общую переменную с оставшейся частью запроса.
Подстановка кортежа — это процесс подстановки значения одной переменной в
запросе (один кортеж за одну операцию).
Использование метода отделения всегда предпочтительней использования метода
подстановки кортежей во всех случаях, когда существует возможность выбора (см. при-
мер, приведенный ниже). Тем не менее рано или поздно декомпозиция методом отделе-
ния обязательно приведет к разбиению запроса на множество компонентов, которые
больше нельзя будет подвергнуть декомпозиции с помощью этого метода, после чего
придется обратиться к методу подстановки кортежей.
Ниже рассмотрен пример декомпозиции (основанный на примере из [17.36]). Словес-
ное выражение этого запроса имеет следующий вид: “Определить имена поставщиков из
Лондона, поставляющих некоторые красные детали весом менее 25 фунтов в количестве
более 200 штук”. Приведем формулировку этого запроса на языке QUEL, на которую да-
лее будем ссылаться, как на формулировку Q0.
QO: RETRIEVE ( S.SNAME) WHERE S.CITY = 'London'
AND S.S# = SP.S#
AND SP.QTY > 200
AND SP.P# = P.P#
AND P.COLOR = 'Red'
AND P.WEIGHT < 25
Здесь подразумеваемый диапазон переменных S, Р и SP распространяется на всю од-
ноименную переменную-отношение.
Исходя из последних двух сравнений в выражении запроса можно заключить, что нас
интересуют только красные детали весом менее 25 фунтов. Следовательно, можно отде-
лить подзапрос с одной переменной (на самом деле являющийся проекцией выборки), в
котором используется переменная Р.
DI: RETRIEVE INTO Р' (Р.Р#) WHERE Р.COLOR = 'Red'
AND Р.WEIGHT < 25
Этот запрос с единственной переменной может быть отделен, так как в нем присутст-
вует только одна переменная (а именно — переменная диапазона Р), совместно исполь-
зуемая с оставшейся частью запроса. Так как запрос D1 связывается с остатком исходно-
го запроса по атрибуту P# (в условии SP.P# = Р.Р#), атрибут P# должен входить в
“кортеж-прототип” (см. главу 7) отделенного запроса. Другими словами, отделенный за-
прос предназначен для выборки номеров только тех красных деталей, которые весят ме-
нее 25 фунтов. Отделенный запрос обозначим как запрос D1, результатом выполнения
которого является временная переменная-отношение Р'. (Назначение предложения INTO
состоит в том, чтобы создать новую переменную-отношение Р' с единственным атрибу-
том Р#. Эта переменная-отношение создается автоматически и содержит результат вы-
полнения операции RETRIEVE.) И наконец заменим ссылки на переменную-отношение Р в
сокращенной версии запроса Q0 ссылками на переменную-отношение Р'. Эту новую со-
кращенную версию исходного запроса обозначим как Q1.
Глава 17. Оптимизация
655
QI: RETRIEVE (S.SNAME) WHERE S.CITY = 'London'
AND S.S# = SP.S#
AND SP.QTY > 200
AND SP.P# =P'.P#
Еще раз применим аналогичный прием к запросу Q1, отделив от него запрос, в кото-
ром используется единственная переменная диапазона SP. Присвоим отделенному запро-
су имя D2, а оставшуюся после отделения часть запроса Q1 назовем Q2.
D2: RETRIEVE INTO SP' (SP.S#, SP.P#) WHERE SP.QTY > 200
Q2: RETRIEVE (S.SNAME) WHERE S.CITY = 'London'
AND S.S# = SP'.S#
AND SP'.P# = P’.P#
Далее тем же методом отделим запрос с единственной переменной S.
D3: RETRIEVE INTO S' (S.S#, S.SNAME) WHERE S.CITY = 'London'
Q3: RETRIEVE (S'.SNAME) WHERE S'.S# = SP'.S#
AND SP'.P# = P',P#
И наконец отделим еще один запрос, в котором используются переменные SP' и Р'.
D4: RETRIEVE INTO SP" (SP'.S#) WHERE SP'.P# = P'.P#
Q4: RETRIEVE (S'.SNAME) WHERE S'.S# = SP".S#
В результате исходный запрос Q0 оказался разбитым на три запроса с одной переменной,
Dl, D2 и D3 (каждый из которых является проекцией выборки), и два запроса с двумя перемен-
ными, D4 и Q4 (каждый из которых является проекцией соединения). Сложившуюся в резуль-
тате ситуацию можно схематично представить в виде структуры, показанной на рис. 17.3.
Окончательный результат
S’ - ? D3 Т S Q4 <- SP" т Р’ -> D4 <- SP’ т ? Dl D2 ? ? Р SP
Рис. 17.3. Дерево декомпозиции запро-
са Q0
Эту схему можно интерпретировать следующим образом.
В запросах Dl, D2 и D3 в качестве входных данных используются переменные-
отношения Р, SP и S (а точнее, те отношения, которые являются текущими значе-
ниями переменных-отношений Р, SP и S) соответственно, которые и помещают ре-
зультат своего выполнения во временные переменные-отношения Р', SP' и S' со-
ответственно.
656
Часть V. Дополнительные аспекты
Далее выполняется запрос D4, использующий в качестве входных данных времен-
ные переменные-отношения Р' и SP' и помещающий результат своего выполне-
ния во временную переменную-отношение SP''.
Наконец выполняется запрос Q4, использующий в качестве выходных данных пе-
ременные-отношения S и SP'результат выполнения которого и является резуль-
татом выполнения исходного запроса.
Обратите внимание, что запросы DI, D2 и D3 полностью независимы и их можно об-
рабатывать в любом порядке (предположительно даже параллельно). Запросы D3 и D4
также можно обрабатывать в любом порядке, но только после получения результатов
выполнения запросов D1 и D2. Запросы D4 и Q4 нельзя подвергнуть дальнейшей декомпо-
зиции, поэтому их следует обрабатывать с помощью метода подстановки кортежей (что
обычно обозначает применение поиска последовательным перебором (или метода
“грубой силы”), поиска по индексу или поиска в хешированном файле). В качестве при-
мера рассмотрим выполнение запроса Q4. Обратившись к обычному набору данных, ис-
пользуемых в этой книге для примеров, можно определить, что множество номеров по-
ставщиков в атрибуте SP* *. S# будет выглядеть так: {' S1', ' S2', ' S4'}. Каждое из этих
трех значений по очереди должно быть подставлено в атрибут SP" .S#. В результате за-
прос Q4 примет следующий вид.
RETRIEVE (S'.SNAME) WHERE S'.S# = 'Si'
OR S'.S# = 'S2'
OR S'.S# = 'S4'
В [17.36] рассматриваются алгоритм разбиения исходного запроса на запросы с не-
приводимыми компонентами и алгоритм выбора переменных для подстановки кортежей.
Именно от этого последнего из двух указанных алгоритмов во многом зависит общий
успех оптимизации. Кроме того, в данной работе предложены эвристические подходы
для оценки стоимости того или иного варианта (в системе INGRES обычно, но не всегда,
для подстановки используется отношение с наименьшей кардинальностью). Основная
задача процесса оптимизации — избежать выполнения декартовых произведений и ми-
нимизировать количество сканируемых кортежей на каждом этапе вычислений.
В [17.36] не представлены алгоритмы оптимизации запросов с одной переменной. Од-
нако информация об этом уровне оптимизации присутствует в общем обзоре системы
INGRES [17.11]. Для оптимизации запросов с одной переменной в СУБД INGRES, в ос-
новном, используются функции, аналогичные подобным функциям в других системах. Они
применяют хранящиеся в каталоге статистические данные, на основе которых выбирают
конкретный путь доступа к требуемым данным (например, индекс или хеш-таблицу).
В [17.37] представлены некоторые экспериментальные материалы (например, резуль-
таты измерения производительности для эталонного набора запросов), позволяющие
сделать вывод, что описанные выше приемы оптимизации дают хорошие результаты и
достаточно эффективны при применении на практике. Ниже приведены некоторые вы-
воды, взятые из этой работы.
1. Метод отделения — это лучшая из методик, которую можно применять на первом
этапе оптимизации.
2. Если на первом этапе нужно выполнять подстановку кортежей, то для этого лучше
всего использовать переменную, по которой выполняется соединение.
Глава 17. Оптимизация
657
3. Если к одной из переменных в запросе с двумя переменными применялась подста-
новка кортежей, то оптимальная тактика заключается в построении временного ра-
бочего индекса или хеш-таблицы (если это еще не сделано) для того атрибута в
другом отношении, по которому выполняется соединение. В СУБД INGRES эта
тактика активно применяется.
17.7. Реализация реляционных операторов
В этом разделе представлено краткое описание некоторых очевидных методов реали-
зации отдельных реляционных операторов, в частности оператора соединения. Включе-
ние данного материала в книгу было вызвано стремлением развеять ту таинственность,
которая все еще витает над описанием процесса оптимизации. Обсуждаемые далее мето-
ды соответствуют механизмам, которые в разделе 17.3 были названы низкоуровневыми
процедурами реализации.
Замечание. Более сложные приемы реализации описаны в аннотациях к определен-
ным работам, ссылки на которые приведены в конце главы.
Для простоты предположим, что кортежи и отношения физически хранятся на диске
так, как они организованы логически. Далее будет рассмотрено выполнение операторов
проекции, соединения и обобщения, причем под операторами обобщения будем пони-
мать оба указанных ниже основных варианта.
1. Обобщение, результат которого не включает атрибутов.
2. Обобщение, результат которого включает как минимум один атрибут.
Первый вариант достаточно прост. Как правило, в этом случае выполняется просмотр
всего отношения, для которого вычисляется обобщающая функция, за исключением ва-
рианта, когда для обобщаемого атрибута имеется индекс. В последнем случае значение
обобщающей функции может быть вычислено исключительно по значениям в файле ин-
декса, без необходимости обращения к самому отношению [17.35]. Например, рассмот-
рим выполнение следующего запроса.
SUMMARIZE SP ADD AVG ( QTY ) AS AQ
Для вычисления его результатов достаточно просмотреть индекс по атрибуту QTY
(предполагается, что такой индекс существует), вовсе не касаясь самой переменной-
отношения поставок SP. Аналогичные соображения применимы и для функций COUNT и
SUM (причем для функции COUNT подойдет любой индекс). Что касается функций МАХ и
MIN, то их результат можно получить, выполнив единственную операцию чтения послед-
ней (для функции МАХ) или первой (для функции MIN) строки индекса (здесь вновь пред-
полагается, что индекс для соответствующего атрибута уже существует).
Далее в этом разделе будут рассматриваться обобщающие функции только второго
типа (т.е. такие, результат вычисления которых включает значения хотя бы одного атри-
бута). Ниже показан пример операции обобщения второго типа.
SUMMARIZE SP PER Р { P# } ADD SUM ( QTY ) AS TOTQTY
С точки зрения пользователя, операции проекции, соединения и операции обобщения
второго типа, конечно, абсолютно не похожи одна на другую. Но с точки зрения реализа-
ции они имеют некоторое сходство, так как в каждом из случаев система должна сгруппи-
658
Часть V. Дополнительные аспекты
ровать кортежи на основе значений некоторых атрибутов или комбинации атрибутов. В
случае операции проекции подобная группировка позволяет системе исключить кортежи-
дубликаты, в случае операции соединения — найти соответствующие друг другу кортежи, а
в случае операции обобщения — вычислить отдельные обобщенные значения (например,
по группам). Существует несколько методов подобной группировки кортежей.
1. Последовательный просмотр (или метод “грубой силы”).
2. Поиск по индексу.
3. Поиск по хеш-таблице.
4. Слияние.
5. Хеширование.
6. Комбинация названных выше методов.
На рис. 17.4-17.8 приведены псевдокоды процедур реализации перечисленных мето-
дов для операции соединения (операции проекции и обобщения оставлены читателю в
качестве упражнения). На этих рисунках используются следующие соглашения. Прежде
всего, R и S — это отношения, которые должны быть соединены, а С — их общий атри-
бут (возможно, составной). Предполагается, что возможен последовательный доступ к
кортежам обоих отношений R и S по одному за одну операцию. Эти кортежи в последо-
вательности доступа будут обозначаться как R[ 1 ], R[2], ..., R[m] и S[ 1 ], S[ 2], ..., S[n]
соответственно. Для соединенного кортежа, составленного из атрибутов кортежей R[i] и
S[ j], будет использоваться обозначение R[i] * S[ j]. И наконец, переменную-
отношение R будем считать внешней, а переменную-отношение S — внутренней
(поскольку они управляют внешним и внутренним циклами просмотра соответственно).
Последовательный просмотр
Метод последовательного просмотра или “грубой силы” иногда также называют про-
стым методом. В этом случае рассматриваются все возможные комбинации кортежей
(т.е. каждый кортеж отношения R проверяется в сочетании с каждым кортежем отноше-
ния S, как показано на рис. 17.4).
Замечание. Метод последовательного просмотра часто называют методом вложенных
циклов, но это название нельзя считать адекватным, поскольку вложенные циклы ис-
пользуются в реализациях всех названных выше методов.
do i := 1 to m ; /* Внешний цикл */
do j := 1 to n ; /* Внутренний цикл */
if R[i].C = S[j].C then
<к результату добавить соединенный кортеж R[i] * S[j]> ;
end ;
end ;
Puc. 17.4. Метод последовательного просмотра
Давайте проанализируем затраты, связанные с использованием метода последова-
тельного просмотра.
Глава 17. Оптимизация
659
Замечание. Здесь мы ограничимся только анализом затрат на выполнение операций
ввода-вывода, хотя на практике может потребоваться также учесть другие параметры
(например, затраты времени центрального процессора).
Прежде всего, ясно, что для реализации этого метода потребуется всего п * m опера-
ций чтения кортежей. А как в отношении операций записи кортежей? Какова кардиналь-
ность результата операции соединения? (Количество операций записи кортежа будет
равно кардинальности результирующего отношения, если последнее требуется записы-
вать на диск.)
В частном, но достаточно важном случае соединения типа “многие к одному”
(например, соединение типа “внешний ключ к соответствующему потенциальному
ключу”) кардинальность результирующего отношения почти всегда точно совпа-
дает с величиной m или п в зависимости от того, какое из отношений, R или S, рас-
положено на стороне “многие” рассматриваемого соединения.
Теперь рассмотрим более общий случай соединения типа “многие ко многим”.
Пусть dCR — количество различающихся значений атрибута С отношения R, по ко-
торому выполняется соединение, и dCS имеет тот же смысл, но для отношения S.
Если предположить, что значения атрибутов распределены равномерно (т.е. любое
значение атрибута С может быть встречено с той же вероятностью, что и другие
значения), то для данного кортежа отношения R существует п/dCS соответствую-
щих кортежей в отношении S со значением атрибута С, равным значению этого
атрибута в рассматриваемом кортеже из отношения R. Таким образом, общее ко-
личество кортежей в соединении (т.е. кардинальность результирующего отноше-
ния) будет равно (m * n)/dCS. Или, если повторить изложенные рассуждения, на-
чав с кортежа в отношении S, кардинальность результирующего отношения соста-
вит (n * m)/dCR. Эти две оценки будут различными, если dCS * dCR, т.е. если в
отношении R существуют значения атрибута С, которые не встречаются в отноше-
нии S, и наоборот. В этом случае следует использовать худшую из оценок.
Конечно, как уже отмечалось, на практике подсчитываются операции ввода-вывода
страниц, а не кортежей. Поэтому предположим, что в отношениях R и S на странице по-
мещается соответственно pR и pS кортежей (т.е. отношения занимают m/pR и n/pS стра-
ниц соответственно). Теперь легко увидеть, что процедура, псевдокод которой показан
на рис. 17.4, выполнит (m/pR) + (m*n)/pS операций чтения страниц. Аналогично, если
поменять местами роли отношений R и S (отношение S считать внешним, a R — внутрен-
ним), количество операций чтения страниц составит (п/pS) + (n*m)/pR.
Для примера предположим, что m = 100, п = 10 000, pR = 1 и pS = 10. Тогда ре-
зультатами вычисления последних двух формул будут значения 100 100 и 1 001 000
операций чтения страниц соответственно.
Замечание. В описанном подходе в качестве внешнего отношения желательно ис-
пользовать меньшее из двух исходных отношений (в данном случае понятие “меньшее”
относится к количеству занимаемых им страниц внешней памяти).
Завершая краткое обсуждение метода последовательного просмотра, заметим, что
этот прием является наихудшим из всех. В нем предполагается, что отношение S не име-
ет ни индекса, ни хеш-таблицы для атрибута С, по которому выполняется соединение.
Эксперименты, проведенные Виттоном (Bitton) [17.7], показали, что если предполагае-
660
Часть V. Дополнительные аспекты
мая ситуация (отсутствие индексов и хеш-таблиц) действительно имеет место, то методы
обработки можно улучшить, построив нужный индекс или хеш-таблицу динамически и
продолжив обработку запроса с помощью методов поиска по индексу или хеш-таблице
(см. следующие два подраздела). Как упоминается в конце следующего раздела, эта идея
поддерживается и в [17.37].
Поиск по индексу
Теперь рассмотрим ситуацию, в которой для атрибута S.C внутреннего отношения S
существует индекс X (рис. 17.5). Преимущество поиска по индексу по сравнению с мето-
дом последовательного просмотра состоит в том, что благодаря наличию индекса X для
данного кортежа внешнего отношения R возможен переход непосредственно к соответ-
ствующему кортежу внутреннего отношения S. Общее количество операций чтения кор-
тежей из отношений R и S будет равно кардинальности результирующего отношения
операции соединения. Общее количество операций чтения страниц для отношений R и S
составит (m/pR) + (mn/dCS) при наихудшем предположении, что каждая операция чте-
ния кортежа из отношения S требует обращения к отдельной странице.
/* Использование индекса X по атрибуту S.C */
do i := 1 to m ; /* Внешний цикл */
/* Пусть для значения индексированного атрибута R[i].C */
/* существует к вхождений индекса: Х[1], ..., Х[к] */
do j := 1 to к ; /* Внутренний цикл */
/* Пусть S[j] — кортеж из S, на который указывает индекс X[j] */
<к результату добавить соединенный кортеж R[i] * S[j]> ;
end ;
end ;
Рис. 17.5. Поиск по индексу
Если кортежи отношения S хранятся в порядке значений соединяющего атрибута С,
то количество операций чтения страницы уменьшится до значения (m/pR) +
(mn/dCS )/pS. Воспользовавшись теми же пробными значениями, что и выше (ш = 100,
п = 10 000, pR = 1, pS = 10), и предположив, что dCS = 100, получим в результате вы-
числения двух последних формул значения 10 100 и 200 соответственно. Разница между
полученными значениями указывает, что кортежи хранимых отношений целесообразно
размещать в “подходящей” физической последовательности [17.9].
Однако при оценке затрат следует учитывать и накладные расходы, связанные с вы-
полнением операций чтения в самом индексе. Наихудшим является предположение, что
при поиске соответствующих кортежей в отношении S для каждого кортежа в отноше-
нии R потребуется выполнить “непредвиденный” поиск по индексу, требующий чтения
страницы для каждого уровня индекса. Для индекса, обладающего х уровнями, операция
поиска добавит к общему количеству операций чтения страницы еще ш*х операций. На
практике х обычно имеет значение 3 или меньше. (Более того, весьма вероятно, что
верхний уровень индекса на протяжении всей обработки данных будет находиться в па-
мяти, что значительно сократит количество операций чтения страниц.)
Глава 17. Оптимизация
661
Поиск по хеш-таблице
Поиск по хеш-таблице аналогичен поиску по индексу, но в качестве “быстрого пути
доступа” к значениям атрибута S.C внутреннего отношения S вместо индекса использу-
ется хеш-таблица (рис. 17.6). Вывод оценки затрат, связанных с выполнением данного
метода, оставлен в качестве упражнения для читателя.
/* Использование хеш-таблицы Н по атрибуту S.C */
do i := 1 to m ; /* Внешний цикл */
k := hash (R[i].C)
/* Пусть имеется h кортежей из S, хранимых в H[k] */
do j := 1 to h ; /* Внутренний цикл */
if R[i].C = S[j].C then
<к результату добавить соединенный кортеж R[i] * S[j]> ;
end ;
end ;
Рис. 17.6. Поиск no хеш-таблице
Метод слияния
В методе слияния предполагается, что кортежи отношений R и S хранятся во внешней
памяти в последовательности значений атрибута С, по которому выполняется соедине-
ние. Если данное предположение отвечает действительности, то два отношения можно
будет просматривать в их физической последовательности, причем обе операции про-
смотра можно синхронизировать, в результате чего соединение может быть выполнено
за один проход по данным (это утверждение истинно по крайней мере для соединений
типа “один ко многим”, но не всегда истинно для соединений типа “многие ко многим”).
Несомненно, подобный метод будет оптимальным, так как каждая страница данных счи-
тывается всего один раз (рис. 17.7). Другими словами, количество операций чтения стра-
ниц составит (m/pR) + (n/pS).
Из этого можно сделать следующие заключения.
Физическая кластеризация логически связанных данных является одним из важ-
нейших факторов, влияющих на производительность системы, т.е. в высшей сте-
пени желательно проводить кластеризацию данных так, чтобы они соответствова-
ли соединениям, наиболее важным для предприятия [17.9].
Если подобная кластеризация отсутствует, то хорошей идеей может быть сорти-
ровка непосредственно во время выполнения запроса какого-то одного или обоих
отношений произвольным способом с последующим соединением методом слия-
ния. (Безусловно, назначение подобной сортировки состоит в динамическом соз-
дании требуемой кластеризации.) На этот метод обычно ссылаются, что вполне
логично, как на метод сортировки-слияния [17.10].
Более подробно эта тема обсуждается в [17.35].
662
Часть V. Дополнительные аспекты
/* Кортежи обоих отношений, R и S, хранятся в последовательности */
/* значений атрибута С. */
/* Здесь приведен код для соединения типа “многие ко многим”, */
/* пример для соединения типа “многие к одному” оставлен */
/* в качестве упражнения для читателя. */
г := 1 ;
s := 1 ;
do while г < m and s < n ; /* Внешний цикл */
v := R[r].C ;
do j := s by 1 while S[j].C < v ;
end ;
s := j ;
do j := s by 1 while S[j].C = v ; /* Внутренний цикл */
do i := r by 1 while R[i].C = v ;
<к результату добавить соединенный кортеж R[i] * S[j]> ;
end ;
end ;
s := j ;
do i := r by 1 while R[i].C = v ;
end ;
r := i ;
end ;
Puc. 17.7. Метод слияния (для соединений типа “.многие ко .многим”)
Хеширование
Как и метод слияния, метод хеширования позволяет обойтись одним проходом для каждо-
го из двух соединяемых отношений (рис. 17.8). В результате первого прохода строится хеш-
таблица для отношения S по значениям атрибута S.C. Записи в этой таблице содержат значе-
ние соединяемого атрибута (а также, возможно, значения других атрибутов отношения S) и
указатель на соответствующий кортеж. Во время второго прохода сканируются кортежи от-
ношения R и вычисляется та же хеш-функция для значений соединяемого атрибута R.C. Когда
по вычисленному для кортежа отношения R значению хеш-функции в хеш-таблице обнаружи-
вается один или несколько соответствующих ему кортежей отношения S, алгоритм проверяет,
действительно ли равны значения R.C и S.C, и, если это так, генерируется кортеж (или корте-
жи) результирующего соединения. Основным преимуществом данного метода по сравнению
с методом слияния является то, что отношения R и S можно хранить в произвольной последо-
вательности, а значит, не требуется предварительно сортировать.
Как и в случае метода поиска по хеш-таблице, вывод оценок затрат, связанных с ис-
пользованием хеширования, оставлен в качестве упражнения для читателя.
17.8. Резюме
Эта глава начинается с утверждения, что для реляционных систем оптимизация явля-
ется как проблемой, так и благоприятной возможностью. Фактически оптимизация яв-
ляется сильной стороной таких систем, причем по целому ряду причин. Реляционная
система с хорошим оптимизатором будет функционировать намного лучше, чем не реля-
Глава 17. Оптимизация
663
ционная. Приведенный вступительный пример дает ясное представление о тех порази-
тельных результатах, которых можно достичь благодаря оптимизации (иногда эффек-
тивность выполнения запроса повышается в соотношении 10 000:1).
/* Построение хеш-таблицы Н по атрибуту S.C */
do j := 1 to n ; /* Внешний цикл */
k := hash (S[j].C)
<добавитпь в таблицу H[k] запись для S[j]>
end ;
/* Теперь выполняется поиск по хеш-таблице для */
/* каждого из кортежей отношения R */
Рис. 17.8. Метод хеширования
Процесс оптимизации в общем случае включает четыре последовательные стадии.
Представление запроса во внутренней форме (обычно это дерево запроса или аб-
страктное синтаксическое дерево, однако подобные представления вполне можно
рассматривать как специфическую внутреннюю форму для выражений реляцион-
ной алгебры или реляционного исчисления).
Преобразование в каноническую форму с помощью различных законов преоб-
разования.
Выбор подходящих случаю низкоуровневых процедур реализации различных
операторов в каноническом представлении запроса.
Генерация планов запроса и выбор плана с наименьшими затратами, оцениваемы-
ми с помощью формул стоимости и статистических показателей базы данных.
Далее обсуждались общие законы распределения, коммутативности и ассоциативно-
сти и их применение к реляционным операторам, таким как соединение. Кроме того, рас-
сматривалось применение этих законов к арифметическим и логическим операторам, а
также к операторам сравнения. Затрагивался и другой общий закон — идемпотентности.
Затем обсуждались некоторые специальные преобразования операторов проекции и выбор-
ки. После этого была представлена идея семантической оптимизации, т.е. преобразования
запросов, которое базируется на знании системой установленных ограничений целостности.
В демонстрационных целях был сделан беглый очерк статистических показателей ба-
зы данных, используемых в СУБД DB2 и INGRES. Далее обсуждалась одна из стратегий,
построенных по принципу “разделяй и властвуй”, — декомпозиция запросов, впервые
реализованная в прототипе системы INGRES. Было также отмечено, что стратегии, по-
строенные по принципу “разделяй и властвуй”, весьма привлекательны для сред с под-
держкой параллельных вычислений и распределенных систем.
И наконец, рассматривались некоторые методы реализации отдельных реляционных
операторов, в частности оператора соединения. Был представлен псевдокод алгоритмов
для пяти методов выполнения операции соединения: метода последовательного про-
смотра, поиска по индексу, поиска по хеш-таблице, метода слияния (включая метод
сортировки-слияния) и метода хеширования. Также кратко рассматривались стоимо-
стные характеристики описанных методов.
664
Часть V. Дополнительные аспекты
В заключение хотелось бы отметить, что, к сожалению, многие современные про-
граммные продукты содержат некоторые замедлители оптимизации, о которых поль-
зователь должен по крайней мере знать (даже если с этим ничего нельзя поделать). За-
медлитель оптимизации — это функция СУБД, не позволяющая оптимизатору выпол-
нять свою работу так, как она могла бы быть выполнена (например, при отсутствии дан-
ной функции). К замедлителям оптимизации можно, например, отнести возможность
вставки в таблицу записей-дубликатов [5.6], трехзначную логику (глава 18) и реализа-
цию трехзначной логики в языке SQL [18.6], [18.10].
Упражнения
17.1. Одни пары выражений в контексте базы данных поставщиков, деталей и про-
ектов эквивалентны, а другие — нет. Какие пары выражений действительно
эквивалентны?
al) S JOIN ( ( Р JOIN J ) WHERE CITY = 'London'
a2) ( P WHERE CITY = 'London' ) JOIN ( J JOIN S )
61) ( S MINUS ( ( S JOIN SPJ ) WHERE P# = P# ( 'P2' ) )
{ Si, SNAME, STATUS, CITY } ) { S#, CITY }
62) S { Si, CITY } MINUS
( S { S#, CITY } JOIN
( SPJ WHERE Pi = Pi ( 'P2' ) ) ) { Si, CITY }
Bl) ( S { CITY } MINUS P { CITY } ) MINUS J { CITY }
b2) ( S { CITY } MINUS J { CITY } )
MINUS ( P { CITY } MINUS J { CITY } )
rl) ( J { CITY } INTERSECT P { CITY } ) UNION ( S { CITY } )
r2) J { CITY } INTERSECT ( S { CITY } UNION P { CITY } )
Д1) ( ( SPJ WHERE Si = Si ('SI' ) )
UNION ( SPJ WHERE P# = P# ( 'Pl' ) ) )
INTERSECT
( ( SPJ WHERE J# = J# ( 'Jl' ) )
UNION ( SPJ WHERE S# = S# ( 'SI' ) ) )
д2) ( SPJ WHERE S# = S# ( 'SI' ) ) UNION
( ( SPJ WHERE P# = P# ( 'Pl' ) ) INTERSECT
( SPJ WHERE J# = Ji ( 'Jl' ) ) )
el) ( S WHERE CITY = 'London' ) UNION ( S WHERE STATUS > 10 )
e2) S WHERE CITY = 'London' AND STATUS > 10
Ж1) ( S { S# } INTERSECT ( SPJ WHERE J# = J# ( 'Jl' ) ) { S# } )
UNION ( S WHERE CITY = 'London' ) { S# }
ж2) S { S# } INTERSECT ( ( SPJ WHERE J# = J# ( 'Jl' ) ) { S# } )
UNION ( S WHERE CITY = 'London' ) { Si } )
31) ( SPJ WHERE J# = J# ( 'Jl' ) ) { Si }
MINUS ( SPJ WHERE P# = Pi ( 'Pl' ) ) { Si }
Глава 17. Оптимизация
665
з2) ( ( SPJ WHERE J# = J# ( 'Jl' ) )
MINUS ( SPJ WHERE P# = P# ( 'Pl' ) ) ) { S# }
И1) S JOIN ( P { CITY } MINUS J { CITY } )
и2) ( S JOIN P { CITY } ) MINUS ( S JOIN J { CITY } )
17.2. Докажите, что операции соединения, объединения и пересечения являются комму-
тативными, а операция вычитания — нет.
17.3. Докажите, что операции соединения, объединения и пересечения являются ассо-
циативными, а операция вычитания — нет.
17.4. Докажите, что:
а) объединение распределяется по пересечению;
б) пересечение распределяется по объединению.
17.5. Докажите, что для всех А и В:
a) A UNION ( A INTERSECT В ) = А;
б) A INTERSECT ( A UNION В ) = А.
Замечание. Эти два закона называются законами поглощения. Как и законы
идемпотентности, коммутативности и т.д., они могут оказаться полезными при
проведении оптимизации.
17.6. Докажите следующее.
а) Выборка безусловно распределяема по объединению, пересечению и вычита-
нию и условно распределяема по соединению.
б) Проекция безусловно распределяема по объединению и пересечению, условно
распределяема по соединению и не распределяема по вычитанию. Запишите
соответствующие критерии для условной распределяемости.
17.7. Распространите правила преобразования, изложенные в разделе 17.4, так, чтобы
учитывались операторы EXTEND и SUMMARIZE.
17.8. Можно ли сформулировать какие-либо полезные правила преобразований для опе-
рации реляционного деления?
17.9. Запишите соответствующий набор правил преобразования для условий, в которых
используются операторы AND, OR и NOT. Примером таких правил может служить за-
кон коммутативности для оператора AND, т.е. утверждение, что выражение A AND В
тождественно выражению В AND А.
17.10. Распространите ответ на предыдущее упражнение, включив в сферу его действия
условия, в которых используются кванторы EXISTS и FORALL. Примером может
служить правило, изложенное в главе 7, и позволяющее преобразовать выражения,
использующие квантор FORALL, в выражения с отрицаемым квантором EXISTS.
17.11. Ниже перечислены ограничения целостности для базы данных поставщиков, дета-
лей и проектов.
Допустимыми городами являются Лондон ('London'), Париж ('Paris'), Рим
('Rome'), Афины ('Athens'), Осло ('Oslo'), Стокгольм ('Stockholm'), Мадрид
('Madrid') и Амстердам ('Amsterdam').
Никакие два проекта не могут быть размещены в одном и том же городе.
666
Часть V. Дополнительные аспекты
В любой момент в Афинах может находиться не более одного поставщика.
Ни одна поставка по количеству не может превышать удвоенное среднее значе-
ние количества по всем поставкам.
Поставщик с наибольшим статусом не может находиться в одном городе с по-
ставщиком с наименьшим статусом.
Каждый проект должен находиться в городе, в котором есть хотя бы один по-
ставщик этого проекта.
Должна существовать по крайней мере одна красная деталь.
Среднее значение статуса поставщика должно быть больше 18.
Каждый поставщик из Лондона должен поставлять деталь с номером ' Р2'.
Хотя бы одна красная деталь должна весить меньше 50 фунтов.
Поставщики из Лондона поставляют больше различных видов деталей, чем по-
ставщики из Парижа.
Поставщики из Лондона поставляют больше деталей (по общему количеству),
чем поставщики из Парижа.
Ниже перечислены простые запросы к этой базе данных:
а) выбрать сведения о поставщиках, которые не поставляют деталь с номером ' Р2';
б) выбрать сведения о поставщиках, которые не поставляют детали для какого-
либо проекта в том же городе, где они находятся;
в) выбрать сведения о таких поставщиках, для которых не существует других по-
ставщиков, поставляющих меньше видов деталей;
г) выбрать сведения о поставщиках из Осло, которые поставляют по крайней мере
два разных вида деталей из Парижа для по крайней мере двух разных проектов
в Стокгольме;
д) выбрать сведения о парах поставщиков из одного города, поставляющих пары
деталей из одного и того же города;
е) выбрать сведения о парах поставщиков из одного города, поставляющих детали
парам проектов, находящихся в одном городе;
ж) выбрать сведения о деталях, поставляемых хотя бы для одного проекта, но только
теми поставщиками, которые размещены не в том городе, где находится сам проект;
з) выбрать сведения о поставщиках наибольшего количества различных типов деталей.
Используйте приведенные выше ограничения целостности для преобразования дан-
ных запросов в более простую форму (но все еще на обычном языке — от вас не
требуется выполнять это упражнение формально).
17.12. Исследуйте доступную вам СУБД. Выполняет ли эта система преобразование вы-
ражений (сейчас это делают не все СУБД)? Если это так, то какие выполняются
преобразования?
17.13. Попробуйте провести следующий эксперимент. Возьмите простой запрос, например
“Выбрать имена поставщиков детали с номером ' Р2' ”, и запишите его всеми извест-
ными вам способами с помощью любого доступного языка запросов (возможно, это
будет язык SQL). Создайте и заполните данными подходящую тестовую базу данных,
выполните все версии запроса и определите время выполнения каждой версии. Если
полученные значения будут сильно различаться, значит, экспериментально доказано,
Глава 17. Оптимизация
667
что оптимизатор системы не полностью справляется с задачей преобразования вы-
ражений. Повторите этот эксперимент с различными исходными запросами. Если
возможно, повторите этот же эксперимент в разных СУБД.
Замечание. Безусловно, разные версии запроса должны давать идентичные резуль-
таты. Если же результаты различаются, то, возможно, вы совершили ошибку или
ошибка существует в оптимизаторе рассматриваемой СУБД. Если обнаружена
ошибка в оптимизаторе, сообщите об этом разработчику СУБД!
17.14. Исследуйте любую доступную вам СУБД. Поддерживает ли она какие-либо стати-
стические показатели базы данных (это делают не все СУБД)? И если поддерживает,
то какие именно? Как эти статистические показатели обновляются — динамически
или с помощью какой-либо утилиты? Если статистические показатели обновляются с
помощью утилиты, то как называется утилита и как часто она запускается? Насколь-
ко выборочно ее действие (в том смысле, что при запуске утилиты со специфически-
ми параметрами обновляется только определенная статистика)?
17.15. В разделе 17.5 было сказано, что в состав статистических показателей, поддерживае-
мых СУБД DB2, входят второе наибольшее и второе наименьшее значения каждого
столбца в каждой базовой таблице. Почему выбраны именно вторые значения?
17.16. В некоторых коммерческих продуктах пользователю разрешается создавать указате-
ли для оптимизатора. Например, в СУБД DB2 спецификация OPTIMIZE FOR п ROWS в
объявлении SQL-курсора означает, что пользователь предполагает извлечь с помо-
щью данного курсора не более п строк (т.е. оператор FETCH будет выполнен для дан-
ного курсора не более п раз). Такая спецификация иногда может позволить оптими-
затору выбрать более эффективный путь доступа, по крайней мере в случае, когда
пользователь действительно выполняет оператор FETCH не более п раз. Оправдано ли,
по вашему мнению, применение таких указателей? Обоснуйте свой ответ.
17.17. Разработайте набор процедур реализации для операций выборки и проекции
(руководствуясь приведенными в разделе 17.7 псевдокодами процедур для опера-
ции соединения). Выведите соответствующий набор формул стоимости для этих
процедур, предположив, что в данном случае нас интересует только количество
операций ввода-вывода (т.е. не пытайтесь учесть в своих формулах степень загруз-
ки процессора и других компонентов системы). Запишите и докажите любые ут-
верждения, принятые в процессе вывода этих формул.
Список литературы
Оптимизация представляет собой чрезвычайно большую и постоянно развиваю-
щуюся область исследований. Важность этих исследований становится значительнее,
чем когда-либо прежде в связи с все возрастающим интересом к системам поддержки
принятия решений, речь о которых пойдет в главе 21. Достаточно сказать, что за послед-
ние несколько лет около 50% докладов на ежегодных конференциях ACM SIGMOD в
той или иной мере были посвящены именно вопросам оптимизации. Приведенный ниже
список представляет собой относительно небольшую выборку из обширной литературы
по оптимизации и связанным с ней вопросам. Условно он разбит на следующие группы.
В [ 17.1 ]—[ 17.7] содержится обзор общих проблем оптимизации или введение в
эту тему.
668
Часть V. Дополнительные аспекты
В [17.8]-[17.17] рассматриваются эффективные методы реализации отдельных
реляционных операций, таких как соединение и обобщение.
В [17.18]—[17.33] представлены различные приемы преобразования выражений,
описанные в разделе 17.4. В частности в [ 17.27]—[ 17.30] рассматриваются се-
мантические преобразования.
В [17.34]—[ 17.45] обсуждаются приемы, использованные в System R, СУБД DB2
и СУБД INGRES, а также общая проблема оптимизации вложенных запросов в
стиле языка SQL.
В [17.46]—[ 17.61] содержится описание многочисленных приемов, хитростей и
идей, подлежащих исследованию в будущем, и т.п. В частности, в [17.58]-
[17.61] рассмотрено влияние параллельной обработки на вопросы оптимизации.
Замечание. Публикации, в которых рассматривается оптимизация в распределен-
ных системах, умышленно исключены из данного списка (см. главу 20).
17.1. Kim W., Reiner D.S., Batory D.S. (eds.). Query Processing In Database Systems.—
New York, N.Y.: Springer-Verlag, 1985.
Это антология работ, посвященных общим проблемам обработки запросов (не только
по оптимизации). Книга состоит из вступительного обозрения Джарка (Jarke), Коха
(Koch) и Шмидта (Schmidt), которое перекликается с публикацией [17.3], но не по-
вторяет ее. Далее следуют работы, описывающие обработку запросов в различных
контекстах: распределенные базы данных, гетерогенные СУБД, проблемы обновле-
ния представлений (работа [9.11] является одной из статей в этом разделе), нетради-
ционные приложения (например, CAD/CAM), оптимизация многооператорных за-
просов [17.49], машины баз данных и физическое проектирование базы данных.
17.2. Special Issue on Query Optimization // IEEE Database Eng. — September, 1982. — 5, № 3.
Это сборник из 13 коротких статей (академического и коммерческого направлений),
в которых описываются различные аспекты оптимизации запросов.
17.3. Jarke М., Koch J. Query Optimization in Database Systems // ACM Comp. Surv. —
June, 1984, — 16, №2.
Отличное учебное пособие. Включает обобщенную систему взглядов по проблеме
вычисления запросов, подобную представленной в разделе 17.3 данной главы, но
базирующуюся на реляционном исчислении, а не на алгебре. После этого в рамках
описанной системы взглядов обсуждается множество приемов оптимизации: син-
таксические и семантические преобразования, низкоуровневые операции реализа-
ции и алгоритмы генерации планов запроса и выбора плана с наименьшей стоимо-
стью. Приводится также обширный набор правил синтаксических преобразований.
Имеется достаточно большой список литературы (без аннотаций). Заметьте, одна-
ко, что после 1984 года по данной теме было опубликовано на порядок больше ра-
бот, чем до 1984 года [17.4].
В работе также кратко обсуждаются другие смежные проблемы, такие как опти-
мизация высокоуровневых языков запросов (т.е. языков, более мощных по срав-
нению с реляционной алгеброй или исчислением) и оптимизация в распределен-
ных базах данных.
17.4. Graefe G. Query Evaluation Techniques for Large Databases // ACM Comp. Surv. —
June, 1993, —25, №2.
Глава 17. Оптимизация
669
Еще одно прекрасное и более новое учебное пособие с обширным списком реко-
мендуемой литературы. “В этом обзоре представлены основы проектирования и
реализации инструментов выполнения запросов... В нем описан широкий круг
практических методов оценки запросов... включая итеративное выполнение слож-
ных планов выполнения запросов, дуализм алгоритмов нахождения соответствия
между множествами на основе сортировки и хеширования, типы параллельного
выполнения запросов и их реализацию, а также специальные операторы для новых
областей применения баз данных.” Рекомендуется прочесть эту работу.
17.5. Palermo F.P. A Data Base Search Problem // J.T. Todd (ed.), Information Systems:
COINS IV. — New York, N,Y,: Plenum Press, 1974.
Одна из наиболее ранних работ по оптимизации (фактически уже ставшая классиче-
ской). Начиная с произвольного выражения реляционного исчисления, в этой работе
сначала к нему применяется алгоритм приведения Кодда для преобразования выра-
жения в эквивалентное алгебраическое выражение (см. главу 7), а затем вводится не-
сколько усовершенствований этого алгоритма, включая перечисленные ниже.
Никакой кортеж не может извлекаться дважды.
Ненужные значения удаляются из кортежа во время его извлечения. Здесь под не-
нужными значениями подразумеваются либо значения атрибутов, не упомянутых
в запросе, либо значения, используемые только для организации выборки. Этот
процесс эквивалентен проекции отношения по некоторым “нужным” атрибутам, а
потому позволяет сократить не только пространство, выделяемое для каждого
кортежа, но и количество кортежей, с которыми ведется работа (в общем случае).
Метод, используемый для создания результирующего отношения, основан на
принципе наименьшего роста, поэтому оно растет очень медленно. Данный ме-
тод приводит к сокращению количества выполняемых сравнений и объема па-
мяти для хранения промежуточных результатов.
Для создания соединений применяется эффективный метод, основанный, во-
первых, на динамическом разложении значений, используемых в соединяемых
членах (например таких, как S.S# = SP.S#), на полусоединения, которые фак-
тически являются некоторой разновидностью динамически создаваемого вто-
ричного индекса (полусоединения Палермо отличаются от полусоединений,
описанных в главе 6), и, во-вторых, на использовании внутреннего представле-
ния каждого соединения, называемого косвенным соединением (indirect join), в
котором для идентификации кортежей — участников соединения используются
внутренние идентификаторы кортежей. Эти методы предназначены для сокра-
щения количества просмотров, необходимых для выполнения соединения, за
счет получения гарантии, что соединяемые кортежи каждого члена соединения
логически упорядочены в соответствии со значениями атрибутов соединения.
Благодаря этому допускается динамическое определение “наилучшей” после-
довательности операций доступа к нужным отношениям.
17.6. Gray J. (ed.). The Benchmark Handbook for Database and Transaction Processing
Systems (2nd edition). — San Francisco, Calif.: Morgan Kaufmann, 1993.
Совет по обработке транзакций (Transaction Processing Council — TPC) является неза-
висимой организацией, которая на протяжении ряда лет разработала несколько тестов,
фактически принятых в качестве промышленного стандарта. В данной книге содержит-
670
Часть V. Дополнительные аспекты
ся подробное описание этих тестов (а также некоторых других). Тест ТРС-А предназна-
чен для измерения производительности OLTP-обработки (где сокращение OLTP озна-
чает Online Transaction Processing, т.е. оперативная аналитическая обработка). Тест ТРС-
В является особой версией теста ТРС-А, предназначенной для измерения производи-
тельности СУБД и базовой операционной системы при игнорировании особенностей
взаимодействия с пользователями и т.п. Тест ТРС-С моделирует работу системы приема
и регистрации заказов (фактически это существенно расширенный вариант теста ТРС-
А). Тест TPC-D предназначен для измерения производительности работы системы под-
держки принятия решений. Он включает набор из 17 достаточно сложных SQL-
запросов (по сути, это единственный тест из четырех перечисленных выше, который
позволяет оценить качество работы собственно оптимизатора).
Замечание. Разработчики СУБД конкурируют друг с другом, добиваясь получения
более высоких показателей производительности при тестировании своих продуктов с
помощью перечисленных выше тестов. Однако следует отметить, что их рекламные
заявления нужно интерпретировать с чрезвычайной осторожностью, поскольку раз-
работчики и поставщики систем баз данных склонны прибегать к разнообразным
уловкам и трюкам для формального повышения показателей эффективности выпол-
нения этих тестов. Поэтому caveat emptor (пусть покупатель будет бдителен)!
17.7. Bitton D., DeWitt D.J., Turbyfill С. Benchmarking Database Systems: A Systematic
Approach // Proc. 9th Intern. Conf, on Very Large Data Bases. — Florence, Italy,
October-November, 1983.
Здесь впервые описано то, что сегодня называют “Висконсинским тестом” (так как
этот тест был разработан авторами данной работы в университете штата Висконсин).
В описываемом тесте используется набор отношений с точно указанными значения-
ми атрибутов. При его выполнении определяется производительность конкретно за-
данных алгебраических операций на указанных отношениях (например, различных
видов проекций, использующих атрибуты с разной степенью дублирования
значений). Таким образом, измеряется эффективность работы оптимизатора системы
на описанных выше основных операциях. (См. также [17.6].)
17.8. Bing Yao S. Optimization of Query Evaluation Algorithms // ACM TODS.— June,
1979, —4, №2.
В работе представлена общая модель вычисления запроса, которая включает многие
известные алгоритмы, как частный случай. Эта модель содержит перечисленные ни-
же низкоуровневые операции и соответствующие наборы формул стоимости.
Индексирование выборок
Индексирование соединений
Пересечение
Доступ к записям
Последовательный просмотр
Фильтрация выборки
Фильтрация соединения
Сортировка
Конкатенация
Проекция
Связный просмотр
Определенный алгоритм обработки запроса выражается в терминах перечислен-
ных низкоуровневых операций, и стоимость этого алгоритма может быть вычисле-
на с помощью формул стоимости. В работе рассмотрены различные классы алго-
Глава 17. Оптимизация
671
ритмов обработки запросов и для каждого класса выработаны формулы стоимости.
В результате проблема оптимизации запроса сводится к решению простого набора
уравнений для вычисления минимальной стоимости. Затем выбирается класс алго-
ритмов, соответствующий полученной минимальной стоимости.
17.9. Biasgen M.W., Eswaran К.Р. Storage and Access in Relational Databases H IBM Sys.
J. — 1977. — 16, №4.
Представлены результаты сравнения различных приемов обработки запросов, в ко-
торых используются операции проекции, выборки и соединения, на основе их
стоимости, выраженной в операциях ввода-вывода. Основные компоненты этих
методов реализованы в системе System R [17.34].
17.10. Merrett Т.Н. Why Sort/Merge Gives the Best Implementation of the Natural Join 11 ACM
SIGMOD. — January, 1983, — 13, №2.
Представлен набор интуитивно понятных аргументов в пользу утверждения, что с
помощью сортировки-слияния можно достичь самых эффективных результатов. В
основном, аргументы сводятся к тому, что:
а) операция соединения будет наиболее эффективной, если оба отношения будут
отсортированы по значениям атрибута, по которому выполняется соединение
(поскольку в данном случае, как показано выше, в разделе 17.7, слияние — дос-
таточно эффективный метод оптимизации, а выборка каждой страницы выпол-
няется только один раз, что действительно является оптимальным);
б) стоимость сортировки отношений в необходимом порядке (на достаточно
больших машинах) будет, вероятно, меньше стоимости любой схемы, в которой
не требуется упорядоченность кортежей в обоих отношениях.
Тем не менее автор допускает, что для его радикальной позиции могут существо-
вать исключения. Например, одно из отношений может быть настолько мало
(например, в случае, когда оно является результатом предыдущей операции вы-
борки), что прямой доступ ко второму отношению через индекс или хеш-таблицу
будет иметь меньшую стоимость, чем сортировка второго отношения. В [17.8]-
[17.11] приведены дополнительные примеры, в которых метод сортировки-слияния
на практике не является лучшим приемом обработки.
17.1 1.Sacco G.M. Fragmentation: A Technique for Efficient Query Processing // ACM
TODS. — June, 1986. — 11, № 2.
Представлен один из методов, использующих принцип “разделяй и властвуй”
для выполнения операции соединения. Согласно этому методу соединяемые от-
ношения рекурсивно разбиваются на подмножества кортежей (фрагменты) и в
этих фрагментах выполняется серия последовательных просмотров. В отличие
от метода сортировки-слияния этот метод не требует предварительной сортиров-
ки отношений. Показано, что фрагментация всегда работает эффективнее сорти-
ровки-слияния, когда последний метод требует предварительной сортировки
обоих отношений, и иногда работает лучше, если метод сортировки-слияния
требует предварительной сортировки только одного (большего) отношения. Ав-
тор утверждает, что данный метод можно применять и для других операций, та-
ких как пересечение и вычитание.
17.1 2.Shapiro L.D. Join Processing in Database Systems with Large Main Memories // ACM
TODS. — September, 1986. — 11, № 3.
672
Часть V. Дополнительные аспекты
Представлено три новых алгоритма хеширования при выполнении операции со-
единения. Один из них “особенно эффективен при наличии основной памяти в
размере, значительно превышающем размер одного из соединяемых отношений”.
Алгоритмы работают благодаря разбиению отношений на непересекающиеся части
(т.е. выборки), которые можно обрабатывать в основной памяти. Автор заявляет,
что, исходя из наблюдаемого снижения цен на первичную память, методы на осно-
ве хеширования могут стать одними из лучших.
17.13. Negri М., Pelagatti G. Distributive Join: A New Algorithm for Joining Relations // ACM
TODS. — December, 1991. — 16, № 4.
Здесь представлен другой метод соединения, использующий принцип “разделяй и
властвуй”, который “...базируется на идее о том, что... не нужно полностью сортиро-
вать оба отношения... Достаточно отсортировать одно отношение полностью, а дру-
гое — лишь частично, избежав таким образом расходов на выполнение полной сор-
тировки второго отношения”. При частичной сортировке рассматриваемая перемен-
ная-отношение разбивается на последовательность неупорядоченных подмножеств
кортежей Pl, Р2, ..., Рп (похоже на метод Сакко (Sacco) [17.11], за исключением того,
что в методе Сакко используется хеширование вместо сортировки), обладающих
следующим свойством: MAX(P[i]) < MIN(P[i+l]) для всех i (1, 2, ..., п-1). Ут-
верждается, что данный метод работает эффективнее метода сортировки-слияния.
17.14. Graefe G., Cole R.L. Fast Algorithms for Universal Quantification in Large Databases 11
ACM TODS. — June, 1995. — 20, № 2.
Квантор всеобщности (FORALL) в языке SQL непосредственно не поддерживается, а
потому он не поддерживается и в современных коммерческих СУБД, хотя он чрез-
вычайно важен для формулировки широкого класса запросов. В этой статье опи-
сываются и сравниваются “три известных алгоритма и один недавно предложен-
ный алгоритм реляционного деления, которое является алгебраическим операто-
ром, включающим квантор всеобщности”. В ней также показано, что новый алго-
ритм работает “с той же скоростью, с какой выполнение хешированного полусо-
единения позволяет получить оценку значения квантора существования для тех же
отношений”. Помимо всего прочего, авторы делают вывод, что квантор FORALL не-
обходимо включить в пользовательский язык, так как большинство оптимизаторов
“не распознает его косвенные формулировки на языке SQL”.
17.15. Bitton D., DeWitt D.J. Duplicate Record Elimination in Large Data Files // ACM
TODS. — June, 1983. — 8, № 2.
Традиционный метод исключения кортежей-дубликатов состоит в сортировке за-
писей с последующим последовательным просмотром. Данная работа предлагает
альтернативное решение, более эффективное для файлов большого размера.
17.16. Simmen D., Shekita Е., Malkemus Т. Fundamental Techniques for Order Optimization H Proc.
1996 ACM SIGMOD Int. Conf, on Management of Data. — Montreal, Canada, June, 1996.
В этой работе представлены методы оптимизации или исключения сортировок.
Они частично основаны на работе Дарвена [10.6] и именно в таком виде реализо-
ваны в СУБД DB2.
17.17. Manku G.S., Rajagopalan S., Lindsay B.G. Approximate Medians and Other Quantities
in One Pass and with Limited Memory 11 Proc. 1998 ACM SIGMOD Int. Conf, on
Management of Data. — Seattle, Wash., June, 1998.
Глава 17. Оптимизация
673
17.18. Smith J.M., Yen-Tang Chang P. Optimizing the Performance of a Relational Algebra
Database Interface // CACM. — October, 1975. — 18, № 10.
Описан алгоритм, использовавшийся в языке “Smart Query Interface for a Relational
Algebra” (SQUIRAL). Этот алгоритм включает следующее.
Преобразование исходного алгебраического выражения в эквивалентную, но
более эффективную последовательность операций в соответствии с принципа-
ми, обсуждавшимися выше, в разделе 17.4.
Привязка отдельных операций в преобразованном выражении к определенным
процессам и использование параллельной и конвейерной обработок для выпол-
нения операций.
Координация порядка сортировки в промежуточных результатах, передаваемых
между процессами.
Использование индексов и попытки локализации страничных ссылок.
Эта статья была одной из первых работ, посвященных преобразованиям выражений.
17.19. Hall P.A.V. Optimization of a Single Relational Expression in a Relational Data Base
System 11 IBM J. R&D. — May, 1976. — 20, № 3.
Описаны некоторые методы оптимизации, используемые в системе PRTV [6.9], ко-
торая, как и язык SQUIRAL [17.18], начинает обработку запроса с преобразования
данного алгебраического выражения в некоторую более эффективную форму. Осо-
бенностью системы PRTV является то, что она не вычисляет каждое выражение
автоматически, как только оно будет получено. Вместо этого выражения комбини-
руются с полученными ранее в более сложное выражение и вычисление отклады-
вается до последнего момента (см. обсуждение пошаговой формулировки запроса
в главе 6, раздел 6.5). Таким образом, “отдельное реляционное выражение” (из за-
головка статьи) на самом деле представляет целую последовательность операций
пользователя. Данный метод оптимизации подобен методу языка SQUIRAL, но в
некоторых перечисленных ниже случаях работает лучше.
Выборка выполняется настолько рано, насколько это возможно.
Последовательность проекций комбинируется в одну операцию проекции.
Избыточные операции исключаются.
Выражения, использующие пустые отношения и тривиальные условия, упрощаются.
Общие выражения выносятся за скобки.
В заключении работы изложены результаты некоторых экспериментов, а также
указаны направления дальнейших исследований.
17.20. Jarke М., Koch J. Range Nesting: A Fast Method to Evaluate Quantified Queries // Proc. 1983
ACM SIGMOD Intern. Conf, on Management of Data. — San Jose, Calif, May, 1983.
Предложен вариант реляционного исчисления, в котором допускается примене-
ние некоторых дополнительных (и полезных) правил синтаксического преобра-
зования. Представлены алгоритмы вычисления выражений в описанном исчис-
лении. (Это исчисление очень напоминает исчисление кортежей, упомянутое в
главе 7.) Кроме того, описана оптимизация в предложенном исчислении отдель-
ного класса выражений, называемых “точными вложенными выражениями”. Из-
ложены методы преобразования в точные выражения относительно сложных за-
674
Часть К Дополнительные аспекты
просов (в частности, запросов, использующих квантор FORALL). Авторы показы-
вают, что в точные выражения можно преобразовать большое количество запро-
сов, используемых на практике.
17.21. Chaudhari S., Shim К. Including Group-By in Query Optimization П Proc. 20th Int.
Conf, on Very Large Data Bases. — Santiago, Chile, September, 1994.
17.22. Makinouchi A., Tezuka M., Kitakami H., Adachi S. The Optimization Strategy for Query
Evaluation in RDB/V1 // Proc. 7th Intern. Conf, on Very Large Data Bases— Cannes,
France, September, 1981.
Система RDB/V1 является прототипом будущего программного продукта AIM/RDB
компании Fujitsu (это SQL-система). В публикации описаны приемы оптимизации,
используемые в данном прототипе. Они кратко сравниваются с аналогичными прие-
мами, используемыми в прототипах систем INGRES и System R. Один из приемов
является новым и состоит в применении динамически полученных значений функции
МАХ и MIN для выполнения дополнительных выборок. Подобный прием приводит к
упрощению процесса выбора порядка соединения и повышает производительность
самой операции соединения. В качестве простого примера для последнего утвержде-
ния предположим, что нужно соединить отношения поставщиков S и деталей Р по ат-
рибуту CITY. Сначала отношение S сортируется по атрибуту S.CITY. В процессе сор-
тировки для атрибута S.CITY определяются значения функций МАХ и MIN; обозначим
их через HIGH и LOW соответственно. Тогда для уменьшения количества кортежей от-
ношения Р, которые потребуется проверять в процессе выполнения соединения,
можно использовать следующую выборку.
1. LOW < P.CITY AND P.CITY < HIGH
17.23. Pirahesh H., Hellerstein J.M., Hasan W. Extensible Rule Based Query Rewrite
Optimization in Starburst // Proc. 1992 ACM SIGMOD Intern. Conf, on Management
Data. — San Diego, Calif., June, 1992.
Как отмечалось в разделе 17.1, для преобразования выражений используется еще
одно название — перезапись запросов (query rewrite). По мнению авторов, не-
сколько неожиданно то, что в современных реляционных СУБД мало внимания
уделяется такому преобразованию (по крайней мере, по состоянию на 1992 год).
В работе описан механизм преобразования выражений прототипа системы
Starburst корпорации IBM [17.50], [25.14], [25.17], [25.21], [25.22]. Пользователи
с соответствующей квалификацией могут в любое время добавить в систему но-
вые правила преобразования выражений (вот почему в заголовке статьи указано
слово “расширяемый” — “extensible”).
17.24. Mumick I.S., Finkelstein S.J., Pirahesh H., Ramakrishnan R. Magic is Relevant // Proc. 1990
ACM SIGMOD Intern. Conf, on Management Data. — Atlantic City, N.J., May, 1990.
Неудачный термин “magic” (“волшебный”) используется в данной публикации для
ссылок на метод оптимизации, который изначально создавался для обработки за-
просов (в частности, рекурсивных), записанных на языке логических баз данных
Datalog (глава 23). Данная работа расширяет этот подход до условно-реляционных
систем, утверждая на основе экспериментальных измерений, что он часто эффек-
тивнее традиционных приемов оптимизации (заметьте, что запрос не обязательно
должен быть рекурсивным, чтобы можно было применить к нему описанный
675
Глава 17. Оптимизация
метод). Основная идея метода состоит в декомпозиции данного запроса на не-
сколько меньших запросов, которые определяют “вспомогательные отношения”
(нечто похожее на метод декомпозиции запросов, рассмотренный в разделе 17.6)
таким образом, что их можно использовать для фильтрации кортежей, не относя-
щихся к данному запросу. Ниже приведен пример запроса, который базируется на
примере из данной работы.
R := EX.ENAME WHERE EX.JOB = 'Clerk' AND EX.SAL >
AVG ( EY WHERE EY.DEPT# = EX.DEPT#, SAL ) ;
(“Выбрать имена клерков ('Clerk'), чья зарплата больше средней зарплаты по от-
делу.”) Если этот запрос выполнять “прямолинейно” (т.е. именно так, как он запи-
сан), система будет проверять отношение, содержащее данные о сотрудниках, кор-
теж за кортежем, пока не вычислит среднюю зарплату для каждого отдела, в кото-
ром работает более одного клерка. Традиционный оптимизатор разобьет исходный
запрос на два запроса меньшего размера.
Tl := ( EX.DEPT#,
AVG ( EY WHERE EY.DEPT# = EX.DEPT#, SAL ) AS ASAL ) ;
T2 := EMP.ENAME WHERE EMP.JOB = 'Clerk' AND
EXISTS Tl ( EMP.DEPT# = Tl.DEPT# AND
EMP.SALARY > Tl.ASAL ) ;
Теперь ни для одного отдела средняя зарплата не будет вычисляться больше одно-
го раза, но будут обрабатываться некоторые не относящиеся к запросу кортежи, в
частности кортежи с данными об отделах, в которых клерки вовсе не работают.
“Волшебный” подход исключает оба нежелательных варианта, повторное вычис-
ление средней зарплаты и обработку не относящихся к запросу кортежей за счет
генерации “вспомогательных” отношений.
/* Первое вспомогательное отношение: */
/* Имена, отделы и зарплата клерков */
Tl := ( EMP.ENAME, ЕМР.DEPT#, ЕМР.SAL )
WHERE ЕМР.JOB = 'Clerk' ;
/* Второе вспомогательное отношение: */
/* Отделы, в которых работают клерки */
Т2 := Tl.DEPT# ;
/* Третье вспомогательное отношение: */
/* Отделы, в которых работают клерки, */
/* и средняя зарплата для каждого отдела */
ТЗ := ( T2.DEPT#,
AVG ( ЕМР WHERE ЕМР.DEPT# = T2.DEPT#, SAL ) AS ASAL ) ;
/* Отношение-результат */
R := Tl.ENAME WHERE EXISTS T3 ( Tl.DEPT# = T3.DEPT# AND
Tl.SAL > T3.ASAL ) ;
676
Часть V. Дополнительные аспекты
“Волшебство” состоит в том, чтобы определить, какие именно вспомогательные
отношения требуется создать.
(См. [17.25], [17.26], а также список литературы в главе 23.)
17.25. Mumick I.S., Pirahesh Н. Implementation of Magic in Starburst H Proc. 1990 ACM
SIGMOD Int. Conf, on Management Data. — Minneapolis, Minn., May, 1994.
17.26. Mumick I.S., Finkelstein S.J., Pirahesh H., Ramakrishnan R. Magic Conditions H ACM
TODS. — March, 1996. — 21, № 1.
17.27. King J.J. QUIST: A System for Semantic Query Optimization in Relational Databases 11
Proc. 7th Intern. Conf, on Very Large Data Bases. — Cannes, France, September, 1981.
Представлена идея семантической оптимизации (см. раздел 17.4). В статье описана
экспериментальная система QUIST (QUery Improvement through Semantic
Transformation — улучшение запросов посредством семантических преобразований),
способная выполнять подобные преобразования.
17.28. Shenoy S.T., Ozsoyoglu Z.M. A System for Semantic Query Optimization // Proc. 1987 ACM
SIGMOD Intern. Conf, on Management of Data. — San Francisco, Calif, May-June, 1987.
Эта публикация расширяет работу Кинга (King) [17.27], представляя схему,
которая динамически выбирает из потенциально очень большого множества
ограничений целостности только те ограничения, которые будут полезны для
обработки данного запроса. Рассматриваемые ограничения целостности разде-
лены на два типа: ограничения причастности (например, “если партия деталей
содержит более 300 единиц, то поставщик должен находиться в Лондоне”) и
ограничения подмножеств (например, “каждый поставщик, находящийся в
Лондоне, должен поставлять хотя бы одну деталь”). Подобные ограничения
используются для преобразования запросов посредством исключения избы-
точных выборок и соединений и введения дополнительных выборок для ин-
дексированных атрибутов. Случаи, когда результат запроса может быть полу-
чен непосредственно из ограничений целостности, также эффективно обраба-
тываются с помощью изложенного метода.
17.29. Siegel М., Sciore Е., Salveter S. A Method for Automatic Rule Derivation to Support
Semantic Query Optimization 11 ACM TODS. — December, 1992. — 17, № 4.
Как было показано в этой главе, семантическая оптимизация использует ограниче-
ния целостности для преобразования запросов. Тем не менее существует несколько
проблем, связанных с этой идеей.
Как оптимизатор может узнать, какое преобразование будет эффективным (т.е.
какое преобразование сделает запрос более эффективным)?
Некоторые ограничения целостности не очень полезны для решения задач оп-
тимизации. Например, ограничение, которое требует, чтобы вес детали был
больше нуля, важно для целостности базы данных, но по сути бесполезно для
целей оптимизации. Как оптимизатор сможет отличить полезные ограничения
целостности от бесполезных?
Некоторые утверждения могут быть справедливы для определенных состояний
базы данных (даже для большинства состояний), однако они не будут ограни-
чениями целостности. Примером может служить утверждение вида
ЕМР.AGE < 50 (возраст сотрудников— не более 50 лет), которое не является
677
Глава 17. Оптимизация
ограничением целостности как таковым (поскольку могут быть сотрудники и
старше 50 лет), но в данный момент в компании может действительно не быть
сотрудников старше 50 лет.
В этой публикации описана архитектура системы, учитывающей перечисленные
проблемы.
17.30.Chakravarthy U.S., Grant J., Minker J. Logic-Based Approach to Semantic Query
Optimization // ACM TODS. — June, 1990. — 15, № 2.
Цитата из вступления: “В нескольких предыдущих работах авторами была описана
и доказана правильность метода семантической оптимизации запросов... В этой
работе обобщаются основные результаты из предыдущих работ и особое внимание
обращается на методы и их применимость к оптимизации реляционных запросов.
Дополнительно в этой работе показано, каким образом описываемый метод подво-
дит итоги и обобщает результаты более ранних работ в области семантической оп-
тимизации. [Кроме того, отмечается] как методы семантической оптимизации за-
просов могут быть распространены на рекурсивные запросы и ограничения цело-
стности, содержащие дизъюнкции, отрицания и рекурсию”.
17.31.Aho A.V., Sagiv Y., Ullman J.D. Efficient Optimization of a Class of Relational
Expressions 11 ACM TODS. — December, 1979. — 4, № 4.
Класс реляционных выражений, упоминаемый в заголовке этой работы, содержит
выражения, использующие только операции отбора по равенству (которые в этой
статье называются выборками), проекции и естественного соединения. Этот класс
выражений иногда называют SPJ-выражениями (от англ, “select”, “projection”,
“join” — “выборка”, “проекция”, “соединение”). SPJ-выражения соответствуют за-
просам в реляционном исчислении, в которых используются только сравнения на
равенство, операции AND и кванторы EXISTS. В работе приводится определенный
вид таблицы (табло — tableau), представляющей двумерный массив, в котором
столбцы соответствуют атрибутам, а строки — условиям, в частности условиям
принадлежности, которые гласят, что конкретный кортеж значений принадлежит
конкретному отношению. Строки табло логически связываются посредством по-
мещения общих символов в связанные строки. Например, табло
S#_______STATUS CITY______________P#________COLOR
_________al___________________________________________
bl al 'London' - S (поставщики)
bl b2 - SP (поставки)
b2 'Red' - P (детали)
представляет запрос “Выбрать статус (al) поставщиков (bl) в Лондоне, которые
поставляют красные детали (Ь2)”. Верхняя строка в табло представляет все атрибу-
ты, которые используются в запросе, следующая строка — это “итоги” (она соот-
ветствует кортежу-прототипу в запросе, определенном в исчислении, или финаль-
ной проекции в алгебраическом запросе), а оставшиеся строки (как уже говори-
лось) представляют условия принадлежности. В данном примере эти строки про-
комментированы посредством указания относящихся к запросу отношений
(точнее, переменных-отношений). Обратите внимание, что b используется для
ссылок на связанные переменные, а а — для ссылки на свободную переменную.
Итоговая строка содержит только переменные типа а.
678
Часть V. Дополнительные аспекты
Табло — это еще один вариант канонической формулировки для представления
запросов (см. раздел 17.3), однако оно не является достаточно общим, чтобы пред-
ставить все возможные реляционные запросы. (Фактически табло можно рассмат-
ривать как синтаксическую разновидность языка Query-By-Example (QBE), хотя и
менее мощную, чем непосредственно язык QBE.) В работе представлены алгорит-
мы преобразования одного табло в другое, семантически эквивалентное табло, в
котором количество строк уменьшено до минимума. Так как количество строк (не
считая двух верхних специальных строк) на единицу больше количества соедине-
ний в соответствующем SPJ-выражении, полученное табло представляет опти-
мальную форму запроса, хотя и в очень специальном смысле (минимальное коли-
чество соединений). (В приведенном выше примере количество соединений уже
минимально, поэтому подобная оптимизация не дает никакого эффекта.) После
этого полученное минимальное табло можно конвертировать обратно в другое
представление для последующей дополнительной оптимизации.
Идея минимизации количества соединений также применима к запросам, сформули-
рованным в терминах представлений, которые построены на основе операции соеди-
нения, в частности к запросам, сформулированным в терминах “универсальных от-
ношений” (см. список литературы в конце главы 12). Например, предположим, что
пользователю предложено представление V, определенное как соединение отноше-
ний S и SP по атрибуту S#, и пользователь вводит следующий запрос.
V { P# }
Прямой алгоритм обработки представлений преобразует данный запрос в
следующий.
( SP JOIN S ) { P# }
Тем не менее, как было показано в разделе 17.4, приведенный ниже запрос дает тот
же результат, хотя он вовсе не использует операции соединения (т.е. количество
соединений в исходном запросе минимизировано).
SP { P# }
Поэтому следует заметить, что, поскольку алгоритмы сжатия табло, описанные в
данной работе, учитывают все явно выраженные функциональные зависимости
между атрибутами (см. главу 10), они являются ограниченным примером метода
семантической оптимизации.
17.32.Sagiv Y., Yannakakis М. Equivalences Among Relational Expressions with the Union
and Difference Operators 11JACM. — October, 1980. — 27, № 4.
В этой статье идеи работы [17.31] расширены так, чтобы их можно было приме-
нять к запросам, использующим операции объединения и вычитания.
17.33.Levy A.Y., Mumick I.S., Sagiv Y. Query Optimization by Predicate Move-Around //
Proc. 1979 ACM SIGMOD Int. Conf, on Very Large Data Bases.— Santiago, Chile,
September, 1994.
17.34. Selinger P.G. et al. Access Path Selection in a Relational Database System П Proc. 1979
ACM SIGMOD Intern. Conf, on Management of Data. — Boston, Mass., May-June, 1979.
В этой важной статье обсуждаются некоторые методы оптимизации, используемые
в прототипе системы System R.
Глава 17. Оптимизация
679
Замечание. Оптимизатор системы System R является предшественником оптимиза-
тора СУБД DB2. В [17.35] дана более подробная информация, специфическая для
СУБД DB2.
В системе System R запрос представляет собой SQL-выражение, поэтому состоит из
набора блоков SELECT-FROM-WHERE (блоков запроса'). Одни блоки могут быть вложе-
ны в другие. Оптимизатор System R сначала определяет порядок, в котором будут
вычисляться блоки запроса, а затем пытается снизить общую стоимость запроса по-
средством выбора реализации с наименьшей стоимостью для каждого отдельного
блока запроса. Обратите внимание, что данная стратегия (сначала — выбор порядка
блоков, а затем — оптимизация отдельных блоков) означает, что конкретный план
выполнения всего запроса никогда не рассматривается, и это приводит к “сужению
пространства поиска” (см. замечания по этому поводу почти в конце раздела 17.3).
Замечание. В случае вложенных блоков оптимизатор вычисляет блоки во вло-
женном порядке, который указал пользователь, т.е. внутренний блок выполняет-
ся первым. В [17.39]—[ 17.45] можно найти критику и дальнейшее обсуждение
данной стратегии.
Для каждого блока запроса существует два случая, которые следует рассмотреть
(первый из них можно рассматривать как частный случай второго).
1. Для блока, в котором используется только выборка и (или) проекция единст-
венного отношения, оптимизатор применяет статистические данные из каталога
совместно с формулами (представленными в этой публикации) для немедлен-
ной оценки размера результата и стоимости низкоуровневых операций, а также
для выбора стратегии построения выборки и (или) проекции.
2. Для блоков, в которых используются два или больше отношений, соединенных
с помощью операции JOIN, возможно, с локальными выборками и (или) проек-
циями отдельных отношений, оптимизатор, во-первых, трактует каждое от-
дельное отношение, как случай 1, и, во-вторых, определяет последовательность
выполнения соединений. Эти две операции не являются независимыми одна от
другой. Так, для отдельного отношения А может быть выбрана определенная
стратегия доступа (например, на основе некоторого индекса), поскольку она по-
зволяет получать кортежи из А в том порядке, который удобен для выполнения
последующего соединения отношения А с другим отношением В.
Соединения реализуются с помощью метода сортировки-слияния, поиска по ин-
дексу или метода последовательного просмотра. В работе особое значение автор
придал тому, что при вычислении, например, вложенного соединения (A JOIN В)
JOIN С необязательно полностью вычислять вложенное соединение A JOIN В пе-
ред соединением его результата и отношения С. Наоборот, каждый кортеж соеди-
нения A JOIN В сразу после вычисления передается процессу, соединяющему этот
кортеж с кортежами из отношения С. Поэтому нет необходимости материализовать
отношение A JOIN В полностью. (Эта идея конвейерной обработки кратко обсуж-
далась в главе 3, раздел 3.2. См. также [17.18], [17.60].)
Эта работа включает и некоторые соображения о стоимости самого процесса опти-
мизации. Для соединения двух отношений стоимость приблизительно равна стоимо-
сти 5-20 операций выборки. При многократном выполнении оптимизированного за-
проса это довольно незначительные расходы. (Отметим, что система System R, как и
680
Часть И. Дополнительные аспекты
СУБД DB2, является компилирующей, поэтому однажды оптимизированный запрос
может выполняться сотни и даже тысячи раз.) В работе утверждается, что оптимиза-
ция сложных запросов требует “всего нескольких тысяч байтов пространства для
хранения и нескольких десятых долей секунды” на компьютере IBM System 370
Mode! 158. “Соединение восьми таблиц было оптимизировано за несколько секунд.”
17.35.Cheng J.M., Loosley C.R., Shibamiya A., Worthington P.S. IBM DATABASE 2
Performance: Design, Implementation, and Tuning 11 IBM Sys. J. — 1984. — 23, № 2.
Здесь содержится краткое описание тактики оптимизации в СУБД DB2 (в первой
версии этой системы): методы преобразования запросов, обработка вложенных
блоков запроса, методы соединения, выбор пути доступа и обработка индексов.
Замечание. В эту работу также включен интересный материал о других аспектах
работы СУБД DB2, влияющих на ее производительность.
17.36. Wong Е., Youssefi К. Decomposition— A Strategy foe Query Processing H ACM
TODS. — September, 1976. — 1, № 3.
17.37. Youssefi K., Wong E. Query Processing in a Relational Database Management System I I Proc.
5th Intern. Conf, on Very Large Data Bases. — Rio De Janeiro, Brazil, September, 1979.
17.38. Rowe L.A., Stonebraker M. The Commercial INGRES Epilogue H M. Stonebraker (ed.).
The INGRES Papers: The Anatomy of a Relational Database Management System. —
Reading, Mass.: Addison-Wesley, 1986.
Коммерческая СУБД Commercial INGRES — это программный продукт, получен-
ный из прототипа University INGRES (Университетская система). Ниже перечисле-
ны некоторые различия между оптимизаторами систем Commercial INGRES и
University INGRES.
1. Университетский оптимизатор использует инкрементное планирование, т.е. оп-
ределяет, что нужно сделать сначала, и делает это, затем определяет, что делать
дальше, исходя из размера полученного промежуточного результата, и т.д.
Коммерческий оптимизатор определяет полный план перед началом выполне-
ния на основе оценок размеров промежуточных результатов.
2. Университетский оптимизатор обрабатывает запросы с двумя переменными
(например, соединения) с помощью метода подстановки кортежей, обсуждав-
шегося в разделе 17.6. Коммерческий оптимизатор поддерживает несколько
мощных методов обработки подобных запросов, включая, в частности, метод
сортировки-слияния, описанный в разделе 17.7.
3. Коммерческий оптимизатор поддерживает более сложный набор статистиче-
ских показателей по сравнению с университетским оптимизатором.
4. Университетский оптимизатор выполняет инкрементное планирование (см. п.
1). Коммерческий оптимизатор выполняет более обширный поиск. Тем не ме-
нее поиск прекращается, если на оптимизацию будет затрачено время, превы-
шающее наилучшую оценку времени выполнения запроса (в противном случае
выполнение оптимизации не даст никаких преимуществ).
5. Коммерческий оптимизатор рассматривает все возможные комбинации индек-
сов, все возможные последовательности соединения и “все доступные методы
выполнения соединения — сортировку-слияние, частичную сортировку-
слияние, поиск по хеш-таблице, ISAM-поиск, поиск по В-дереву и метод после-
довательного просмотра” (см. раздел 17.7).
Глава 17. Оптимизация
681
17.39. Kim W. On Optimizing an SQL-Like Nested Query // ACM TODS. — September,
1982, —7, №3.
См. комментарий к [17.43].
17.40. Kiessling W. On Semantic Reefs and Efficient Processing of Correlation Queries with
Aggregates // Proc. 11th Intern. Conf, on Very Large Data Bases.— Stockholm,
Sweden, August, 1985.
См. комментарий к [17.43].
17.41. Ganski R.A., Wong H.K.T. Optimization of Nested SQL Queries Revisited // Proc. 1987
ACM SIGMOD Intern. Conf, on Management of Data. — San Francisko, Calif, May, 1987.
См. комментарий к [17.43].
17.42. Giinter von Biiltzingsloewen. Translating and Optimizing SQL Queries Having
Aggregates // Proc. 13th Intern. Conf, on Very Large Data Bases. — Brighton, England,
September, 1987.
См. комментарий к [17.43].
17.43. Muralikrishna M. Improved Unnesting Algorithms for Join Aggregate SQL Queries 11 Proc.
18th Intern. Conf, on Very Large Data Bases. — Vancouver, Canada, August, 1992.
Язык SQL позволяет создавать “вложенные подзапросы”, т.е. блоки SELECT-FROM-
WHERE, вложенные внутрь других подобных блоков. Эта конструкция порождает
некоторые трудности при реализации. Рассмотрим следующий SQL-запрос
(“Определить имена поставщиков детали с номером ' Р2'”), на который далее бу-
дем ссылаться, как на запрос Q1.
SELECT S.SNAME
FROM S
WHERE S.S# IN
( SELECT SP.S#
FROM SP
WHERE SP.P# = 'P2' ) ;
В системе System R [17.34] этот запрос будет реализован следующим образом.
Сначала будет вычислен внутренний блок и создана временная таблица Т, со-
держащая номера требуемых поставщиков. После этого кортеж за кортежем бу-
дет проверена вся таблица S и для каждого выбранного из нее кортежа будет
просматриваться таблица Т с целью определения, содержится ли в ней соответ-
ствующий номер поставщика. Эта стратегия достаточно неэффективна
(поскольку таблица Т не имеет индекса).
Теперь рассмотрим запрос Q2.
SELECT S.SNAME
FROM S, SP
WHERE S.S# = SP.S#
AND SP.P# = 'P2' ;
Легко установить, что он семантически идентичен предыдущему, но система
System R проанализирует дополнительную стратегию реализации данного запроса.
В частности, если таблицы S и SP окажутся физически сохраненными в последова-
тельности номеров поставщиков, то система применит слияние, которое будет вы-
682
Часгпъ V. Дополнительные аспекты
подняться весьма эффективно. Предположив, что два рассмотренных выше запро-
са логически эквивалентны, но второй вариант более удобен с точки зрения эффек-
тивности реализации, мы придем к выводу, что возможность преобразования за-
просов, подобных Q1, в запросы, подобные Q2, требует более глубокого изучения.
Эта возможность и является предметом обсуждения в [ 17.39]—[ 17.45].
Ким (Kim) [17.39] был первым, кто обратил внимание на эту проблему. В его рабо-
те идентифицировано пять типов вложенных запросов и описаны соответствующие
алгоритмы. В ней приводятся результаты экспериментов, которые показывают, что
предложенные алгоритмы повышают производительность обработки вложенных
запросов (обычно на один-два порядка).
Затем Кесслинг (Kiessling) [17.40] показал, что алгоритмы Кима работают не-
корректно, если в списке атрибутов выборки вложенного запроса (на любом
уровне) содержится обобщающая функция COUNT (алгоритм Кима некорректно
обрабатывает случаи, когда аргументы функции COUNT являются пустыми отно-
шениями). Термин “семантические рифы” в названии работы Кесслинга указы-
вает на сложности, с которыми сталкивается пользователь при попытке получить
корректные и непротиворечивые результаты подобных запросов. Более того,
Кесслинг показал, что алгоритмы Кима усовершенствовать непросто (поскольку
“похоже, не существует единого способа выполнить данное преобразование эф-
фективно и корректно при любых условиях”).
В работе Гански (Ganski) и Вонга (Wong) [17.41] описано решение проблемы, об-
наруженной Кесслингом. Оно состоит в использовании в преобразованной версии
запроса внешнего соединения (глава 18) вместо обычного внутреннего соединения.
(По мнению современных авторов, это усовершенствование не вполне удовлетво-
рительно, потому что оно вводит нежелательную зависимость упорядочения среди
операторов в преобразованном запросе.) В данной работе описывается еще одна
ошибка в оригинальной работе Кима, которая устраняется аналогичным способом.
Тем не менее работа не лишена собственных ошибок. Одни связаны с проблемой
строк-дубликатов (печально известные “семантические рифы” [17.40]), другие — с
изъянами в реализации квантора EXISTS в языке SQL [18.6].
В [17.42] предпринята попытка сформулировать всю проблему на теоретической
основе (основной проблемой предыдущих работ являлось то, что, как обнаружили
различные авторы, поведение —- семантическое и синтаксическое — вложений и
обобщающих функций в языке SQL не совсем понятно). В ней также определены
расширенные версии реляционного исчисления и реляционной алгебры
(расширения касались действий над обобщениями и неопределенными значениями
(NULLS)) и доказана эквивалентность расширенных формулировок (при этом ис-
пользовался более элегантный по сравнению с ранее опубликованным метод дока-
зательства). Затем семантика языка SQL представлена с помощью отображения
конструкций этого языка на расширенное исчисление, определенное в работе. Тем
не менее необходимо отметить следующее.
1. Обсуждаемый диалект языка SQL ближе к диалектам, используемым в коммер-
ческих продуктах, по сравнению с диалектами языка SQL, которые использу-
ются в [ 17.39]—[ 17.41]. Однако этот диалект еще не стал полностью общеприня-
тым. Он не включает оператора UNION и прямой поддержки операторов типа
Глава 17. Оптимизация
683
“=ALL” и “>ALL” (см. приложение А), а трактовка неизвестных истинных значе-
ний отличается от трактовки, обусловленной стандартом языка SQL (на самом
деле эта трактовка даже лучше).
2. В данной работе для “технического упрощения” не рассматриваются методы
исключения кортежей-дубликатов. Но влияние такого пропуска не совсем ясно
просматривается, исходя из того, что (как было показано ранее) наличие или
отсутствие кортежей-дубликатов может значительно повлиять на корректность
некоторых преобразований [5.6].
Наконец, в [17.43] утверждается, что в некоторых случаях оригинальные алгорит-
мы Кима [17.39], несмотря на некорректность, могут быть эффективнее “общей
стратегии”, изложенной в [17.41]. Поэтому автор работы [17.43] предлагает аль-
тернативный способ исправления ошибок в алгоритмах Кима. К тому же в этой ра-
боте представлены некоторые улучшения рассматриваемых алгоритмов.
17.44. Baekgrand L., Mark L. Incremental Computation of Nested Relational Query Expressions //
ACM TODS. — June, 1995. —20, № 2.
Еще одна статья об оптимизации запросов, включающих подчиненные запросы
в стиле языка SQL, в частности коррелированные запросы (“вложение”, упо-
мянутое в заголовке статьи, относится к вложенным подчиненным запросам в
стиле языка SQL). Предлагаемая стратегия включает преобразование исходно-
го запроса в эквивалентный запрос без вложений с последующей инкремент-
ной оценкой полученной версии запроса без вложений. “Для поддержки перво-
го этапа разработан очень краткий алгоритм преобразования типа “алгебра —
алгебра”... В [преобразованном] выражении интенсивно используется оператор
MINUS. Для реализации второго этапа предложен и проанализирован эффектив-
ный алгоритм инкрементной оценки операций MINUS.” Термин инкрементное
вычисление означает, что для оценки данного запроса могут использоваться
предварительно вычисленные результаты.
17.45. Rao J., Ross К.А. Using Invariants: A New Strategy for Correlated Queries // Proc. 1998
ACM SIGMOD Int. Conf, on Management of Data. — Seattle, Wash., June, 1998.
Еще одна статья об оптимизации запросов, в том числе подчиненных запросов в
стиле языка SQL.
17.46. Warren D.H.D. Efficient Processing of Interactive Relational Database Queries
Expressed in Logic // Proc. 7th Intern. Conf, on Very Large Data Bases. — Cannes,
France, September, 1981.
Представлен взгляд на оптимизацию запросов с точки зрения формальной логики.
Описаны приемы, которые используются в экспериментальной СУБД, для форму-
лировки запросов применяющей язык Prolog. Создается впечатление, что эти
приемы очень похожи на приемы, используемые в системе System R, хотя разрабо-
таны они были совершенно независимо и с несколько отличными целями. В работе
указывается, что в отличие от обычных языков запросов, таких как QUEL и SQL,
языки, основанные на логике (подобные языку Prolog), позволяют записывать за-
просы так, чтобы выделить следующее:
логические цели, которые являются основными компонентами запроса;
логические переменные, связывающие эти компоненты;
684
Часть V. Дополнительные аспекты
порядок достижения логических целей, который является критическим момен-
том с точки зрения реализации.
Из этого следует, что подобные языки весьма удобны в качестве базы для выпол-
нения оптимизации. Действительно, такой язык можно рассматривать в качестве
еще одного кандидата для внутреннего представления запроса, исходно сформули-
рованного с помощью какого-либо другого языка (см. раздел 17.3).
17.47. loannidis Y.E., Wong Е. Query Optimization by Simulated Annealing // Proc. 1987 ACM
SIGMOD Intern. Conf, on Management of Data. — San Francisco, Calif., May, 1987.
С увеличением числа отношений, используемых в запросе, количество возможных пла-
нов выполнения этого запроса растет экспоненциально. В традиционных коммерческих
приложениях число отношений в запросе обычно невелико и, следовательно, количест-
во потенциальных планов выполнения запроса (“пространство поиска”) остается в ра-
зумных пределах. Тем не менее в современных приложениях количество отношений в
запросе может быть достаточно большим (примеры приводятся в главе 21). Более того,
в приложениях нового типа ощущается необходимость “глобальной” (т.е. для многих
запросов) оптимизации [17.49] и поддержки рекурсивных запросов. Эти функции также
значительно увеличивают пространство поиска. Исчерпывающий поиск в таких усло-
виях становится неэффективным, и возникает настоятельная необходимость в исполь-
зовании методов сужения пространства поиска.
В публикации содержатся ссылки на более ранние работы по проблеме оптимиза-
ции запросов с большим количеством отношений и многозапросной оптимизации.
Однако в данной работе утверждается, что для оптимизации рекурсивных запросов
не разработано ни одного алгоритма, после чего приводится алгоритм, который,
как утверждают авторы, применим даже на пространствах поиска большого разме-
ра. В частности, показано, как применять предложенный алгоритм в случае рекур-
сивных запросов. Данный алгоритм (называемый “модельным отжигом”, так как
он моделирует процесс отжига, с помощью которого выращивают кристаллы, сна-
чала прогревая жидкий раствор, а затем постепенно охлаждая его) является высо-
коэффективным алгоритмом, который может успешно применяться для решения
проблемы оптимизации в других контекстах.
См. также [17.48].
17.48. Swami A., Gupta A. Optimization of Large Join Queries // Proc. 1988 ACM SIGMOD
Intern. Conf, on Management of Data. — Chicago, Ill., June, 1988.
Общая проблема определения оптимального порядка выполнения соединений в за-
просах, использующих большое количество отношений (что характерно для дедук-
тивных баз данных, описываемых в главе 23), является комбинаторно сложной. В
работе представлен сравнительный анализ нескольких алгоритмов, предназначен-
ных для решения этой проблемы: возмущенный обход, псевдослучайная генерация
данных, последовательные улучшения, последовательные эвристики и модельный
отжиг [17.47] (названия методов добавляют немного “поэзии” в предмет обсужде-
ния, который выглядит достаточно прозаично). Согласно результатам проведенно-
го анализа алгоритм последовательных улучшений превосходит все остальные ал-
горитмы, в частности алгоритм модельного отжига “сам по себе” нельзя использо-
вать для больших запросов-соединений.
17.49. Sell is Т.К. Multiple-Query Optimization // ACM TODS. — March, 1988. — 13, № 1.
Глава 17. Оптимизация
685
Классическое исследование оптимизации, в котором автор сосредоточился на
проблеме оптимизации отдельных изолированных реляционных выражений. В
будущем, однако, возможность оптимизации нескольких отдельных запросов,
как одного модуля, станет, вероятно, весьма важной. Одной из причин такого
состояния дел стало то, что единственный запущенный запрос на верхнем уровне
может быть преобразован в несколько запросов на реляционном уровне. В рабо-
те приведен следующий пример. Выдача на естественном языке запроса
“Хорошо ли оплачивается работа Майка?” может привести к выполнению трех
отдельных реляционных запросов.
Зарабатывает ли Майк больше $75 000?
Зарабатывает ли Майк больше $60 000, и обладает ли он опытом работы ме-
нее 5 лет?
Зарабатывает ли Майк больше $45 000, и обладает ли он опытом работы ме-
нее 3 лет?
Этот пример демонстрирует, что наборы связанных запросов обычно совместно
используют некоторые подчиненные выражения, поэтому подобные наборы запро-
сов приходится оптимизировать глобально.
В работе рассматриваются запросы, в которых используются только конъюнкции
выборок и (или) соединения по эквивалентности, а также излагаются обнадежи-
вающие результаты и предлагаются направления дальнейших исследований.
17.50. Lohman G.M. Grammar-Like Functional Rules for Representing Query Optimization
Alternatives // Proc. 1988 ACM SIGMOD Intern. Conf, on Management of Data.—
Chicago, III., June, 1988.
В некоторых случаях реляционные оптимизаторы можно рассматривать как экс-
пертные системы. Тем не менее исторически сложилось так, что правила, управ-
ляющие процессом оптимизации, встраиваются непосредственно в процедурный
код, а не записываются отдельно в декларативном виде. Вследствие этого расши-
рение оптимизатора путем добавления новых приемов оптимизации — непростая
задача. Будущие системы баз данных (глава 25), видимо, еще больше усугубят эту
проблему, так как явно просматривается необходимость индивидуальной установ-
ки дополнительных наборов правил, расширяющих возможности оптимизатора для
поддержки определенных пользователем специальных типов данных. Поэтому
разные исследователи предложили структурировать оптимизатор как экспертную
систему с использованием явно выраженных декларативных правил.
Однако эта идея страдает недостаточной производительностью. В частности, на
любой стадии обработки запроса может применяться большое количество пра-
вил, и поиск подходящего правила может потребовать достаточно сложных вы-
числений. В этой работе представлен альтернативный подход (в данный момент
используемый в прототипе системы Starburst [25.14], [25.17], [25.21], [25.22]), в
котором правила определяются посредством продуктивных правил грамматики,
подобной грамматикам формальных языков. Эти правила, называемые правила-
ми STAR (STrategy Alternative Rules — правила альтернативной стратегии), по-
зволяют осуществлять рекурсивное построение планов выполнения запросов из
других планов и “операторов плана нижнего уровня” (low-level plan operator —
LOLEPOP), которые являются базовыми операциями над отношениями, такими
686
Часть V. Дополнительные аспекты
как соединение, сортировка и т.п. Каждый из LOLEPOP-операторов имеет свои
подвиды. Например, LOLEPOP-оператор соединения имеет подвиды сортировки-
слияния, хеширования и т.д.
В работе утверждается, что изложенный выше подход имеет множество преимуществ:
правила (STAR) легко понятны тем, кто будет создавать новые правила; процесс
выбора правила, которое нужно применить в конкретной ситуации, проще и эф-
фективнее по сравнению с традиционным подходом, применяемым в экспертных
системах; кроме того, достигнута возможность расширяемости.
17.51. Nakano R. Translation with Optimization from Relational Calculus to Relational Algebra
Having Aggregate Functions // ACM TODS. — December, 1990. — 15, № 4.
Как показано в главе 7 (раздел 7.4), запросы на языке, базирующемся на реляци-
онном исчислении, можно реализовать посредством преобразования исходного
запроса в эквивалентное алгебраическое выражение с последующей оптимизаци-
ей полученного алгебраического выражения, которая завершается выполнением
этого оптимизированного выражения. Автор предлагает схему объединения пер-
вого и второго этапов, т.е. преобразование данного выражения реляционного ис-
числении непосредственно в оптимальное выражение в реляционной алгебре.
Утверждается, что эта схема “более эффективна и перспективна... так как слож-
ное алгебраическое выражение оптимизировать весьма непросто”. В процессе
оптимизации используются некоторые эвристические преобразования, постро-
енные на основе уже имеющихся знаний об эквивалентности некоторых выраже-
ний в исчислении и алгебре.
17.52. Whang K-Y., Krishnamurthy R. Query Optimization in a Memory-Resident Domain
Relational Calculus Database System // ACM TODS. — March, 1990. — 15, № 1.
Наиболее дорогой аспект в обработке запросов (в средах с достаточно большой
основной памятью, как предполагается в данной работе) — вычисление логиче-
ских выражений. Поэтому в подобных средах целью оптимизации является мини-
мизация количества таких вычислений.
17.53. Freytag J.C., Goodman N. On the Translation of Relational Queries into Iterative
Programs // ACM TODS. — March, 1989. — 14, № 1.
Представлены методы непосредственной компиляции реляционных выражений в
выполняемый код на таких языках, как С и Pascal. Заметьте, что этот поход отличает-
ся от подхода, изложенного в данной главе, где оптимизатор для создания плана вы-
полнения запроса комбинировал предварительно написанные (параметризованные)
фрагменты кода.
17.54. Ono К., Lohman G.M. Measuring the Complexity of Join Enumeration in Query
Optimization // Proc. 16th Intern. Conf, on Very Large Data Bases.— Brisbane,
Australia, August, 1990.
Так как операция соединения в своей основе является бинарной, оптимизатор должен
разбить соединение N отношений (N > 2) на последовательность бинарных соедине-
ний. Большинство оптимизаторов выполняет эту операцию в строго “вложенном”
порядке. Оптимизаторы выбирают пару отношений, которые будут соединены пер-
выми, после чего соединяют результат с третьим отношением и т.д. Другими слова-
ми, выражение, подобное A JOIN В JOIN С JOIN D, будет трактоваться как
(( D JOIN В ) JOIN С ) JOIN А, но ни в коем случае не как ( A JOIN D ) JOIN
Глава 17. Оптимизация
687
( В JOIN С ). Более того, традиционные оптимизаторы разрабатываются так, чтобы
вообще исключить выполнение операции декартова произведения. Показанные
приемы можно трактовать как “сужение пространства поиска”, поэтому для выбора
последовательности соединения все еще нужны эвристические методы.
В данной публикации также содержится описание других аспектов оптимизатора
прототипа системы IBM Starburst [17.50], [25.14], [25.17], [25.21], [25.22]. Автор
аргументирует это тем, что приведенные тактики в некоторых случаях неуместны,
поэтому возникает необходимость в адаптируемом оптимизаторе, который можно
заставить использовать разные тактики для различных запросов.
Замечание. В отличие от типичных современных коммерческих программных про-
дуктов, система Starburst способна трактовать выражение вида R.A = S.B + с как
условие “соединения”. Кроме того, она поддерживает свойство “транзитивной
замкнутости предикатов” (см. раздел 17.4).
17.55. Vance В., Maier D. Rapid Bushy Join-Order Optimization with cartesian Products // Proc.
1996 ACM SIGMOD Int Conf, on Management of Data. — Montreal, Canada, June, 1996.
Как сказано в комментарии к предыдущей ссылке, оптимизаторы стремятся
“сократить пространство поиска” (помимо всего прочего) за счет исключения пла-
нов выполнения запросов, в которых используется декартово произведение. В этой
статье показано, что поиск во всем пространстве “допустим в большей степени,
чем это признавалось прежде”, а исключение декартова произведения не всегда
желательно. Согласно утверждениям авторов, основными результатами этой ста-
тьи являются полное отделение определения порядка соединения от анализа пре-
дикатов и представление “новых технологий реализации” для решения проблемы
определения порядка соединения.
17.56. Ioannidis Y.E., Ng R.T., Shim К., Sellis Т.К. Parametric Query Optimization H Proc.
18th Intern. Conf, on Very Large Data Bases. — Vancouver, Canada, August, 1992.
Рассмотрим следующий запрос.
EMP WHERE SALARY > <зарллата>
Здесь параметр <зарплата> задается во время выполнения запроса. Предположим,
что атрибут SALARY (зарплата) обладает индексом. Тогда получаем следующее.
Если параметр <зарплата> имеет значение $10 000 в месяц, то лучшим спосо-
бом реализации запроса является индекс (так как можно предположить, что
большинство сотрудников не удовлетворяют условию выборки).
Если параметр <зарплата> имеет значение $ 1 000 в месяц, то лучшим способом
реализации запроса будет последовательный просмотр (так как можно предполо-
жить, что практически все сотрудники будут удовлетворять условию выборки).
Данный пример демонстрирует утверждение о том, что некоторые решения об оп-
тимизации лучше принимать во время выполнения, даже в компилирующих систе-
мах. В работе исследована возможность генерации наборов планов выполнения за-
просов во время компиляции (каждый план является “оптимальным” для некоторо-
го подмножества из множества всех возможных значений параметров времени вы-
полнения) и выбора соответствующего плана во время выполнения, когда реаль-
ные значения параметров уже известны. В частности, автор обращает внимание на
один конкретный параметр — размер пространства буфера для запроса. Результа-
688
Часть V. Дополнительные аспекты
ты экспериментов показали, что данный подход незначительно замедляет процесс
оптимизации и жертвует немногим в отношении качества генерируемых планов
запросов. Поэтому автор утверждает, что данный подход может существенно по-
высить производительность обработки запросов. “Значительный выигрыш в про-
изводительности можно получить от использования планов запросов, непосредст-
венно связанных с определенными значениями параметров.”
17.57. Kabra N., DeWitt D.J. Efficient Mid-Query Re-Optimization of Sub-Optimal Query
Execution Plans // Proc. 1998 ACM SIGMOD Int. Conf, on Management of Data.—
Seattle, Wash., June, 1998.
17.58. Gray J. Parallel Database Systems 101 // Proc. 1995 ACM SIGMOD Int. Conf, on
Management of Data. — San Jose, Calif., May, 1995.
Это не научная статья, а расширенная аннотация для презентации учебного посо-
бия. По сути, основная идея параллельных систем заключается в разбиении боль-
шой задачи на несколько малых задач, которые могут решаться одновременно, что
способствует общему повышению производительности. В частности, реляционные
системы баз данных прекрасно подходят для распараллеливания обработки по са-
мой природе реляционной модели. Дело в том, что концептуально легко выполня-
ются следующие действия: разбиение отношения несколькими разными способами
на несколько подчиненных отношений; разбиение реляционного выражения на не-
сколько подчиненных выражений также несколькими разными способами. В духе
заголовка этой статьи следует отметить некоторые важные концепции параллель-
ных систем баз данных.
Прежде всего, сама по себе архитектура используемого аппаратного обеспечения
должна предполагать возможность параллельной работы. Ниже перечислены три
основных типа такой архитектуры, каждая из которых включает несколько процес-
соров, несколько жестких дисков, а также сеть для обмена данными.
С разделением оперативной памяти. Сеть позволяет всем процессорам обра-
щаться к общей оперативной памяти.
С разделением дисковой памяти. Каждый процессор обладает собственной
оперативной памятью, но сеть позволяет всем процессорам обращаться к об-
щей дисковой (внешней) памяти.
Без разделения. Каждый процессор обладает собственной оперативной и дисковой
памятью, но сеть позволяет всем процессорам обмениваться данными между собой.
На практике обычно используется архитектура “без разделения”, по крайней
мере для больших систем (поскольку в двух других подходах при возрастании
числа процессоров очень скоро начинают появляться конфликтные ситуации).
Если говорить точнее, то архитектура “без разделения” обеспечивает линей-
ное ускорение, т.е. повышение времени отклика в N раз при увеличении вы-
числительной мощности аппаратного обеспечения в N раз, и линейное мас-
штабирование (scalability), т.е. время отклика остается постоянным при уве-
личении вычислительной мощности аппаратного обеспечения и объема данных
в одинаковое количество раз.
Ниже представлены некоторые способы секционирования данных (data
partitioning), т.е. разбиения отношения г на секции или подчиненные отношения и
распределение этих секций между п различными процессорами.
Глава 17. Оптимизация
689
Секционирование диапазона (range partitioning). Отношение г делится на непе-
ресекающиеся секции 1, 2, ..., п на основе значений некоторого подмножества s
атрибутов отношения г (концептуально отношение г отсортировано по под-
множеству атрибутов s, а результат разделен на п секций равного размера).
Секция i при этом соответствует процессору i. Данный подход очень удобен
для запросов с выборками на основе условий равенства или соответствия диа-
пазону для подмножества атрибутов отношения s.
Хеш-секционирование (hash partitioning). Каждый кортеж t отношения г соот-
ветствует процессору h(t), где h— некоторая хеш-функция. Этот метод пре-
красно подходит для запросов с выборками на основе условий равенства для
одного или нескольких хеш-атрибутов, а также для запросов с последователь-
ным доступом ко всему отношению г.
Круговое секционирование (round robin partitioning). Концептуально отношение
г отсортировано некоторым образом, а i-й кортеж в отсортированном резуль-
тате соответствует процессору с номером, вычисленным как результат деления
i по модулю п. Этот подход прекрасно подходит для запросов с последователь-
ным доступом ко всему отношению г.
Распараллеливание обработки можно применять для выполнения отдельной опе-
рации {интраоперационное распараллеливание), для выполнения разных опера-
ций внутри одного запроса {межоперационное или интразапросное распаралле-
ливание) и для выполнения разных запросов {.межзапросное распараллелива-
ние). Эти варианты рассмотрены в учебных пособиях [17.4], [17.61]; некоторые
методы и алгоритмы обсуждаются в [17.59], [17.60]. Следует отметить, что па-
раллельная версия хеш-соединения (см. раздел 17.7) особенно эффективна и ши-
роко используется на практике.
17.59.Bitton D., Boral Н., DeWitt D.J., Wilkinson К. Parallel Algorithms for the Execution of
Relational Database Algorithms // ACM TODS. — September, 1983. — 8, № 3.
Здесь описаны алгоритмы реализации операций сортировки, проекции,
соединения, обобщения и обновления в многопроцессорных средах. Представлены
также общие формулы стоимости, учитывающие операции ввода-вывода, загрузку
процессора и обмен сообщениями. Эти формулы можно адаптировать к различным
многопроцессорным архитектурам.
17.60.Hasan W., Motwani R. Optimization Algorithms for Exploiting the parallelism-
Communication Tradeoff in Pipelined Parallelism // Proc. 20th Intern. Conf, on Very
Large Data Bases. — Santiago, Chile, September, 1994.
17.61.Silberschatz A., Korth H.F., Sudarshan S. Database System Concepts (3rd edition).—
New York, N.Y.: McGraw-Hill, 1997.
Это общий учебник по управлению базами данных, который включает целую
главу о параллельных системах баз данных, а также главу о различных архитек-
турах систем баз данных (централизованных, клиент/серверных, параллельных и
распределенных).
690
Часть V. Дополнительные аспекты
Ответы к некоторым упражнениям
17.1. а— эквивалентны; б— эквивалентны; в— эквивалентны; г— не эквивалентны;
д — эквивалентны; е — не эквивалентны (эти выражения будут эквивалентными,
если заменить операцию AND операцией OR); ж — не эквивалентны; з — не эквива-
лентны; и — эквивалентны.
17.2. В демонстрационных целях покажем, что соединение является коммутативным.
Соединение A JOIN В отношений А{Х, Y} и B{Y, Z} — это отношение с заголов-
ком {X, Y, Z} и такими кортежами {Х:х, Y:y, Z:z}, что кортеж из значений х
(для X) и у (для Y) должен присутствовать в отношении А, а кортеж из значений у
(для Y) и z (для Z) должен присутствовать в отношении В. Это определение абсо-
лютно симметрично относительно А и В. Поэтому A JOIN В тождественно
В JOIN А. |
17.3. Для примера покажем ассоциативность операции объединения. Объединение
A UNION В двух отношений А и В совместимых типов — это отношение с тем же
заголовком, что А и В, и телом из всех кортежей t, принадлежащих отношению А, В
или им обоим одновременно. Таким образом, если С — еще одно совместимое по
типу отношение, то:
объединение ( A UNION В ) UNION С — это отношение с тем же заголовком и
телом, состоящим из всех кортежей t, которые принадлежат отношению
A UNION В, отношению С или им обоим одновременно;
объединение A UNION ( В UNION С ) — это отношение с тем же заголовком и
телом, состоящим из всех кортежей t, которые принадлежат отношению
В UNION С, отношению А или им обоим одновременно.
Эти два отношения имеют одинаковые заголовки, а тело в каждом случае состоит
из всех кортежей, принадлежащих хотя бы одному из отношений А, В или С. Поэто-
му приведенные отношения тождественны. |
17.4. Покажем, что объединение распределяется по пересечению.
Если t е A UNION ( В INTERSECT С ),TOt G А или t 6 В INTERSECT С.
• Если t е А, то t g A UNION В и t е A UNION С, и, следовательно, t G (А
UNION В ) INTERSECT ( A UNION С ).
• Если t е В INTERSECT С, то t G В и t g С. Тогда t е ( A UNION В ) и t е (А
UNION С ). Следовательно, t G ( A UNION В ) INTERSECT ( A UNION С ).
И обратно, если t G ( A UNION В ) INTERSECT ( A UNION С ),TOt G ( A UNION
В ) и t G (A UNION С ). Из этого следует, что t G А или t принадлежит обоим
отношениям, В и С. Следовательно, t G A UNION ( В INTERSECT С ). |
17.5. Покажем, что A UNION ( A INTERSECT В ) = А. Если t G А, то ясно, что t G A UNION
( A INTERSECT В ). И обратно, если t G A UNION ( A INTERSECT В ), то t е А или t
принадлежит обоим отношениям, А и В. В любом случае получим, что t е А. |
17.6. Два случая с условиями уже рассмотрены в разделе 17.4. А случаи без условий
достаточно просты. Покажем, что проекция не распределяется по разности на ос-
нове следующего обратного примера. Пусть отношения A{X,Y} и В{Х,Y} содержат
Глава 17. Оптимизация
691
по одному кортежу, а именно — кортежи {Х:х, Y: у} и {X: х, Y: z} соответственно
(y^z). Тогда (A MINUS В){X} дает отношение, содержащее только кортеж {Х:х},
тогда как А{Х} MINUS В{X} дает пустое отношение. |
17.9. Хороший набор подобных правил можно найти в [17.3].
17.10. Хороший набор подобных правил можно найти в [17.3].
17.11.
а) Выбрать сведения о поставщиках не из Лондона, не поставляющих деталь с но-
мером 'Р2';
б) выбрать сведения о поставщиках из Парижа;
в) выбрать сведения о поставщиках не из Лондона, причем таких, для которых не су-
ществует других поставщиков, поставляющих меньше различных типов деталей;
г) выбрать пустое множество сведений о поставщиках;
д) упрощение невозможно;
е) выбрать пустое множество сведений о парах поставщиков;
ж) выбрать пустое множество сведений о деталях;
з) выбрать сведения о таких поставщиках не из Парижа, которые поставляют наи-
большее количество различных видов деталей.
Заметьте, что результаты выполнения некоторых запросов (если быть точным, то
результаты запросов б, г, е и ж) можно получить непосредственно из ограничений
целостности.
17.15. Исходя из особенностей методов обработки, настоящие максимальное и минималь-
ное значения иногда являются в некотором роде фиктивными. Например, макси-
мальным значением атрибута “employee name” (имя сотрудника) будет строка из букв
Z (или букв Я), а ее минимальным значением — строка, составленная из пробелов.
Если исходить из этих значений, то оценка, например, среднего расстояния между
разными значениями атрибута в таблице может быть вычислена некорректно.
692
Часть V. Дополнительные аспекты
Глава
Отсутствующая информация
18.1. Введение
В повседневной жизни часто приходится сталкиваться с проблемой отсутствия некото-
рой информации. Весьма типичны ситуации, когда, например, “дата рождения неизвестна”,
“имя докладчика будет объявлено дополнительно”, “местонахождение объекта в данный
момент неизвестно” и т.д. Поэтому в системах баз данных должен существовать механизм
обработки подобных ситуаций. На практике наиболее типичный подход к решению этой
проблемы (используемый, в частности, в языке SQL и, следовательно, во многих коммер-
ческих продуктах) основан на применении неопределенных значений (NULL-значений) и
трехзначной логики. Например, вес детали, скажем, с номером 'Р7', может быть неизвес-
тен, поэтому упрощенно можно сказать, что ее вес “является неопределенным”. В более
точном смысле это выражение означает следующее: а) известно, что деталь существует; б)
несомненно, деталь имеет вес; в) чему равен вес, нам неизвестно.
Давайте рассмотрим этот пример более внимательно. Ясно, что мы не можем поместить
истинное значение веса детали в атрибут WEIGHT кортежа, описывающего деталь с номером
'Р7'. Следовательно, все, что остается, — пометить или как-то обозначить, что значение
атрибута WEIGHT этого кортежа является неопределенным. В дальнейшем наличие подоб-
ной метки будет интерпретироваться как указание, что истинное значение атрибута неиз-
вестно. Для удобства можно неформально сказать, что атрибут WEIGHT “содержит неопре-
деленное значение” или что значение этого атрибута “равно NULL”. На практике подобные
выражения действительно широко используются. Однако следует четко понимать, что по-
добные выражения неформальны и несколько неточны, поскольку, говоря, что значение
атрибута WEIGHT в кортеже является неопределенным или равно NULL, мы на самом деле
имеем в виду, что кортеж вообще не содержит никакого значения атрибута WEIGHT. По-
этому широко распространенные выражения “неопределенное значение” и “значение NULL”
использовать не рекомендуется, так как это “неопределенное значение (NULL)” на самом де-
ле не значение, а всего лишь некая отметка или обозначение.
В следующем разделе будет показано, что при вычислении любого скалярного срав-
нения, в котором какой-либо из операндов не определен (содержит NULL), вместо значе-
ния true (истина) или false (ложь) будет получено логическое значение unknown
(неизвестно). Причиной такого состояния дел является принятая нами интерпретация
обозначения NULL как указателя “значение неизвестно”. Если значение переменной А не-
известно, то неизвестен и результат любого ее сравнения, например вида А > В, причем
независимо от значения В (даже если предположить, что значение переменной В также
неизвестно). В частности, следует отметить, что два неопределенных значения (NULL)
нельзя считать равными одно другому, поэтому, если обе переменные, А и В, содержат
неопределенные значения (NULL), результатом сравнения А = В всегда будет значение
Глава 18. Отсутствующая информация
693
unknown, а не true. Однако эти переменные не считаются и неравными, т.е. результатом
сравнения А В также будет значение unknown. Концепция неопределенных значений,
по крайней мере в общепринятом смысле, неизбежно приводит нас к необходимости ис-
пользования логики с тремя логическими значениями: true (истина), false (ложь) и
unknown (неизвестно).
Прежде чем продолжить обсуждение, автор данной книги считает необходимым еще
раз заявить, что он полностью разделяет мнение многих авторов о том, что неопределенные
значения (NULL) и трехзначная логика являются ошибочными понятиями и им нет места в
четких формальных системах, подобных реляционной модели1. Однако, оставляя все на
своих местах, ему не хотелось бы лишать читателя возможности обсудить неопределенные
значения и трехзначную логику, поэтому в настоящее издание и включена данная глава.
План главы таков. Непосредственно после введения в разделе 18.2 без излишнего не-
доверия и критики описываются основные идеи, на которых базируется концепция неоп-
ределенных значений и трехзначной логики. (Суть в том, что невозможно строго и спра-
ведливо критиковать любые идеи без их предварительного описания.) Затем в разде-
ле 18.3 обсуждаются некоторые более важные следствия изложенных идей и предприни-
мается попытка обосновать мнение автора о том, что понятие неопределенных значений
является ошибочным. В разделе 18.4 рассматриваются следствия наличия неопределен-
ных значений в первичных и внешних ключах. Далее, в разделе 18.5, будет сделано от-
ступление от основной темы с целью описания чаще всего встречающихся операций в
контексте неопределенных значений и трехзначной логики — операций внешнего соеди-
нения. В разделе 18.6 в очень сжатой форме описывается альтернативный способ обра-
ботки отсутствующей информации с использованием специальных значений. В разде-
ле 18.7 кратко рассматриваются аспекты языка SQL, имеющие отношение к обсуждае-
мой проблеме. И наконец в разделе 18.8 приводится краткое резюме.
Еще одно предварительное замечание. Существует множество причин, не позволяю-
щих поместить истинное значение в тот или иной атрибут кортежа, и неизвестность это-
го значения — только одна из возможных причин. Среди других причин следует назвать
такие, как “значение неприменимо”, “значения не существует” и т.д. [18.5]2. Действи-
тельно, в [5.2] Кодд предложил использовать в реляционной модели не одно, а два вида
I Например, утверждение о том, что кортеж с описанием некоторой детали не содержит
значения атрибута WEIGHT, эквивалентно — по определению! — утверждению, что данный кор-
теж вообще не является кортежем описания детали. Иначе говоря, можно утверждать, что
этот кортеж не является реализацией соответствующего предиката. Суть заключается в том,
что самой по себе попытки точно сформулировать назначение схемы с использованием неопре-
деленных значений вполне достаточно, чтобы показать, почему эта идея не является логически
последовательной. Одно из следствий этого факта состоит в том, что данную схему очень
трудно последовательно объяснить. “Имеет смысл лишь украдкой взглянуть на эту проблему и
особо не ломать над ней голову” [18.19].
~ Однако следует особо отметить, что в любом из перечисленных выше случаев как таковой
“отсутствующей информации” нет. Например, если для сотрудника 'Joe' значение комиссионно-
го вознаграждения “неприменимо”, значит, для него неприменима сама концепция выплаты комис-
сионных и, таким образом, здесь нет никакой отсутствующей информации. (Тем не менее, если
кортеж с описанием сотрудника 'Joe' содержит “неприменимое неопределенное значение” в ат-
рибуте комиссионного вознаграждения, этот кортеж вообще не является кортежем с описанием
сотрудника, поскольку он не является корректной реализацией предиката “Описание сотрудника”.)
694
Часть V. Дополнительные аспекты
неопределенных значений: одно из них — “значение неизвестно”, а второе — “значение
неприменимо”. В результате в предложенной Коддом реляционной модели используется
уже не трех-, а четырехзначная логика. Автор данной книги возражает против подобных
предложений в этой и во всех других своих работах (например, в [18.5]). В данной главе
мы сосредоточимся только на одном виде неопределенных значений, а именно— на
“значение неизвестно”. На него мы достаточно часто, но не всегда, будем ссылаться с
помощью аббревиатуры UNK (от “unknown” — “неизвестно”).
18.2. Обзор концепции трехзначной логики
В этом разделе описываются принципиальные компоненты концепции трехзначной логи-
ки применительно к проблеме отсутствующей информации. Начнем обсуждение с рассмотре-
ния влияния неопределенных значений (т.е. UNK) на вычисление логических выражений.
Логические выражения
Выше уже отмечалось, что результатом скалярных операций сравнения, в которых
хотя бы один из операндов является величиной UNK, будет логическое значение unknown
вместо значения true или false. Поэтому в таких случаях приходится иметь дело с трех-
значной логикой. Третьим логическим значением здесь является значение unknown, на
которое мы достаточно часто, но не постоянно, будем ссылаться с помощью сокращения
ипк. Ниже приведены таблицы истинности для операторов AND, OR и NOT в трехзначной
логике (в таблицах используются следующие сокращения: t — true, f— false, и — ипк).
AND t u f ’OR t u f NOT
t t u f t t t t t f
u u u f u t u u u u
f f f f f t u f f t
Предположим, что А = 3, В = 4 и переменная С имеет значение UNK. Тогда приведен-
ные ниже выражения будут иметь следующие результаты (приведены справа).
А > В AND В > С : false
А > В OR В > С : ипк
А < В OR В < С : true
NOT ( А = С ) : ипк
Тем не менее для реализации трехзначной логики одних только операторов AND, OR и
NOT недостаточно [18.11]. Еще одним важным оператором является оператор MAYBE
(возможно) [18.5]. Таблица истинности данного оператора показана ниже.
MAYBE
t f
u t
f f
Чтобы продемонстрировать необходимость в операторе MAYBE, рассмотрим запрос
“Получить сведения о сотрудниках с годовой зарплатой менее $50 000, которые могут быть
(но это точно неизвестно) программистами и родились до 18 января 1971 года”. С помощью
оператора MAYBE данный запрос можно достаточно кратко записать в следующем виде.
Глава 18. Отсутствующая информация
695
EMP WHERE MAYBE ( JOB = 'Programmer' AND
DOB < DATE ('1971-1-18') AND
SALARY < 50000.00 )
(Здесь предполагается, что атрибуты JOB, DOB и SALARY переменной-отношения EMP
имеют типы CHAR, DATE и RATIONAL соответственно.) Без оператора MAYBE этот же запрос
будет выглядеть следующим образом.
ЕМР WHERE ( ISJJNK ( JOB ) AND
DOB < DATE ('1971-1-18') AND
SALARY < 50000.00 )
OR ( JOB = 'Programmer' AND
ISJJNK ( DOB ) AND
SALARY < 50000.00 )
OR ( JOB = 'Programmer' AND
DOB < DATE ('1971-1-18') AND
ISJJNK ( SALARY ) )
OR ( ISJJNK ( JOB ) AND
ISJJNK ( DOB ) AND
SALARY < 50000.00 )
OR ( ISJJNK ( JOB ) AND
DOB < DATE ('1971-1-18') AND
ISJJNK ( SALARY ) )
OR ( JOB = 'Programmer' AND
ISJJNK ( DOB ) AND
ISJJNK ( SALARY ) )
OR ( ISJJNK ( JOB ) AND
ISJJNK ( DOB ) AND
ISJJNK ( SALARY ) )
(Здесь предполагается существование другого истинностного оператора ISJJNK,
который принимает в качестве параметра единственное скалярное выражение и воз-
вращает значение true, если этот операнд равен UNK, или значение false — в против-
ном случае.)
Не следует воспринимать изложенное выше как подтверждение того, что оператор
MAYBE является единственным дополнительным логическим оператором, который необ-
ходим в трехзначной логике. На практике, например, весьма полезным может оказаться
оператор TRUE_OR_MAYBE. (См. [18.5], а также [18.11].)
Кванторы EXISTS и FORALL
Вопреки тому несомненному факту, что для представления большинства примеров
в этой книге используется реляционная алгебра, а не исчисление, нам все же следует
рассмотреть влияние трехзначной логики на вычисление кванторов реляционного ис-
числения EXISTS и FORALL. Как говорилось в главе 7, кванторы EXISTS и FORALL опре-
деляются как циклические операции OR и AND соответственно. Иначе говоря, если г —
отношение с кортежами tl, t2, ..., tm, V— переменная диапазона, которая прини-
696
Часть V. Дополнительные аспекты
мает значения из данного отношения, a p(V) — логическое выражение, в котором ис-
пользуется переменная V, то выражение EXISTS V ( р ( V ) ) по определению экви-
валентно следующему выражению.
false OR р ( tl ) OR ... OR р ( tm )
Аналогично выражение FORALL V ( р ( V ) ) по определению эквивалентно такому
выражению.
true AND р ( tl ) AND ... AND p ( tm )
Что произойдет, если значение р( ti) для некоторого i будет равно ипк? Например,
пусть отношение г содержит следующие кортежи.
( 1, 2, 3 )
( 1, 2, UNK )
( UNK, UNK, UNK )
Предположим для простоты, что тремя атрибутами в указанном выше порядке слева
направо являются атрибуты А, В и С соответственно и каждый из них имеет тип INTEGER.
Ниже приведены примеры различных выражений и результаты их вычисления.
EXISTS V ( ; V.C > 1 ) : true
EXISTS V ( ; v.b > 2 ) : unk
EXISTS V | ; MAYBE ( V.A > 3 ) ) : true
EXISTS V | ; isjjnk ( v.c ) ) : true
FORALL V | ; v.a > 1 ) : false
FORALL V I [ V.B > 1 ) : unk
FORALL V I [ MAYBE ( V.C > 1 H : false
Вычисляемые скалярные выражения
Рассмотрим следующее числовое выражение.
WEIGHT * 454
Здесь атрибут WEIGHT представляет вес некоторой детали, например детали с номером
'Р7'. Что будет, если вес детали с номером 'Р7' является величиной UNK? Каким будет зна-
чение всего этого выражения? Ответ состоит в том, что значением всего выражения также
должна быть величина UNK. В общем случае, если хотя бы один из операндов скалярного
выражения является величиной UNK, результатом вычисления всего выражения также будет
величина UNK. Таким образом, например, если атрибут WEIGHT содержит величину UNK, ре-
зультатом вычисления всех приведенных ниже выражений также будет величина UNK.
WEIGHT + 454 454 + WEIGHT + WEIGHT
WEIGHT - 454 454 - WEIGHT - WEIGHT
WEIGHT * 454 454 * WEIGHT
WEIGHT / 454 454 / WEIGHT
Замечание. Вероятно, следует сразу же отметить, что подобная трактовка числовых
выражений может привести к появлению некоторых аномалий. Например, выражение
WEIGHT - WEIGHT, значением которого должен быть нуль, на самом деле будет иметь
697
Глава 18. Отсутствующая информация
значение UNK, а результатом вычисления выражения WEIGHT/0 будет также величина UNK
вместо обычного в данном случае сообщения об ошибке деления на нуль (конечно, в
обоих выражениях предполагается, что атрибут WEIGHT содержит величину UNK). Такие
аномалии будут игнорироваться до особого упоминания.
Аналогичные рассуждения применимы ко всем другим скалярным типам и операто-
рам, за исключением операторов сравнения, рассмотренного выше оператора IS_UNK и
рассматриваемого ниже оператора IF_UNK (см. два предыдущих подраздела). Таким об-
разом, для символьных строк выражение А | | В возвращает UNK, если А равен UNK либо В
равен UNK, либо оба равны UNK. (Снова следует отметить существование аномальных слу-
чаев, рассмотрение которых мы здесь опустим.)
Оператор IF_UNK получает на входе два операнда и возвращает значение первого
операнда, если это не величина UNK. Если первый операнд является величиной UNK, то
оператор IF_UNK возвращает значение второго операнда. Другими словами, это оператор
преобразования величины UNK в некоторое значение, не равное UNK. Например, предпо-
ложим, что значение UNK разрешено использовать для помещения в атрибут CITY пере-
менной-отношения S. Рассмотрим следующее выражение.
EXTEND S ADD IFJJNK ( CITY, 'City unknown') AS SCITY
В результате его вычисления будет получена переменная-отношение, в которой зна-
чение атрибута SCITY равно 'City unknown' для каждого поставщика, город которого в
переменной-отношении S определен как UNK.
Следует заметить, что оператор IF_UNK можно определить с помощью оператора
IS_UNK. Точнее говоря, выражение IF_UNK ( <выражение1>, <выражение2> ), где пара-
метры <выражениеТ> и <выражение2> должны иметь одинаковые типы, эквивалентно
следующему выражению.
IF IS_UNK (<выражение1>) THEN <выражение2> ELSE <выражение1> END IF
UNK - это не ипк
Очень важно понимать, что величина UNK (неопределенное значение вида “значение
неизвестно”) и значение ипк (логическое значение unknown) — это не одно и то же3.
Действительно, данное положение дел является прямым следствием того, что ипк — это
значение (точнее, логическое значение), в то время как величина UNK вообще не является
значением. Но давайте более точно сформулируем сказанное выше. Предположим, что X
является переменной логического типа (BOOLEAN). Тогда она может принимать одно из
следующих значений: true, false или ипк. Таким образом, выражение “X равно ипк” озна-
чает в точности то, что значение переменной X известно и равно ипк. В отличие от этого
выражение “X равно UNK” означает, что значение переменной X неизвестно.
Могут ли домены содержать величину UNK
Из того факта, что UNK не является значением, прямо следует заключение, что домены
(т.е. множества значений) не могут содержать величину UNK. Действительно, если бы до-
мены могли содержать неопределенные значения какого-либо вида, проверка ограниче-
3 Тем не менее в стандарте SQL3 они рассматриваются как эквивалентные понятия (см.
приложение Б).
698
Часть V. Дополнительные аспекты
ний целостности для них всегда завершалась бы с положительным результатом! Однако,
поскольку домены в действительности не могут содержать величину UNK, “отношения”,
допускающие присутствие величины UNK, являются чем угодно, но только не реляцион-
ными отношениями. Причем это верно как для отношений, определение которых дано
в главе 5, так и для отношений, отвечающих оригинальному определению Кодда [5.1]. К
обсуждению этого важного вопроса мы еще вернемся в разделе 8.6.
Реляционные выражения
Рассмотрим влияние величины UNK на операторы реляционной алгебры. Для просто-
ты ограничимся пятью примитивными операторами: выборки, проекции, произведения,
объединения и вычитания (воздействие величины UNK на другие операторы можно опре-
делить на основе заключений о ее воздействии на пять перечисленных операторов).
Прежде всего заметим, что на операцию произведения величина UNK никакого влия-
ния не оказывает.
Затем операцию выборки следует несколько переформулировать, потребовав, чтобы
возвращались только кортежи, для которых условие выборки имеет значение true, т.е.
эта операция не должна включать в результат кортежи, для которых условие выборки
принимает значение false или ипк.
Замечание. Использование именно этой формулировки неявно предполагалось в при-
мере с оператором MAYBE, приведенном выше, в разделе о логических выражениях.
Теперь рассмотрим оператор проекции. Проецирование отношения подразумевает,
кроме всего прочего, исключение кортежей-дубликатов. В двухзначной логике два кор-
тежа считаются дубликатами тогда и только тогда, когда все соответствующие компо-
ненты обоих кортежей равны. Однако в трехзначной логике некоторые компоненты кор-
тежей могут содержать величину UNK, а величина UNK не равна никакой другой величине,
даже самой себе. Следует ли из этого заключить, что кортеж, который содержит величи-
ну UNK, не может быть дубликатом другого кортежа и даже самого себя?
Согласно Кодду [13.6] ответ на этот вопрос отрицательный', две величины UNK, даже
если они не равны между собой, считаются дубликатами одна другой в целях исключе-
ния кортежей-дубликатов4. Очевидное противоречие объясняется следующим образом.
“...проверка в процессе исключения кортежей-дубликатов... выполняется на более
низком уровне детализации по сравнению с тестированием на наличие равенства в
операциях выборки. Поэтому здесь можно применять различные правила. ”
Автор предоставляет читателю право решать, является ли такое обоснование прием-
лемым. В любом случае давайте согласимся сейчас с этим обоснованием, а заодно при-
мем следующее определение.
Кортежи tl и t2 являются дубликатами один другого тогда и только тогда, когда они
имеют одинаковые атрибуты и каждые два значения соответствующих атрибутов в
обоих кортежах либо имеют одинаковые значения, либо оба содержат величину UNK.
4 Работа [ 13.6] была первой работой Кодда, в которой рассматривалась проблема отсут-
ствия информации, хотя описание этой проблемы не являлось основной задачей статьи (см. гла-
ву 13). Помимо всего прочего, в статье предлагаются версии “возможного” ©-соединения, 0-
выборки, операторы деления (см. упр. 18.4), а также “внешние” версии соединения, пересечения,
вычитания, 0-соединения и естественного соединения (см. раздел 18.5).
Глава 18. Отсутствующая информация
699
Теперь, исходя из этого расширенного определения кортежей-дубликатов, можно со-
хранить прежнее определение операции проекции в неизменном виде.
Объединение также подразумевает исключение избыточных кортежей-дубликатов, и
для этой операции также может быть применено приведенное выше определение. Таким
образом, объединение отношений rl и г2 одного и того же типа можно определить как
отношение г того же типа, включающее все возможные кортежи t, такие, что кортеж t
является дубликатом некоторого кортежа в отношении rl или в отношении г2 (или в них
обоих одновременно).
И наконец, операция вычитания определяется аналогично (хотя она и не требует ис-
ключения кортежей-дубликатов). Иначе говоря, кортеж t попадает в результат операции
rl MINUS г2 тогда и только тогда, когда этот кортеж является дубликатом какого-либо
кортежа в отношении г 1, но не является дубликатом ни одного из кортежей в отношении
г2. (Для полноты картины отметим, что операция пересечения определяется аналогич-
но: кортеж t попадает в результат операции rl INTERSECT г2 тогда и только тогда, когда
этот кортеж является дубликатом какого-либо кортежа в отношении rl и одновременно
дубликатом какого-либо кортежа в отношении г2.)
Операции обновления
Здесь следует упомянуть два основных момента.
1. Если атрибут А отношения R может содержать величину UNK и если вставляемый в от-
ношение R кортеж не содержит значения для атрибута А, то система автоматически по-
местит величину UNK на место опущенного значения. Если атрибут А в отношении R не
допускает присутствия величины UNK, то попытка создать кортеж (с помощью операции
INSERT или UPDATE), в котором в атрибут А помещено значение UNK, приведет к ошибке.
2. Попытка создать в отношении R кортеж-дубликат (с помощью операции INSERT или
UPDATE) обычно является ошибкой. В данном случае определение кортежей-
дубликатов взято из предыдущего подраздела.
Ограничения целостности
Как указывалось в главе 8, ограничение целостности задается в виде логического вы-
ражения, результат вычисления которого не должен быть равен значению false. Следова-
тельно, ограничение целостности не будет нарушено, если результат его вычисления бу-
дет равен значению ипк (на самом деле это неявно предполагалось в наших замечаниях,
приведенных выше в настоящем разделе в отношении ограничений типов). Конечно, в
этом случае точнее было бы сказать, что нам ничего неизвестно о том, будет ли наруше-
но данное ограничение целостности. Но с известной долей приближения вполне можно
утверждать, что если в предложении WHERE значение ипк рассматривается как false, то в
ограничениях целостности оно рассматривается как true.
18.3. Некоторые следствия изложенной схемы
Использование подхода с трехзначной логикой, описанной в предыдущем разделе,
имеет ряд логических следствий, причем некоторые из них совсем не очевидны. В дан-
ном разделе обсуждаются эти следствия и их значения.
700
Часть V. Дополнительные аспекты
Преобразование выражений
Прежде всего отметим, что выражения, которые в двухзначной логике всегда воз-
вращают значение true, в трехзначной логике необязательно всегда будут давать тот же
результат. Ниже приведено несколько примеров с комментариями, но следует иметь в
виду, что этот список далеко не полон.
Сравнение х = х не обязательно в результате даст true.
В двухзначной логике любая переменная х всегда равна самой себе. В трехзнач-
ной логике переменная х не равна самой себе, если она содержит величину UNK.
Логическое выражение р OR NOT(p) не обязательно в результате даст true.
Здесь р — это некоторое логическое выражение. В двухзначной логике выражение
р OR NOT(p) всегда имеет значение true (т.е. истинно), независимо от значения р.
Однако в трехзначной логике, если р равно ипк, общее выражение сводится к
ипк OR NOT(imJt), т.е. к выражению ипк OR ипк, что, в свою очередь, упрощается
до значения ипк, а не true.
Этот частный пример демонстрирует одно интересное свойство трехзначной ло-
гики, которое можно описать так. Если выполнить два запроса, “Получить сведе-
ния обо всех поставщиках из Лондона” и “Получить сведения обо всех поставщи-
ках не из Лондона”, а затем объединить результаты обоих запросов, то не обяза-
тельно будут получены сведения обо всех поставщиках. Чтобы получить список
всех поставщиков, к двум запросам нужно добавить еще один: “Получить сведе-
ния обо всех поставщиках, которые, возможно (may be), находятся в Лондоне”5.
Суть данного примера, безусловно, состоит в том, что в реальном мире состояния
“находится в Лондоне” и “находится не в Лондоне” являются взаимоисключаю-
щими и покрывают весь спектр возможностей. Однако в базе данных содержится
не сам реальный мир, а лишь знания о реальном мире, и эти знания характеризу-
ются тремя, а не двумя возможными состояниями. В рассматриваемом здесь при-
мере это следующие состояния: “место нахождения известно, и это Лондон”,
“место нахождения известно, и это не Лондон”, “место нахождения неизвестно”.
Более того, как показано в [18.6], очевидно, что систему базы данных нельзя оп-
рашивать о состоянии реального мира, ей можно задавать вопросы только о тех
знаниях о реальном мире, которые представлены в базе данных в виде значений.
Такое “противоестественное” свойство, приведенное в примере, порождено тем,
что пользователь мыслит в терминах реального мира, а система функционирует,
опираясь исключительно на свои знания об этом реальном мире.
Замечание. Тем не менее автор данной книги подозревает, что описанное несоот-
ветствие между предметными областями— это всего лишь ловушка, в которую
очень легко попасть. Заметьте, что каждый отдельный запрос, описанный в пре-
дыдущих главах (в примерах, упражнениях и т.п.), был сформулирован в терминах
“реального мира”, а не в терминах “знаний о реальном мире”. И в этом смысле
данная книга вовсе не является каким-то исключением.
5 Как следует из этих рассуждений, выражением, которое в трехзначной логике всегда бу-
дет давать в результате true (т.е. будет аналогом выражения р OR NOT(p) в двухзначной логи-
ке), является р OR NOT(p) OR MAYBE(р).
Глава 18. Отсутствующая информация
701
Вычисление логического выражения г JOIN г не обязательно в результате даст г.
В двухзначной логике естественное соединение отношения г с самим собой всегда
дает в результате исходное отношение г (т.е. операция естественного соединения
является идемпотентной). Однако в трехзначной логике кортеж, содержащий ве-
личину UNK в любой из позиций, не будет соединен сам с собой, поскольку опера-
ция соединения, в отличие от операции объединения, предусматривает проверку
наличия равенства, а не исключение дублирующихся кортежей.
Операция INTERSECT больше не является частным случаем операции JOIN.
Это заключение является следствием того факта, что, опять же, операция соеди-
нения предусматривает проверку наличия равенства, тогда как операция пересе-
чения, подобно операции объединения, предусматривает отбор кортежей-
дубликатов.
Из равенства А = В AND В = С вовсе не обязательно следует равенство А = С.
Развернутая иллюстрация этого следствия приведена в следующем разделе.
Таким образом, эквивалентности, корректные в двухзначной логике, не являются
эквивалентностями в трехзначной логике. Одно из наиболее серьезных следствий по-
добных несоответствий таково. Как правило, в основе различных законов преобразо-
вания, которые используются для преобразования запросов в более эффективную
форму, лежит простая эквивалентность вида г JOIN г = г (см. главу 17). Более того,
эти законы используются не только системой (в процессе оптимизации), но и пользо-
вателями (когда они пытаются отыскать “наилучший” способ записи конкретного за-
проса). Если же исходная эквивалентность таковой не является, то построенные на ней
законы преобразования, очевидно, являются некорректными. А если законы преобра-
зования некорректны, то и выполняемые на их основе преобразования некорректны. В
свою очередь, некорректные преобразования запросов приводят к неправильным от-
ветам со стороны системы.
Пример с базой данных отделов и сотрудников
Для иллюстрации проблемы некорректных преобразований мы подробно обсудим
специальный пример, взятый из [18.9] (по некоторым важным для данного случая
причинам он построен на использовании реляционного исчисления, а не реляционной
алгебры). Предположим, что имеется простая база данных отделов и сотрудников, по-
казанная на рис. 18.1.
DEPT DEPT# ЕМР EMP# DEPT#
D2 El UNK
Рис. 18.1. База данных отделов и сотрудников
Рассмотрим следующее условие, которое может являться частью некоторого запроса.
DEPT.DEPT# = ЕМР.DEPT# AND ЕМР.DEPT# = DEPT# ( 'DI' )
702
Часть И Дополнительные аспекты
Здесь DEPT и ЕМР являются переменными диапазона. Для всех кортежей в базе данных
приведенное условие сводится к выражению ипк AND ипк, т.е. просто к значению ипк.
Тем не менее “хороший” оптимизатор, исходя из того, что если А = В и В = С, то
А = С, добавит к исходному условию дополнительную выборку А = С (как описано в
главе 17.4). В результате получится следующее выражение.
DEPT.DEPT# = ЕМР.DEPT# AND ЕМР.DEPT# = DEPT# ( 'Dl' )
AND DEPT.DEPT# = DEPT# ( 'Dl' )
Это измененное выражение теперь сведется к выражению ипк AND ипк AND false или
просто к значению false (для двух рассматриваемых кортежей в базе данных). В этом
свете рассмотрим следующее выражение.
EMP.EMP# WHERE EXISTS DEPT ( NOT
( DEPT.DEPT# = EMP.DEPT# AND EMP.DEPT# = DEPT# ( 'Dl' ) ) )
В результате его вычисления будет возвращен код сотрудника 'Е1', если это выраже-
ние "оптимизировать ” в изложенном смысле, и не будет возвращено ничего, если его не
"оптимизировать ”. Безусловно, это означает, что проведенная “оптимизация” некоррект-
на. Таким образом, показано, что приемы оптимизации, которые были корректны (и удоб-
ны) в обычной двухзначной логике, являются некорректными в трехзначной логике.
Попробуем оценить влияние сказанного выше на способы расширения систем с двух-
значной логикой в отношении поддержки трехзначной логики. В лучшем случае подоб-
ное расширение потребует некоторой переработки существующей системы, так как от-
дельные фрагменты кода оптимизатора будут работать некорректно, причем в худшем
случае оптимизатор будет вносить явные ошибки в результаты запросов. Более общий
подход предполагает анализ последствий расширения систем, поддерживающих п-
значную логику, до систем поддержки (п+1)-значной логики для любых n > 1.
Проблема интерпретации
Теперь исследуем приведенный выше пример базы данных отделов и сотрудников бо-
лее тщательно. Так как сотрудник с номером ' Е1' в действительности приписан к конкрет-
ному отделу, величина UNK представляет некоторое реальное значение d. В данном случае
значение d либо равно 'D1', либо нет. Проанализируем значение следующего выражения.
DEPT.DEPT# = ЕМР.DEPT# AND ЕМР.DEPT# = DEPT# ( 'Dl' )
Если d равно 'Dl', то для приведенного выше примера данных все выражение имеет
значение false, поскольку именно это значение дает вычисление первого терма выраже-
ния. Если d не равно ' D1', то все выражение также будет иметь значение false, так как
именно это значение будет получено при вычислении второго терма выражения —
ЕМР.DEPT# = DEPT# ( 'Dl' ). Иначе говоря, в реальном мире исходное выражение все-
гда имеет значение false, независимо от того, какое реальное значение представлено ве-
личиной UNK. Отсюда следует вывод, что результат, корректный в контексте реального
мира, и результат, корректный в трехзначной логике, — это не одно и то же! Иначе гово-
ря, трехзначная логика отражает поведение реального мира некорректно, т.е. можно счи-
тать, что трехзначная логика не является адекватным инструментом для интерпретации
поведения реального мира!
Глава 18. Отсутствующая информация
703
Замечание. Эта проблема интерпретации является далеко не единственной проблемой,
возникающей в связи с использованием неопределенных значений и трехзначной логики
(подробное обсуждение аналогичных вопросов можно найти в [18.1]—[18.11]). Она даже не яв-
ляется наиболее фундаментальной (см. следующий подраздел). Но, по мнению автора, именно
эта проблема имеет наибольшее практическое значение и вызывает наибольший интерес.
Еще раз о предикатах
Предположим, что отношение, являющееся текущим значением переменной-отношения
ЕМР, содержит только два кортежа: ('Е2','D2') и ('El' ,UNK). Первое соответствует утвер-
ждению “В отделе с номером 'D2' есть сотрудник с номером ' Е2' а второе — “Существует
сотрудник с номером ' Е1(Напомним, утверждение “Кортеж включает величину UNK” озна-
чает, что на самом деле этот кортеж вообще не содержит никакого значения в данной позиции
кортежа. Таким образом, кортеж ('El' ,UNK), если такое сомнительное обозначение вообще
можно назвать кортежем, на самом деле следует рассматривать как кортеж ('Е1').) Иначе го-
воря, эти два кортежа являются реализациями двух разных предикатов, а все “отношение” во-
все не является отношением; это всего лишь некоторое объединение двух разных отношений
с двумя разными заголовками (в данном частном случае).
Теперь можно предположить, что сложившуюся ситуацию можно было бы исправить,
утверждая, что на самом деле существует всего один предикат, содержащий оператор OR.
Существует сотрудник с номером Е#, работающий в отделе с номером D# OR
существует сотрудник с номером Е#.
Обратите внимание, что теперь (следуя допущению о замкнутости мира) отношение
должно содержать “кортеж” вида (Ei,UNK) для всех сотрудников Ei! Страшно даже по-
думать о результатах обобщения подобной попытки исправления дел на тот случай, ко-
гда “отношение” “содержит величину UNK” в нескольких разных “атрибутах”. (В любом
случае полученное подобным образом “отношение” вовсе не будет являться отношени-
ем, что будет показано в следующем абзаце.)
Перефразируем сказанное выше. Если значение данного атрибута в данном кортеже
данного отношения “представлено величиной UNK”, то (повторим это еще раз) в позиции
атрибута на самом деле вообще ничего не содержится. А это означает, что данный
“атрибут” не является атрибутом, данный “кортеж” не является кортежем, а данное
“отношение” не является отношением и все последующие действия с этими объектами
(какими бы они ни были) уже не могут быть обоснованы с помощью математической ре-
ляционной теории. Иначе говоря, использование величины UNK и трехзначной логики
противоречит основам реляционной модели.
18.4. Отсутствующие значения и ключи
Замечание. Далее вместо термина UNKmhi будем (в основном, по историческим при-
чинам) использовать более традиционную терминологию, т.е. термин NULL.
Вопреки всему сказанному в предыдущем разделе на практике неопределенные зна-
чения (NULL) и трехзначная логика широко поддерживаются в большинстве современных
программных продуктов. Резонно предположить, что такая поддержка имеет очень важ-
ные последствия, особенно в отношении ключей. Именно это и будет предметом нашего
краткого рассмотрения.
704
Часть V. Дополнительные аспекты
Первичные ключи
Как уже отмечалось в разделе 8.8, исторически сложилось так, что в реляционной
модели, по крайней мере в базовых переменных-отношениях, один (и только один) по-
тенциальный ключ должен быть выбран в качестве первичного ключа переменной-
отношения. Все остальные потенциальные ключи (если таковые имеются) считаются
альтернативными. Помимо концепции первичного ключа, в эту модель по некоторым
историческим причинам входит следующее “метаограничение” или правило сохранения
целостности сущности.
Правило сохранения целостности сущности. Ни один компонент первичного
ключа любой базовой переменной-отношения не может содержать неопределен-
ные значения (NULL).
Обоснование этого ограничения построено на приведенной ниже последовательности
умозаключений.
1. Кортежи базовых переменных-отношений представляют сущности реального мира.
2. Сущности реального мира всегда должны допускать возможность их идентифика-
ции (по определению).
3. Следовательно, их аналоги в базе данных также должны допускать возможность
идентификации.
4. В базе данных значения первичного ключа используются в качестве идентификаторов.
5. Следовательно, значение любого первичного ключа не может быть “неопреде-
ленным”.
В связи с этим приведем ряд соображений.
1. Прежде всего, часто ошибочно считается, что скрытый между строк смысл ограни-
чения целостности сущности заключается в том, что “значения первичного ключа
должны быть уникальными”. (Действительно, значения первичного ключа должны
быть уникальными, но это следует из самого определения первичного ключа.)
2. Далее заметим, что это правило применимо только для первичных ключей, а аль-
тернативные ключи могут содержать неопределенные значения (NULL). Но если
некий ключ АК является альтернативным ключом, в котором допускаются неопре-
деленные значения (NULL), то он не может использоваться в качестве первичного
ключа, поскольку для него нарушается требование сохранения целостности сущно-
сти. Тогда в каком смысле ключ АК является потенциальным? И наоборот, если вы-
двинуть требование, что альтернативные ключи не могут содержать неопределен-
ные значения (NULL), то правило сохранения целостности сущности будет отно-
ситься ко всем потенциальным ключам, а не только к первичным ключам. В любом
из этих двух вариантов указанное правило выглядит не вполне корректно.
3. Наконец, заметим, что правило сохранения целостности сущности применимо
только для базовых переменных-отношений, тогда как другие переменные-
отношения могут содержать первичные ключи с неопределенными значениями
(NULL). В качестве тривиального и очевидного примера рассмотрим проекцию пе-
ременной-отношения R по атрибуту А, в котором допускается присутствие неопре-
Глава 18. Отсутствующая информация
705
деленных значений (NULL). Очевидно, что правило сохранения целостности сущно-
сти нарушает принцип взаимозаменяемости (для базовых и производных перемен-
ных-отношений). По нашему мнению, это может послужить серьезным аргументом
для отказа от него (данная концепция будет отвергнута нами независимо от вклю-
чения неопределенных значений (NULL)).
Замечание. Допустим, что мы отказались от идеи применять неопределенные значе-
ния (NULL) и для представления недостающей информации вместо них использовали спе-
циальные значения аналогично тому, как это делается в реальном мире (подробности
приводятся в разделе 18.6). Тогда модифицированная версия правила сохранения цело-
стности сущности будет иметь следующий вид: “Никакой компонент первичного ключа
любой базовой переменной-отношения не может содержать подобных специальных зна-
чений”. Это требование может использоваться как рекомендация, но не является непре-
ложным законом (так же, как идеи дальнейшей нормализации служат в качестве реко-
мендаций, а не строгих законов). На рис. 18.2 приведен пример (взятый из [5.7]) базовой
переменной-отношения SURVEY, для которой может потребоваться нарушить эту реко-
мендацию. В ней представлены результаты опроса сотрудников о размере их зарплаты,
которые включают среднее, максимальное и минимальное значения для группы сотруд-
ников с определенным годом рождения. (Здесь атрибут BIRTHYEAR является первичным
ключом.) Кортеж со специальным значением ???? атрибута BIRTHYEAR представляет тех
служащих, которые постеснялись ответить на вопрос о годе рождения.
SURVEY BIRTHYEAR AVGSAL MAXSAL MINSAL
1960 85К 130K 33K
1961 82К 125K 32K
1962 77К 99K 32K
1963 78К 97K 35K
1970 29К 35K 12K
???? 56К 117K 20K
Рис. 18.2. Пример значений данных в переменной-отношении SURVEY
Внешние ключи
Еще раз обратимся к базе данных отделов и сотрудников, содержимое которой пока-
зано на рис. 18.1. Возможно, вы не обратили на это внимания, однако в свое время я на-
меренно не сказал, что на данном рисунке атрибут DEPT# переменной-отношения ЕМР яв-
ляется внешним ключом. Предположим теперь, что это так. Сразу становится понятно
следующее: требуется уточнить формулировку определения ограничений ссылочной це-
лостности с учетом того, что внешние ключи могут содержать неопределенные значения
(NULL), а это, очевидно, противоречит исходной формулировке данного ограничения,
приведенной в главе 8.
Ограничение ссылочной целостности (исходная формулировка}. База данных не
должна содержать никаких несогласованных значений внешних ключей.
706
Часть V. Дополнительные аспекты
В действительности это определение можно оставить в неизменном виде, если соот-
ветствующим образом расширить определение термина “несогласованные значения
внешнего ключа”. А именно, назовем несогласованным значением внешнего ключа такое
его непустое (т.е. NONNULL) значение в ссылающейся переменной-отношении, для кото-
рого не существует согласованного значения потенциального ключа в соответствующей
ссылочной переменной-отношении.
Здесь следует отметить такие важные особенности.
1. Запрет или разрешение на присутствие неопределенных значений (NULL) в данном
внешнем ключе должно задаваться в определении базы данных. (Конечно, в дейст-
вительности это требование справедливо в отношении всех атрибутов в целом, не-
зависимо от того, являются ли они частью некоторого внешнего ключа.)
2. Возможность присутствия неопределенных значений (NULL) во внешних ключах
требует введения нового типа ссылочного действия, SET NULL, которое можно бу-
дет указывать в правилах DELETE и UPDATE при определении внешних ключей.
VAR SP BASE RELATION { ... } ...
FOREIGN KEY { S# } REFERENCES S
ON DELETE SET NULL
ON UPDATE SET NULL ;
При использовании этих спецификаций операция DELETE в переменной-отношении
поставщиков приведет к помещению неопределенных значений (NULL) в атрибут
внешнего ключа всех кортежей с данными о соответствующих поставках, и только
после этого сведения об указанных поставщиках будут удалены. Аналогично опе-
рация UPDATE для атрибута S# в переменной-отношении поставщиков вызовет по-
мещение неопределенных значений (NULL) в атрибут внешнего ключа всех корте-
жей с данными о соответствующих поставках, и только после этого сведения об
указанных поставщиках будут обновлены.
Замечание. Спецификация SET NULL может быть указана только для тех внешних
ключей, в которых допускается наличие неопределенных значений (NULL).
3. Наконец, следует отметить, что “необходимости” разрешить присутствие неопре-
деленных значений (NULL) во внешних ключах вполне можно избежать за счет со-
ответствующего проектирования базы данных [18.20]. Еще раз обратимся к приме-
ру с отделами и сотрудниками. Возможна ситуация, когда некоторые сотрудники
действительно не относятся ни к одному из отделов. Но тогда, как уже предполага-
лось в конце предыдущего раздела, логичнее было бы не включать атрибут номера
отдела DEPT# в переменную-отношение ЕМР, а создать отдельную переменную-
отношение ED с атрибутами EMP# и DEPT#, предназначенную для представления того
факта, что указанный сотрудник работает в данном отделе. Если некоторый со-
трудник не относится ни к одному отделу, ситуацию легко можно представить, ис-
ключив кортеж для этого сотрудника из переменной-отношения ED.
18.5. Внешнее соединение
В этом разделе делается некоторое отступление от основной темы главы с целью обсу-
ждения часто используемой операции внешнего соединения [18.3], [18.4], [18.7], [18.14],
[18.15]. Внешнее соединение — это расширенная форма обычного или внутреннего соеди-
Глава 18. Отсутствующая информация 707
нения. Внешнее соединение отличается от внутреннего тем, что кортежи одного из отно-
шений, не имеющие соответствия среди кортежей другого отношения, появляются в ре-
зультирующем отношении с неопределенными значениями (NULL) во всех позициях атри-
бутов второго отношения, вместо того чтобы быть просто проигнорированными, как в
обычном соединении. Этот оператор не является примитивным. Например, для построения
внешнего естественного соединения по номеру поставщика переменных-отношений по-
ставщиков и поставок можно использовать приведенное ниже выражение (в демонстраци-
онных целях предположим, что NULL является корректным скалярным выражением).
( S JOIN SP )
UNION
( EXTEND ( ( S { S# } MINUS SP { S# } ) JOIN S )
ADD NULL AS P#, NULL AS QTY )
Результат будет содержать кортежи и для поставщиков, не выполнивших ни одной
поставки. В этих кортежах будут содержаться неопределенные значения (NULL) в позици-
ях атрибутов P# и QTY.
Исследуем этот пример более подробно. Взгляните на рис. 18.3. На нем вверху показа-
ны значения данных в исходных переменных-отношениях, ниже — результат их внутрен-
него естественного соединения, а еще ниже — результат их внешнего естественного соеди-
нения. Как следует из рисунка, внутреннее соединение, попросту говоря, утрачивает ин-
формацию о поставщиках, не выполнивших ни одной поставки (в данном примере это по-
ставщик с номером ' S5'), в то время как внешнее соединение сохраняет ее. Действительно,
имеющееся различие и является причиной использования внешнего соединения.
S S# SNAME STATUS CITY SP S# P# QTY
S2 Jones 10 Paris S2 Pl 300
S5 Adams 30 Athens S2 P2 400
Обычное (внутреннее) соединение:
S# SNAME STATUS CITY P# QTY Информация
S2 Jones 10 Paris Pl 300 для поставщика с номером
S2 Jones 10 Paris P2 400 ‘S5’ “теряется”
Внешнее соединение:
S# SNAME STATUS CITY P# QTY Информация
S2 Jones 10 Paris Pl 300 для поставщика с номером
S2 Jones 10 Paris P2 400 ‘S5’ “сохраняется”
S5 Adams 30 Athens UNK UNK
Рис. 18.3. Внутреннее и внешнее соединения (пример)
Таким образом, внешнее соединение предназначено для решения весьма важной про-
блемы, заключающейся в потере информации при внутреннем соединении. Некоторые
авторы высказывают мнение, что система должна обеспечивать прямую и явную под-
держку внешних соединений, вместо того чтобы требовать от пользователя при построе-
нии запроса прибегать к различным ухищрениям для достижения желаемого результата.
708
Часть V. Дополнительные аспекты
В частности, Кодд рассматривает внешнее соединение как неотъемлемую часть реляци-
онной модели [5.2]. Тем не менее в этой книге мы не будем высказываться за явную под-
держку внешних соединений по приведенным ниже причинам.
Прежде всего, конечно, операция внешнего соединения использует неопределен-
ные значения (NULL), а автор настоящей книги всегда выступает против этого по
целому ряду описанных ранее причин.
Кроме того, обратите внимание, что существует несколько разновидностей операции
внешнего соединения — левое, правое и полное внешнее ©-соединение, а также ле-
вое, правое и полное внешнее естественное соединение. (Левое соединение сохра-
няет в результирующем отношении информацию из левого операнда, правое — из
правого операнда, а полное— с обеих сторон.) На рис. 18.3 показан пример левого
соединения, точнее, левого внешнего естественного соединения. Более того, обрати-
те внимание, что не существует достаточно простого способа порождения внешнего
естественного соединения из внешнего ©-соединения [18.7]. В результате не ясно,
какой именно оператор внешнего соединения должна явно поддерживать система.
Далее, вопрос о внешнем соединении ни в коем случае нельзя считать столь же
тривиальным, как тот простой пример, который приведен на рис. 18.3. На практи-
ке, как показано в [18.7], операции внешнего соединения присущ ряд “неприятных
свойств”, которые в своей совокупности не позволяют эффективно реализовать ее
поддержку в существующих языках, в частности в языке SQL. Предпринятые в
некоторых коммерческих СУБД попытки решить эту проблему оказались неудач-
ными, т.е. в них так и не удалось справиться с “неприятными свойствами” (см.
[18.7], где данный вопрос описан подробнее).
И наконец, уже было высказано мнение о том, что атрибуты, значениями кото-
рых могут быть отношения, представляют собой альтернативный подход, позво-
ляющий радикально устранить все эти проблемы (глава 19). Такой подход исклю-
чает необходимость использования неопределенных значений (NULL) и операций
внешнего соединения и в действительности, по мнению автора, является более
элегантным решением. Например, для показанных на рис. 18.3 данных приведен-
ное ниже выражение позволяет получить результат, представленный на рис. 18.4.
WITH ( S RENAME S# AS X ) AS Y :
EXTEND Y ADD ( SP WHERE S# = X ) AS PQ
S# SNAME STATUS CITY PQ
S2 S5 Jones Adams 10 30 Paris Athens
P# QTY
Pl P2 300 400
P# QTY
Puc. 18.4. Сохранение информации о поставщике с номером 'S5' (более эффек-
тивный способ)
Глава 18. Отсутствующая информация
709
В частности, пустое множество деталей, поставляемых поставщиком с номером
' S5', на рис. 18.4 представлено именно в виде пустого множества, а не в виде ка-
ких-то неопределенных значений (NULL), как это было в случае, показанном на
рис. 18.3. Представление пустого множества в виде пустого множества, похоже,
является удачной идеей. Действительно, при должной поддержке атрибутов, зна-
чениями которых могут быть отношения, операция внешнего соединения может
оказаться совершенно излишней.
При более внимательном изучении этого вопроса можно заметить, что имеет
место проблема интерпретации неопределенных значений (NULL), которые по-
являются в результирующем отношении операции внешнего соединения. На-
пример, что представляют собой неопределенные значения, показанные на
рис. 18.3? Несомненно, они не означают “значение неизвестно” или “значение
неприменимо”. На самом деле единственная логически обоснованная интерпре-
тация их смысла следующая: “Значение является пустым множеством”. Более
подробно эта проблема обсуждается в [18.7].
В заключение раздела заметим, что существует возможность определить “внешние”
версии других операторов реляционной алгебры, в частности операторов объединения,
пересечения и вычитания [13.6]. И вновь Кодд рассматривает по крайней мере один из
таких операторов, а именно — внешнее объединение, как неотъемлемую часть его реля-
ционной модели [5.2]. Подобные версии операторов позволяют выполнять объединение
двух отношений и другие операции, даже если данные отношения несовместимы по
типу. Основной принцип работы таких операторов состоит в расширении каждого из
операндов за счет добавления атрибутов, свойственных другому операнду, с помещени-
ем неопределенных значений (NULL) в каждый такой атрибут каждого кортежа (после че-
го операнды становятся совместимыми по типу). Затем выполняется обычное объедине-
ние, пересечение или вычитание6. Тем не менее мы не будем подробно обсуждать эти
операции по следующим причинам.
Внешнее пересечение гарантированно возвращает пустое отношение, за ис-
ключением специального случая, когда исходные отношения совместимы по
типу. Однако в такой ситуации внешнее пересечение вырождается до обычно-
го пересечения.
Внешнее вычитание гарантированно возвращает первый операнд, за исклю-
чением специального случая, когда исходные отношения совместимы по ти-
пу. Однако в такой ситуации внешнее вычитание вырождается до обычного
вычитания.
Основными проблемами, характерными для операции внешнего объединения, яв-
ляются проблемы интерпретации; причем они даже сложнее проблем интерпрета-
ции, имеющих место в случае операции внешнего соединения. (См. [18.2] для бо-
лее детального изучения.)
6 Данное объяснение относится к исходным определениям этих операций [13.6]. В работе
[5.2] они в некоторой степени изменены, и читателю предлагается самостоятельно рассмот-
реть эти подробности.
710
Часть V. Дополнительные аспекты
18.6. Специальные значения
Как показано выше, введение неопределенных значений (NULL) приводит к раз-
рушению реляционной модели, которая великолепно обходилась без них в течение
десяти лет с момента ее создания 1969 году [5.1] и вплоть до введения этих значе-
ний в 1979 году [13.1].
Теперь предположим, как в разделе 18.4, что понятие “неопределенных значений” в
контексте представления отсутствующей информации заменено понятием специальных
значений. Следует отметить, что в реальном мире мы обычно пользуемся именно специ-
альными значениями. Например, специальное значение “?” используется для обозначе-
ния количества рабочих часов для некоторого сотрудника, если его фактическое значе-
ние по какой-либо причине неизвестно7. Таким образом, общая идея заключается в том,
чтобы просто применять подходящее специальное значение, отличное от обычных зна-
чений атрибута, во всех тех случаях, когда обычное значение не может использоваться.
Обратите внимание, что это специальное значение обязательно должно принадлежать
соответствующему домену. Поэтому в примере с данными о количестве рабочих часов
типом атрибута HOURS_WORKED является не просто целое число, а целые числа плюс спе-
циальное значение.
Безусловно, следует признать, что изложенная выше схема не очень элегантна, но она
обладает явным преимуществом, поскольку не подрывает логических основ реляционной
модели. В остальной части этой книги мы будем просто игнорировать возможность под-
держки неопределенных значений (NULL) за исключением некоторых случаев, специфи-
ческих для контекста языка SQL, когда те или иные ссылки на неопределенные значения
(NULL) будут неизбежны. Более подробно эти вопросы рассматриваются в [18.12].
18.7. Поддержка неопределенных значений
в языке SQL
Поддержка неопределенных значений (NULL) и трехзначной логики в языке SQL от-
ражает весь широкий спектр подходов, описанных в разделах 18.1-18.5. Так, например,
когда в языке SQL условие WHERE применяется к таблице Т, это исключает из рассмотре-
ния все строки таблицы Т, для которых указанное в предложении WHERE условие прини-
мает значение false или ипк (т.е. не true). Аналогично, когда к результату выполнения не-
которой операции группирования, представленному таблицей G, применяется оператор
HAVING, из дальнейшего рассмотрения исключаются все группы кортежей, для которых
указанное в предложении HAVING условие принимает значение false или ипк (т.е. не true).
Из этого следует, что мы просто обратили внимание читателя на некоторые возможно-
сти, специфические для языка SQL и не являющиеся частью концепции трехзначной ло-
гики, которая обсуждалась в предыдущем разделе.
Замечание. Очень сложно оценить все последствия поддержки неопределенных зна-
чений (NULL) в языке SQL. Дополнительную информацию можно найти в официальных
документах стандарта SQL [4.22] и в учебном издании [4.19].
7 Обратите внимание, что для этого не используется неопределенное значение (NULL). В ре-
альном мире никакого неопределенного значения вообще не существует.
Глава 18. Отсутствующая информация
711
Определение данных
Как описано в разделе 5.5 главы 5, для столбцов таблиц базы данных обычно указы-
вается некоторое значение, принимаемое по умолчанию', оно часто определяется (явно
или неявно), как величина NULL. Более того, столбцы в таблицах базы данных всегда раз-
решают использование неопределенных значений, если условие запрета их использова-
ния не будет указано явно (например, в виде фразы NOT NULL). Представление неопреде-
ленных значений зависит от реализации, но оно должно быть таким, чтобы система
смогла отличить это значение от других, которые неопределенными не являются (даже
несмотря на то, что операция сравнения NULL х не дает в результате true).
Табличные выражения
Напомним замечание из главы 7 (раздел 7.7) о том, что явная поддержка операции
JOIN была введена только в версии SQL/92 стандарта языка SQL. Более того, если перед
ключевым словом JOIN указан один из определителей LEFT, RIGHT или FULL (с необяза-
тельной добавкой OUTER в каждом случае), рассматриваемое соединение является внеш-
ним. Вот несколько примеров.
S LEFT JOIN SP ON S.S# = SP.S#
S LEFT JOIN SP USING ( S# )
S LEFT NATURAL JOIN SP
Три приведенных выражения эквивалентны, но первое приводит к созданию таблицы
с двумя идентичными столбцами номера поставщика, а второе и третье — таблицы с од-
ним столбцом номера поставщика.
Язык SQL также поддерживает аппроксимацию внешнего соединения, которую назы-
вают объединяющим соединением. Однако подробное обсуждение этого вопроса выхо-
дит за рамки данной главы.
Условные выражения
Как отмечалось в главе 8, в языке SQL условные выражения являются аналогом того,
что во всех остальных случаях называется логическими (или булевыми) выражениями
(более подробно они рассматриваются в приложении А). Неудивительно, что условные
выражения являются той частью языка SQL, которая в наибольшей степени связана с
неопределенными значениями и трехзначной логикой. Ниже предлагается несколько за-
мечаний по этому поводу.
Проверка наличия неопределенного значения. В языке SQL предусмотрены два
специальных оператора сравнения, IS NULL и IS NOT NULL, предназначенных для
проверки наличия или отсутствия неопределенных значений. Синтаксис использо-
вания этих операторов показан ниже.
<конструктор строки> IS [ NOT ] NULL
(Параметр <конструктор строки> подробно рассматривается в приложении А.)
Невнимательные пользователи могут попасть здесь в ловушку, поскольку выра-
жения г IS NOT NULL и NOT (г IS NULL) не являются эквивалентными! Более
подробно эта особенность рассматривается в [4.19].
712
Часть V. Дополнительные аспекты
Проверка наличия значений true, false и unknown. Если р - это заключенное в
скобки условное выражение, то следующие операторы также являются условными
выражениями.
р IS [ NOT ] TRUE
р IS [ NOT ] FALSE
p IS [ NOT ] UNKNOWN
Значения этих выражений показаны в приведенной ниже таблице истинности.
р true false unk
р IS TRUE true false false
р IS NOT TRUE false true true
p IS FALSE false true false
p IS NOT FALSE true false true
p IS UNKNOWN false false true
p IS NOT UNKNOWN true true false
Обратите внимание, что выражения р IS NOT TRUE и NOT р не являются эквива-
лентными.
Замечание. Выражение р IS UNKNOWN соответствует описанному выше оператору
MAYBE(p).
Условие MATCH. Синтаксис параметра <условне match» (см. приложение А) содер-
жит ключевые слова PARTIAL и FULL (их использование в приложении А не рас-
сматривается). Эти опции могут повлиять на результат, если в данных присутст-
вуют неопределенные значения.
<конструктор строки» MATCH [ UNIQUE ]
[ PARTIAL | FULL ] ( <табличное выражение»)
Существует шесть возможных случаев, зависящих от того, указана ли опция
UNIQUE, а также указана ли опция PARTIAL либо FULL. Подробное обсуждение этого
вопроса достаточно сложное и выходит за рамки настоящей главы. Дополнитель-
ную информацию можно найти в [4.19].
Условие EXISTS. См. комментарий к [18.6].
Скалярные выражения
Литералы. Ключевое слово NULL может быть использовано как способ лите-
рального представления неопределенных значений (например, в операторе
INSERT). Тем не менее следует заметить, что данное ключевое слово может ука-
зываться не во всех контекстах, в которых допускается использование литера-
лов. Согласно стандарту “не существует значения параметра <литерал> для
представления неопределенных значений, хотя в некоторых случаях для указа-
ния необходимости использования неопределенного значения может употреб-
ляться ключевое слово NULL” [4.22]. Поэтому, например, ключевое слово NULL
нельзя явно использовать как операнд в простых операциях сравнения, т.е. вы-
ражение WHERE X = NULL некорректно.
Глава 18. Отсутствующая информация
713
Функция COALESCE. Это SQL-аналог функции IF_UNK (см. раздел 18.2), определен-
ной выше в данной главе.
Обобщающие функции. Обобщающие функции языка SQL, например SUM, AVG
и т.п., не ведут себя в соответствии с правилами для скалярных операторов,
изложенными выше, в разделе 18.2. Вместо этого они просто игнорируют лю-
бое неопределенное значение в своих аргументах (исключение составляет
функция COUNT(*), при вычислении которой неопределенное значение тракту-
ется, как обычное значение). Кроме того, если этим функциям в качестве ар-
гумента передается пустое множество, они возвращают неопределенное
значение. Исключение и здесь составляет функция COUNT, которая в данном
случае возвращает значение “нуль”. (Сравните с трактовкой обработки пустых
множеств, изложенной в главе 7.)
Скалярные подчиненные запросы. Если скалярное выражение фактически является
заключенным в скобки табличным выражением, например (SELECT S.CITY
FROM S WHERE S.S#='S1'), то вполне естественно, что результатом вычисления
подобного табличного выражения должна быть таблица, содержащая единствен-
ный столбец и единственную строку. Тогда значением скалярного выражения в
целом будет то единственное скалярное значение, которое содержится в результи-
рующей таблице. Но если результатом вычисления табличного выражения являет-
ся таблица, не содержащая ни одной строки, в языке SQL значение этого скаляр-
ного выражения определяется, как неопределенное (NULL).
Ключи
Ниже кратко перечислены основные особенности использования неопределенных
значений в ключевых атрибутах, характерные для языка SQL.
Потенциальные ключи. Пусть С — это атрибут, являющийся частью потенциаль-
ного ключа К некоторой базовой таблицы. Если ключ К является первичным, то
язык SQL запрещает использование неопределенных значений в столбце С
(обеспечивая таким образом соблюдение ограничения целостности сущности).
Тем не менее, если ключ К не является первичным, язык SQL разрешает присутст-
вие в столбце С любого количества неопределенных значений (конечно, вместе с
любым количеством значений, не являющихся неопределенными).
Внешние ключи. Правила, определяющие смысл соответствия значения заданного
внешнего ключа некоторому значению соответствующего потенциального ключа
(при наличии в них неопределенных значений), очень сложны. В данном случае их
подробное обсуждение опускается. Заметим только, что они, в основном, совпа-
дают с правилами, установленными для условий MATCH (см. выше).
Неопределенные значения также оказывают влияние на выполнение действий по
установленным правилам поддержки ссылочной целостности (CASCADE, SET NULL
и т.д.), заданным в предложениях ON DELETE и ON UPDATE. Дополнительно под-
держивается действие SET DEFAULT, требующее установки заданного значения по
умолчанию. Для простоты изложения подробное обсуждение этой проблемы здесь
опущено. Заинтересованный читатель может обратиться к [4.19].
714
Часть К Дополнительные аспекты
Внедренные SQL-операторы
Индикаторные переменные. Рассмотрим конкретный пример внедренного SQL-
выражения. (Он уже приводился в главе 4 при описании однострочного опера-
тора SELECT.)
EXEC SQL SELECT STATUS, CITY
INTO :RANK, :CITY
FROM S
WHERE S# = :GIVENS# ;
Предположим, что для некоторых поставщиков атрибут STATUS может содержать
неопределенное значение. Тогда выполнение приведенного выше оператора
SELECT завершится неудачей, если в выбранном кортеже атрибут STATUS будет со-
держать неопределенное значение (в переменную SQLSTATE будет помещен код
ошибки 22002). В общем случае, когда существует вероятность, что выбираемое
значение может оказаться неопределенным, для данного атрибута пользователь
должен указать, помимо целевой, еще и индикаторную переменную. Пример оп-
ределения индикаторной переменной приведен ниже.
EXEC SQL SELECT STATUS, CITY
INTO :RANK INDICATOR :RANKING, :CITY
FROM S
WHERE S# = :GIVENS# ;
IF RANKING = -1 THEN ... /* Атрибут STATUS содержит величину NULL */;
END IF;
Если значение, которое нужно выбрать, является неопределенным и для данного ат-
рибута задана индикаторная переменная, то в эту переменную будет помещено зна-
чение -1 (значение, помещаемое в целевую переменную, зависит от реализации).
Упорядочение. Для упорядочения строк, полученных в результате вычисления
табличного выражения, в определении курсора используется фраза ORDER BY.
(Безусловно, она может использоваться и при вводе интерактивных запросов.)
Возникает вопрос: “Каков относительный порядок двух скалярных значений А и В,
если либо А является неопределенным значением, либо В является неопределен-
ным значением, либо оба они одновременно являются неопределенными значе-
ниями?”. В стандарте языка SQL на этот вопрос даются следующие ответы.
1. В процессе упорядочения все неопределенные значения считаются равными од-
но другому.
2. В процессе упорядочения все неопределенные значения считаются либо боль-
шими всех остальных значений, либо меньшими их всех (реальный выбор одной
из этих возможностей зависит от конкретной реализации).
18.8. Резюме
В этой главе обсуждались проблема отсутствующей информации и выбранный в
настоящее время подход к ее решению, базирующийся на использовании неопределен-
ных значений и трехзначной логики. Было показано, что неопределенное значение на
самом деле значением не является, хотя так принято говорить (например, говорят, что
Глава 18. Отсутствующая информация
715
некоторый атрибут кортежа содержит “значение NULL”). Результатом любых операций
сравнения, в которых один из операндов содержит неопределенное значение, служит
третье логическое значение unknown (сокращенно — ипк), поэтому такая логика назы-
вается трехзначной. Кроме того, отмечалось, что, по крайней мере концептуально, ин-
формация может отсутствовать по целому ряду причин, поэтому существуют различные
виды неопределенных значений (NULL). Для одного из видов неопределенных значе-
ний — “значение не определено” — было предложено удобное сокращение UNK.
Далее исследовалось влияние использования величины UNK и трехзначной логики на вы-
числение логических выражений, кванторов FORALL и EXISTS, вычисляемых выражений
и реляционных операторов произведения, выборки, проекции, объединения, пересечения и
вычитания, а также на выполнение операторов обновления INSERT и UPDATE. В этой главе бы-
ли представлены оператор ISJJNK (проверяющий наличие величины UNK), оператор IF_UNK
(для преобразования величины UNK в логическое значение, отличное от UNK) и оператор MAYBE
(для преобразования значения ипк в true). Дополнительно обсуждалась проблема кортежей-
дубликатов с учетом присутствия величины UNK. Кроме того, было особо подчеркнуто, что
величина UNK и логическое значение ипк — это не одно и то же.
Затем рассматривались некоторые следствия изложенных идей. Было показано, что
некоторые эквивалентности двухзначной логики не являются эквивалентностями
в трехзначной логике. В результате пользователи и программы-оптимизаторы СУБД мо-
гут совершать ошибки в процессе преобразования выражений. Но даже без учета на-
званных ошибок трехзначная логика обладает одним очень серьезным недостатком —
она не соответствует реальному миру, т.е. результаты операций в трехзначной логике
не всегда корректны по отношению к ситуации в реальном мире.
После описывались последствия присутствия неопределенных значений в первичных и
внешних ключах (в частности, упоминались правила поддержки целостности сущностей
и пересмотренное правило поддержки ссылочной целостности). Было сделано отступление
для описания внешнего соединения. Отмечалось, что автор не является сторонником пря-
мой поддержки этой операции (по крайней мере, в ее обычном смысле), так как считает,
что существует лучшее решение той проблемы, которую призвано решать внешнее соеди-
нение. В частности, автор предлагает использовать решения на основе атрибутов со зна-
чениями-отношениями. Также кратко рассматривалась возможность существования и дру-
гих “внешних” операций, в частности операции внешнего объединения.
В данной главе проанализирована поддержка изложенных идей в стандарте языка SQL.
В трактовке проблемы отсутствия информации в стандарте языка SQL широко использует-
ся трехзначная логика, но эта трактовка вносит множество осложнений, описание которых
выходит за рамки данной книги. И действительно, в дополнение к собственным недостат-
кам трехзначной логики ([18.6], [18.10]) стандарт языка SQL вносит свои недостатки. Более
того, эти дополнительные недостатки, по сути, выступают как факторы замедления про-
цесса оптимизации (более подробно это обсуждается в конце главы 7).
В заключение попытаемся кратко сформулировать некоторые дополнительные замечания.
Читатель, безусловно, согласится, что проблемы, связанные с использованием не-
определенных значений и трехзначной логики, описаны в книге несколько сжато.
Тем не менее здесь представлен достаточно большой объем материала, позво-
ляющего убедиться в том, что “преимущества”, достигаемые при использовании
трехзначной логики, более чем сомнительны.
716
Часть И Дополнительные аспекты
Следует также заметить, что даже если читатель не слишком озабочен проблема-
ми, связанными с использованием трехзначной логики, ему все же рекомендуется
избегать применения соответствующих возможностей языка SQL из-за упоминав-
шихся выше “дополнительных недостатков”.
Исходя из всего сказанного, автор рекомендует пользователям СУБД полностью иг-
норировать все средства поддержки трехзначной логики, предоставленные разра-
ботчиком выбранного им продукта. Вместо них целесообразно использовать более
строгий механизм “специальных значений” (благодаря своей строгости остающийся
в рамках двухзначной логики). Подобная схема подробно описана в [18.12].
И наконец повторим важное утверждение, сформулированное в разделе 18.6.
Очень нестрого говоря, если значение данного атрибута данного кортежа данного
отношения “является неопределенным”, то в этой позиции атрибута вообще ниче-
го не содержится. Это означает, что данный “атрибут” уже не является атрибутом,
что этот “кортеж” уже не является кортежем, что это “отношение” уже не является
отношением и для обоснования наших дальнейших действий (какими бы они ни
были) использовать математическую реляционную теорию уже нельзя.
Упражнения
18.1. Укажите логические результаты вычисления следующих выражений, если А = 6,
В = 5, С = 4и0 содержит величину UNK.
а) А = В OR ( В > С AND А > D )
б) А > В AND ( В < С OR IS_UNK ( А - D ) )
в) А < С OR В < С OR NOT ( А = С )
г) B<DORB = DORB>D
д) MAYBE ( А > В AND В > С )
е) MAYBE ( IS_UNK ( D ) )
ж) MAYBE ( ISJJNK ( А + В ) )
з) IFJJNK ( D, А ) > В AND IFJJNK ( С, D ) < В
18.2. Отношение г содержит следующие кортежи.
(6,5,4)
( UNK, 5, 4 )
( 6, UNK, 4 )
( UNK, UNK, 4 )
( UNK, UNK, UNK )
Как было сказано выше в этой главе, предположим, что три атрибута в указанном
порядке слева направо называются А, В и С соответственно и каждый атрибут имеет
тип INTEGER. Укажите логические результаты вычисления следующих выражений,
где V — переменная диапазона, принимающая значения из отношения г.
a) EXISVS V ( V.B > 5 )
б) EXISVS V ( V.B > 2 AND V.C > 5 )
Глава 18. Отсутствующая информация
717
в) EXISVS V ( MAYBE ( V.C > 3 ) )
г) EXISVS V ( MAYBE ( IS_UNK ( V.C ) ) )
д) FORALL V ( V.A > 1 )
e) FORALL V ( V.B > 1 OR IS_UNK ( V.B ) )
ж) FORALL V ( MAYBE ( V.A > V.B ) )
18.3. Строго говоря, оператор IS_UNK не нужен. Почему?
18.4. В [13.6] Кодд предложил “maybe’’-версии для некоторых операторов реляци-
онной алгебры. Например, maybe-выборка отличается от обычного оператора
выборки тем, что возвращает кортежи, для которых условие выборки прини-
мает значение ипк, а не true. Тем не менее, строго говоря, подобные операторы
не нужны. Почему?
18.5. В двухзначной логике существует только два логических значения — true и false.
Следствием этого является существование ровно четырех возможных унарных
логических операторов: один преобразует оба значения в true, второй преобразу-
ет оба значения в false, третий преобразует true в false и наоборот (т.е. это опера-
тор NOT) и четвертый сохраняет значение операнда неизменным. Кроме того,
существует ровно 16 возможных бинарных логических операторов (см. таблицу
истинности, приведенную ниже).
А |В____________________________________________
ttttttttttffffffff
tfttttffffttttffff
ftttffttffttffttff
fftftftftftftftftf
Докажите, что все четыре унарных оператора и все шестнадцать бинарных опера-
торов можно записать с помощью комбинаций операторов NOT, AND и OR
(следовательно, нет необходимости явно поддерживать все двадцать операторов).
18.6. Сколько логических операторов может быть в трехзначной логике? А в четырех-
значной? А для более общего случая — в и-значной логике?
18.7. (Взято из [18.5].) На рис. 18.5 приведен набор данных для очередного варианта ба-
зы данных поставщиков и деталей. Этот вариант отличается от предыдущих тем,
что в отношение SP включен атрибут SHIP# (номер партии), а атрибут P# в этом
отношении определен как разрешающий использование величины UNK.
(Отношение Р в данном примере не используется и в упражнении не описывается.)
S S# SNAME STATUS CITY SP SHIP# S# P# QTY
SI Smith 20 London SHIP1 SI Pl 300
S2 Jones 10 Paris SHIP2 S2 P2 200
S3 Blake 30 Paris SHIP3 S3 UNK 400
S4 Clark 20 London
Рис. 18.5. Вариант базы данных поставщиков и деталей
Рассмотрим следующее выражение реляционного исчисления.
718
Часть V. Дополнительные аспекты
S WHERE NOT EXISTS SP ( SP.S# = S.S# AND
SP.P# = P# ( 'P2' ) )
Здесь S и SP — это неявные переменные диапазона. Какая из следующих интерпре-
таций запроса будет корректна (если таковая вообще существует)?
а) Получить сведения о поставщиках, которые не поставляют деталь с номером
'Р2'.
б) Получить сведения о поставщиках, о которых неизвестно, поставляют ли они де-
таль с номером ' Р2'.
в) Получить сведения о поставщиках, о которых известно, что они не поставляют
деталь с номером ' Р2'.
г) Получить сведения о поставщиках, о которых либо известно, либо не известно,
что они поставляют деталь с номером ' Р2'.
18.8. Спроектируйте схему физического представления базовых SQL-таблиц, допус-
кающих использование неопределенных значений.
Список литературы
18.1. Codd E.F. and Date C.J. Much Ado About Nothing // C.J. Date. Relational Database
Writings 1991-1994. — Reading, Mass.: Addison-Wesley, 1995.
Вероятно, именно Кодд является наиболее известным сторонником использования
неопределенных значений и трехзначной логики для обработки отсутствующей
информации. В этой статье содержится текст дискуссии по этому поводу между
Коддом и автором. В ней имеется следующее превосходное замечание:
“Управление базой данных существенно упростилось бы, если бы отсутствующие
значения не существовали” (Кодд).
18.2. Darwen Н. Into the Unknown // C.J. Date. Relational Database Writings 1985-1989. —
Reading, Mass.: Addison-Wesley, 1990.
В этой работе поднимается ряд дополнительных вопросов в отношении использова-
ния неопределенных значений и трехзначной логики, наиболее сложным из которых
является следующий: “Если (как показано в упр. 5.9 в главе 5) отношение TABLE_DEE
соответствует значению true, а отношение TABLE_DUM - значению false и если отно-
шения TABLE_DEE и TABLE_DUM являются единственными возможными экземплярами
отношения степени «нуль», то что же соответствует значению ипкТ.
18.3. Darwen Н. Outer Join with No Nulls and Fewer Tears // C.J. Date and Hugh Darwen.
Relational Database Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
В работе предложен простой вариант “внешнего соединения”, в котором не ис-
пользуются неопределенные значения и решается много других задач, которые
должны были устраняться с помощью внешних соединений.
18.4. Date C.J. The Outer Join // C.J. Date. Relational Database: Selected Writings. — Read-
ing, Mass.: Addison-Wesley, 1986.
Здесь подробно обсуждается проблема внешнего соединения и приводятся не-
которые предложения по поддержке этой операции в таких реляционных язы-
ках, как SQL.
Глава 18. Отсутствующая информация
719
18.5. Date C.J. NOT is Not “Not”! (Notes on Three-Valued Logic and Related Matters) // C.J. Date.
Relational Database Writings 1985-1989. — Reading, Mass.: Addison-Wesley, 1990.
Предположим, что выражение X имеет тип BOOLEAN. В этом случае оно должно
иметь одно из значений true, false или ипк. Тогда утверждение “X не равно true” оз-
начает, что значением выражения X является либо значение ипк, либо значение
false. В противоположность этому выражение X = NOT true имеет значение false
(см. таблицу истинности для операции NOT). Таким образом, действие операции
NOT в языке трехзначной логики не соответствует частице “не” в обычном языке...
Этот факт уже привел в замешательство многих (включая разработчиков стандарта
языка SQL) и, несомненно, будет продолжать удивлять.
18.6. Date C.J. EXISTS is Not “Exist”! (Some Logical Flaws in SQL) // C.J. Date. Relational
Database Writings 1985-1989. — Reading, Mass.: Addison-Wesley, 1990.
В этой статье утверждается, что оператор EXISTS языка SQL не является идентич-
ным квантору существования языка трехзначной логики, потому что он всегда ра-
вен либо true, либо false и никогда не равен ипк, даже если ипк является логически
корректным ответом.
18.7. Date C.J. Watch Out for Outer Join // C.J. Date and Hugh Darwen. Relational Database
Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
В разделе 18.5 утверждается, что внешнее соединение обладает несколькими
“неприятными свойствами”. В этой работе приводится перечень подобных
свойств.
1. Внешнее ©-соединение не является выборкой из результата декартова произве-
дения.
2. Выборка не распространяется на операции внешнего ©-соединения.
3. В трехзначной логике выражение А < В— это не то же самое, что выражение
А < В OR А = В.
4. В трехзначной логике операции ©-сравнения не транзитивны.
5. Внешнее естественное соединение не является проекцией внешнего соединения
по эквивалентности.
В статье также рассматривается влияние, оказанное на конструкты SELECT-FROM-
WHERE в результате введения в язык SQL поддержки внешних соединений.
1. Операция расширения в предложении WHERE не работает.
2. Оператор AND, связывающий операции внешнего соединения и выборки, не ра-
ботает.
3. Включение условия соединения в предложение WHERE не работает.
4. Внешние соединения из более чем двух отношений не могут быть сформулиро-
ваны без использования вложенных выражений.
5. Операция расширения в предложении SELECT (только) не работает.
В этой статье также показано, что во многих существующих программных продук-
тах содержатся ошибки, вызванные указанными выше условиями.
18.8. Date C.J. Composite Foreign Keys and Nulls // C.J. Date and Hugh Darwen. Relational
Database Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
720
Часть V. Дополнительные аспекты
В этой статье рассматривается возможность полного и частичного присутствия не-
определенных значений во внешних ключах.
18.9. Date C.J. Three-Valued Logic and the Real World // C.J. Date and Hugh Darwen.
Relational Database Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
18.10. Date C.J. Oh No Not Nulls Again // C.J. Date and Hugh Darwen. Relational Database
Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
В этой статье приводится дополнительная информация о неопределенных значениях.
18.11. Date C.J. A Note on the Logical Operators Of SQL // Relational Database Writings
1991-1994. — Reading, Mass.: Addison-Wesley, 1995.
В трехзначной логике (3VL) используются три логических значения — true, false и
unknown (обозначенные здесь как t,f и и соответственно). Следовательно, в трех-
значной логике может быть 3*3*3=27 возможных унарных операторов, так
как каждое из трех возможных входных значений t,f и и может отображать любое
из трех возможных выходных значений t,f ми. По той же причине в трехзначной
логике может быть 39=19 683 возможных бинарных оператора (см. таблицу, при-
веденную ниже).
t u f
t t/u/f t/u/f t/u/f
u t/u/f t/u/f t/u/f
f t/u/f t/u/f t/u/f
Фактически в более общем случае и-значная логика (hVL) включает п в степени п
унарных операторов и п в степени п2 бинарных операторов (см. таблицу, приве-
денную ниже).
Унарные операторы Бинарные операторы
2VL 4 16
3VL 27 19 683
4VL 256 4 294 967 296
n VL (л)**(и) (л)**(л2)
Для любой и-значной логики, где п > 2, возникают следующие вопросы.
Каков наиболее подходящий набор примитивных операторов? (Например, как
множество операторов {NOT, AND}, так и множество операторов {NOT, OR} явля-
ются подходящими примитивными наборами для двухзначной логики.)
Каков подходящий набор полезных операторов? (Например, множество {NOT,
AND, OR} — подходящий полезный набор для двухзначной логики.)
В данной статье показано, что стандарт SQL (при очень вольной интерпретации)
прямо или косвенно поддерживает все 19 710 операторов трехзначной логики. Тем
не менее необходимо обратить внимание на то, что в логике операторы оперируют
предикатами и предложениями, в то время как в языке SQL (даже при вольной ин-
терпретации) операторы оперируют только предложениями.
18.12. Date C.J. Faults and Defaults (in five parts) // C.J. Date, Hugh Darwen and David
McGoveran. Relational Database Writings 1994-1997.— Reading, Mass.:
Addison-Wesley, 1998.
Глава 18. Отсутствующая информация
721
Разработан систематический подход к проблеме отсутствия информации, ос-
нованный на использовании значений по умолчанию и двухзначной логики
вместо неопределенных значений и трехзначной логики. В статье аргументи-
ровано доказывается, что значения по умолчанию — это то, что мы использу-
ем в реальном мире (в реальном мире такого понятия, как NULL, не
существует). Таким образом, желательно, чтобы системы баз данных были
максимально приближены к реальному миру.
18.13. Debabrata Dey and Sumit Sarkar. A Probabilistic Relational Model and Algebra // ACM
TODS 21, No. 3, September, 1996.
В этой статье предлагается способ работы с “неопределенностью в значениях дан-
ных” на основе теории вероятности вместо неопределенных значений и трехзнач-
ной логики. “Вероятностная реляционная модель” является совместимым расши-
рением обычной реляционной модели.
18.14. Cesar A. Galindo-Legaria. Outerjoins and Disjunctions // Proc. 1994 ACM SIGMOD Int.
Conf. On Management of Data, Minneapolis, Minn., May, 1994.
Внешнее соединение в общем случае не является ассоциативным оператором
[18.4]. Эта статья точно характеризует те внешние соединения, которые являются
ассоциативными, и те, которые не являются таковыми. В ней также предлагаются
стратегии реализации каждого случая.
18.15. Cesar A. Galindo-Legaria and Amon Rosenthal. Outerjoin Simplification and Reordering
for Query Optimization 11 ACM TODS 22, No. 1, March, 1997.
В этой статье представлен “полный набор правил преобразования” для выражений,
включающих внешние соединения.
18.16. Piyush Goel and Bala Iyer. SQL Query Optimization: Reordering for a General Class of
Queries // Proc. 1996 ACM SIGMOD Int. Conf, on Management of Data, Montreal, Canada,
June, 1996.
Так же, как и в [18.15], в этой статье рассматриваются выражения преобразования
с внешними соединениями: “[Мы] предлагаем метод переупорядочения [произ-
вольного] SQL-запроса с соединениями, внешними соединениями и... обобщаю-
щими функциями... [Мы] предлагаем мощное и простое средство [для упрощения
такого переупорядочения, которое называется] обобщенная выборка”.
18.17. Heath I.J. IBM internal memo. —April, 1971.
В статье впервые вводится термин (и концепция) “внешнее соединение”.
18.18. Liu К.-C., Sunderraman R. Indefinite and Maybe Information in Relational Databases //
ACM TODS. — March, 1990. — 15, № 1.
Содержит набор формальных предложений по расширению реляционной модели
для работы с возможной информацией (например, “деталь с номером 'Р7' может
быть черной”) и с неопределенной или дизъюнктивной информацией (например,
“деталь с номером 'Р8' или номером 'Р9' красная”). Представлены таблицы ис-
тинности (l-tables) для нормальной (определенной), возможной и неопределенной
информации. Для работы с таблицами истинности расширены операторы выборки,
проекции, произведения, объединения, пересечения и вычитания.
18.19. Maier D. The Theory of Relational Databases. — Rockville, Md.: Computer Science
Press, 1983.
722
Часть V. Дополнительные аспекты
18.20. McGoveran D. Nothing from Nothing I I C.J. Date, Hugh Darwen and David McGoveran.
Relational Database Writings 1994-1997. — Reading, Mass.: Addison-Wesley, 1998.
Работа состоит из четырех частей. В части I показано определяющее значение логики
в системах баз данных. В части II объясняется, почему эта логика должна быть двух-
значной и почему попытки использовать трехзначную логику не приветствуются. В
части III рассматривается, как можно “разрешить” проблемы трехзначной логики. И
наконец в части IV приводится ряд прагматических решений этих проблем.
18.21. Rescher N. Many-Valued Logic. —New-York, N.Y.: McGraw-Hill, 1969.
Стандартный учебник по многозначной логике.
Ответы к некоторым упражнениям
18.1. Вариант а— значение ипк; вариант б— значение true; вариант в— значение true;
вариант г — значение ипк (обратите внимание на то, что интуитивно предполагает-
ся другой ответ); вариант д — значение false; вариант е — значение false (обратите
внимание на то, что оператор IS_UNK никогда не возвращает значение ипк); вари-
ант ж — значение false; вариант з — значение true.
18.2. Вариант а — значение ипк; вариант б— значение ипк; вариант в— значение true;
вариант г — значение false; вариант д — значение ипк; вариант е — значение true;
вариант ж — значение false.
18.3. Это следует из приведенного ниже тождества.
IS_UNK ( х ) = MAYBE ( х = х )
18.4. Так как, например, выражение MAYBE_RESTRICT г WHERE р аналогично выражению
Г WHERE MAYBE(p).
18.5. Четыре унарных оператора могут быть определены следующим образом (здесь
А — единственный операнд).
А
NOT(A)
A OR NOT(A)
A AND NOT(A)
16 бинарных операторов могут быть определены следующим образом (здесь А и
В — два возможных операнда).
A OR NOT(A) OR В OR NOT(B)
A AND NOT(A) AND В AND NOT(B)
A
NOT(A)
В
NOT(B)
A OR В
A AND В
A OR NOT(B)
A AND NOT(B)
Глава 18. Отсутствующая информация
723
NOT(A) OR В
NOT(A) AND В
NOT(A) OR NOT(B)
NOT(A) AND NOT(B)
(NOT(A) OR B) AND (NOT(B) OR A)
(NOT(A) AND B) OR (NOT(B) AND A)
Чтобы убедиться в том, что одновременное использование операторов AND и OR не
является необходимым, обратите внимание на следующее выражение.
A OR В = NOT ( NOT ( А ) AND ( NOT ( В ) )
18.6. См. комментарий к [18.11].
18.7. Корректен вариант в. Более подробная информация приводится в [18.8].
Дополнительное упражнение. Для интерпретации варианта б предложите форму-
лировку с использованием реляционного исчисления.
18.8. Опишем кратко представление, используемое в СУБД DB2. В ней столбец табли-
цы, который может принимать неопределенные значения, физически представлен в
хранимой базе данных двумя столбцами — столбцом непосредственно данных и
скрытым столбцом индикатора (длиной 1 байт), сохраняемым как префикс для
столбца фактических данных. Значение в столбце индикатора, состоящее из дво-
ичных единиц, указывает, что соответствующее значение в столбце данных должно
игнорироваться (т.е. восприниматься как неопределенное значение); значение в
столбце индикатора, состоящее из двоичных нулей, указывает, что соответствую-
щее значение в столбце данных должно восприниматься, как реальное значение.
Безусловно, столбец индикатора всегда скрыт от пользователя.
724
Часть V. Дополнительные аспекты
Глава
Наследование типов
19.1. Введение
В главе 13 уже рассматривались понятия подтипов и супертипов, а точнее— подти-
пов и супертипов сущностей. Там же отмечалось, что если, например, некоторые слу-
жащие являются программистами и все программисты являются служащими, то тип
сущности PROGRAMMER можно рассматривать как подтип сущности EMPLOYEE, а тип сущ-
ности EMPLOYEE — как супертип сущности PROGRAMMER. Но при этом подчеркивалось, что
“тип сущности” не является типом в каком-либо формальном смысле, в частности по-
скольку само понятие “сущность” определено довольно нестрого. В этой главе мы по-
знакомимся с понятиями подтипов и супертипов поближе, но термин “тип” будем упот-
реблять в более формальном и точном смысле, как в главе 5. Поэтому начнем с точного
определения рассматриваемого термина.
Тип— это именованное множество значений (т.е. все возможные значения рас-
сматриваемого типа) вместе со связанным множеством операторов, которые мо-
гут применяться для значений и переменных данного типа.
Кроме того, добавим следующее.
Любой конкретный тип является либо системно определенным, либо пользова-
тельским.
В определении любого конкретного типа указывается множество всех допустимых
его значений (для этого, безусловно, используются ограничения типа, как указы-
валось в главе 8).
Значения типа могут быть сколь угодно сложными.
Реальное или физическое представление каждого значения всегда скрыто от поль-
зователя, т.е. типы отличаются от их реального представления. Однако каждый
тип имеет хотя бы одно возможное представление, которое явно доступно поль-
зователю через соответствующие операторы ТНЕ_ или их эквиваленты.
Значения и переменные каждого типа могут обрабатываться только с помощью
операторов, определенных для этого типа.
К числу таких операторов, кроме упомянутых операторов ТНЕ_, относятся сле-
дующие операторы.
а) По крайней мере один оператор выбора, точнее, один такой оператор для каж-
дого предоставленного пользователю возможного представления. Он позволяет
“выбрать” любое значение данного типа или указать его посредством соответ-
ствующего вызова операции выбора.
Глава 19. Наследование типов
725
б) Оператор равенства, который позволяет проверить, являются ли два произ-
вольных значения данного типа на самом деле одним и тем же значением.
в) Оператор присвоения, позволяющий присвоить некоторое значение данного
типа переменной, которая рассматривается как переменная данного типа.
г) Определенные операторы проверки типа, которые будут рассмотрены в раз-
деле 19.6.
Замечание. Эти операторы могут оказаться ненужными, если отсутствует
поддержка наследования.
Ко всему сказанному выше необходимо добавить следующее.
Одни типы могут являться подтипами других супертипов. Если В — это подтип
типа А, то все операторы и ограничения типа, которые применимы к типу А, также
применимы к типу В (наследование), но тип В в этом случае имеет еще и собст-
венные операторы и ограничения типа, которые не применимы к типу А.
Например, предположим, что заданы два типа, ELLIPSE (Эллипс) и CIRCLE
(Окружность), понимаемые в их обычном толковании. Тогда можно сказать, что тип
CIRCLE— это подтип типа ELLIPSE (а тип ELLIPSE— это супертип типа CIRCLE). При
этом подразумевается следующее.
Каждая окружность является эллипсом (т.е. множество всех окружностей является
подмножеством всех эллипсов), однако обратное утверждение неверно.
Следовательно, каждый оператор, который применим к эллипсам вообще, безус-
ловно, применим и к окружностям (поскольку окружности являются эллипсами),
однако обратное утверждение неверно. Например, оператор THE_CTR (Определить
центр) можно применять ко всем эллипсам, а значит, и к окружностям, но опера-
тор THE_R (Определить радиус) можно применять только к окружностям.
Кроме того, любое ограничение, которое применимо к эллипсам вообще, приме-
нимо и к окружностям в частности (опять же, поскольку окружности являются
эллипсами), однако обратное утверждение неверно. Например, если эллипсы под-
чиняются ограничению а > b (где а и b — его большая и малая полуоси соответ-
ственно), то же самое ограничение должно выполняться и для окружностей. Из-
вестно, что для окружностей полуоси а и b совпадают с радиусом г, а значит, ука-
занное ограничение удовлетворяется тривиально, т.е. для окружностей на самом
деле применимо более строгое ограничение а = Ь. Однако это ограничение не
удовлетворяется для всех эллипсов в общем случае.
Замечание. Везде в этой главе не уточненный дополнительно термин “ограничение”
будет использоваться для обозначения именно ограничения типа. Кроме того, тер-
мины “радиус” и “полуось” здесь означают то, что точнее было бы назвать длиной
радиуса или полуоси.
Таким образом, говоря нестрого, тип CIRCLE наследует операторы и ограничения от ти-
па ELLIPSE, а также имеет собственные операторы и ограничения, которые не применимы к
типу ELLIPSE. Обратите внимание, что подтип имеет подмножество значений, но в то же
время — и супермножество свойств (этот аспект иногда служит источником путаницы!).
Замечание. Здесь и далее в этой главе под термином “свойства” мы будем подразуме-
вать удобное сокращение для “совокупности операторов и ограничений”.
726
Часть V. Дополнительные аспекты
Почему используется наследование типов
Почему тема наследования типов заслуживает отдельного рассмотрения? Имеется по
меньшей мере два ответа на этот вопрос.
Во-первых, идеи выделения подтипов и наследования весьма широко распростра-
нены в реальном мире, т.е. нет ничего необычного в такой ситуации, когда все
значения типа имеют определенные свойства вообще и в то же время некоторое
подмножество этих значений имеет собственные дополнительные специфические
свойства. Поэтому выделение подтипов и использование механизма наследования
представляются вполне полезными инструментами “моделирования реальности”
(или семантического моделирования, как мы называли его в главе 13).
Во-вторых, если имеется возможность распознавать такие шаблоны, т.е. шаблоны
выделения подтипов и наследования, то, включив информацию о них в программ-
ное обеспечение приложений и систем, можно будет получить определенную
практическую выгоду. Например, программу, которая применима для эллипсов,
можно будет использовать и для окружностей даже в том случае, если первона-
чально она создавалась без учета существования понятия окружностей (например,
тип CIRCLE еще не был определен во время написания программы). Это так назы-
ваемое преимущество повторного использования кода.
К сожалению, эти потенциальные возможности, как мы сейчас убедимся, не находят
единодушной поддержки, поскольку нет единого мнения относительно формальной,
строгой и абстрактной модели наследования типов, подтверждением чему может слу-
жить следующее высказывание из [19.10].
"Основная идея наследования довольно проста... [тем не менее, несмотря на] ее ве-
дущую роль в современных... системах, наследование— еще довольно спорный меха-
низм... [Какого-либо] исчерпывающего представления о наследовании пока нет. ”
Обсуждение в этой главе основывается на модели, разработанной автором вместе с
Хью Дарвеном и подробно описанной в [3.3]. Поэтому предупредим читателя о том, что
другие авторы в других текстах иногда вкладывают в такие термины, как “подтип” и
“наследование”, смысл, который несколько отличается от трактовки, принятой в настоя-
щей книге.
Предварительные замечания
Существует ряд вопросов, в которых нужно разобраться, прежде чем переходить к
обсуждению аспектов, непосредственно связанных с самим наследованием. В данном
подразделе этим мы и займемся.
Значения имеют тип
Воспользуемся рассуждениями из главы 5. Если v — некоторое значение, то его
можно представить как помеченное неким флажком значение с надписью “Я —
целое”, “Я — номер поставщика”, “Я — окружность” и т.д. Поэтому при отсутст-
вии наследования каждое значение будет относиться строго к одному типу. При
использовании наследования значение может относиться к нескольким типам од-
новременно, т.е. иметь тип ELLIPSE и CIRCLE в одно и то же время.
Глава 19. Наследование типов 727
Переменные имеют тип
Каждая переменная имеет ровно один объявленный тип. Например, можно объя-
вить переменную следующим образом.
VAR Е ELLIPSE ;
Здесь объявленный тип переменной Е — ELLIPSE. Если наследование не применя-
ется, все возможные значения переменных имеют только один тип, а именно —
соответствующий объявленный тип. Однако при использовании наследования
данная переменная будет иметь значение, которое может относиться к нескольким
типам одновременно, т.е. текущее значение переменной Е может быть эллипсом,
который в действительности является окружностью, а потому относится и к типу
ELLIPSE, и к типу CIRCLE в одно и то же время.
Одиночное и множественное наследования
Существует две разновидности наследования: одиночное и множественное. Вы-
ражаясь неформально, одиночное наследование означает, что каждый подтип
имеет ровно один супертип и наследует свойства лишь одного этого типа. В слу-
чае множественного наследования каждый подтип может иметь любое количе-
ство супертипов и наследовать свойства каждого из них. Очевидно, что первый
вариант является частным случаем второго. Однако использование даже одиноч-
ного наследования является достаточно сложной задачей (такое утверждение мо-
жет показаться несколько неожиданным, но это действительно так). Поэтому в на-
стоящей главе мы ограничимся обсуждением лишь одиночного наследования и
под общим термином наследование (при отсутствии дополнительных пояснений)
всегда будем подразумевать именно одиночное наследование. Заинтересованному
читателю можно рекомендовать обратиться к [3.3], где подробно обсуждаются оба
вида наследования, как множественное, так и одиночное.
Наследование скалярных значений, кортежей и отношений
Очевидно, что наследование возможно как для скалярных, так и для неска-
лярных значений1, поскольку, в конце концов, эти нескалярные значения по-
строены из скалярных значений. В частности, механизм наследования может
применяться также к значениям кортежей и отношений. Однако даже насле-
дование скалярных значений является весьма сложным механизмом (что,
опять-таки, несколько неожиданно). Поэтому мы ограничимся рассмотрением
лишь наследования скалярных значений и будем подразумевать, что не уточ-
ненные дополнительно термины тип, значение и переменная означают тип,
значение и переменную именно скалярного типа. В [3.3] можно найти сведе-
ния обо всех видах наследования, а также о наследовании как скалярных зна-
чений, так и кортежей и отношений.
I Напомним, что скалярный тип — это такой тип, который не имеет компонентов, видимых
пользователю. Пусть вас не вводит в заблуждение то, что скалярные типы имеют возможные
представления, которые, в свою очередь, действительно имеют видимые пользователю компо-
ненты, как указывалось в главе 5. Эти компоненты являются компонентами возможного пред-
ставления, а не компонентами типа, несмотря на то что мы иногда для упрощения ссылаемся на
них так, как будто они действительно являются компонентами типа.
728
Часть V. Дополнительные аспекты
Наследование структуры или поведения
Напомним, что скалярные значения могут иметь внутреннюю (физическую) структуру
или представление произвольной сложности. Например, эллипсы и окружности, как
нам уже известно, могут вполне законно считаться скалярными значениями, хотя их
внутренняя структура может быть довольно сложной. Однако внутренняя структура
всегда скрыта от пользователя. Значит, когда мы говорим о наследовании (по край-
ней мере, в рамках нашей модели), мы не подразумеваем под этим наследование
структуры, поскольку, с точки зрения пользователя, никакой структуры для наследова-
ния просто нет! Другими словами, нас интересует так называемое наследование пове-
дения, а не наследование структуры. (Здесь подразумевается “поведение” операто-
ров, хотя, напомним, что в нашей модели наследуются и ограничения.)
Замечание. Безусловно, структурное наследование не исключается полностью.
Однако, по нашему мнению, оно является вопросом, относящимся к реализации, а
не к модели.
Подтаблицы и супертаблицы
К этому моменту читателю должно быть уже понятно, что обсуждаемая модель
наследования связана с так называемым наследованием доменов (напомним, что
домены и типы — это одно и то же). Однако, когда речь о возможностях наследо-
вания идет в реляционном контексте, большинство чаще всего полагает, что име-
ется в виду наследование таблиц. Например, в язык SQL3 включена поддержка
концепции “подтаблиц и супертаблиц”, в соответствии с которой определенная
таблица В может наследовать все столбцы какой-то другой таблицы А и, кроме то-
го, иметь собственные столбцы (см. приложение Б). Однако, на наш взгляд, идея
“подтаблиц и супертаблиц” — это совершенно особый феномен, который, воз-
можно, кому-то и интересен (хотя мы к этому относимся скептически [13.12]), но
не имеет ничего общего с собственно наследованием типов.
И последнее замечание. В действительности тема наследования типа относится к дан-
ным в целом, а не ограничивается лишь данными, хранимыми в базах данных. Поэтому из
соображений простоты в большинстве примеров этой главы будут использоваться локаль-
ные данные (обычные программные переменные и т.п.), а не данные базы данных.
19.2. Иерархия типов
Рассмотрим реальный пример, который будет использоваться до конца этой главы.
Он включает набор геометрических типов— PLANE_FIGURE (Плоская фигура), ELLIPSE
(Эллипс), CIRCLE (Окружность), POLYGON (Многоугольник) и т.д. Все используемые типы
упорядочены в виде так называемой иерархии типов или, в более общем случае, в виде
графа типов (рис. 19.1). Ниже приведены упрощенные определения для некоторых гео-
метрических типов, записанные на языке Tutorial D (и, в частности, ограничения типов).
TYPE PLANE_FIGURE ;
TYPE ELLIPSE POSSREP ( A LENGTH, В LENGTH, CTR POINT )
SUBTYPE-OF ( PLANE_FIGURE )
CONSTRAINT ( THE_A ( ELLIPSE ) > THE_B ( ELLIPSE ) ) ;
Глава 19. Наследование типов
729
TYPE CIRCLE POSSREP ( R LENGTH, CTR POINT )
SUBTYPE_OF ( ELLIPSE )
CONSTRAINT ( THE_A ( CIRCLE ) = THE_B ( CIRCLE ) ) ;
Исходя из этих определений система будет знать, что, например, тип CIRCLE — это
подтип типа ELLIPSE, и поэтому операторы и ограничения, которые, в общем, примени-
мы для эллипсов, в частности, применимы и для окружностей.
Необходимо кратко пояснить смысл спецификации POSSREP для типов ELLIPSE и
CIRCLE. Прежде всего, предполагается (для простоты), что эллипсы всегда ориенти-
рованы таким образом, что их большая ось располагается горизонтально, а мень-
шая — вертикально. Поэтому эллипсы могут быть представлены своими полуосями
а и Ь (и центром). Окружности же могут быть представлены радиусом г (и центром).
Также предполагается, как и в главе 8, что все эллипсы таковы, что большая полуось
а всегда не меньше, чем меньшая полуось Ь (т.е. эллипсы “низкие и широкие ”, а не
“высокие и тонкие”).
Ниже в сокращенном виде представлены определения для некоторых операторов,
связанных с указанными выше типами.
OPERATOR AREA ( Е ELLIPSE ) RETURNS ( AREA ) ;
/* "область"; обратите внимание, что имя AREA используется в обоих */
/* случаях: для самого оператора и для типа результата */
END OPERATOR ;
OPERATOR ТНЕ_А ( E ELLIPSE ) RETURNS ( LENGTH ) ;
/* "полуось a" */ ...;
END OPERATOR ;
OPERATOR THE_B ( E ELLIPSE ) RETURNS ( LENGTH ) ;
/* "полуось b" */ ... ;
END OPERATOR ;
OPERATOR THE_CTR ( E ELLIPSE ) RETURNS ( POINT ) ;
/* "центр" */ ... ;
END OPERATOR ;
730
Часть V. Дополнительные аспекты
OPERATOR THE_R ( C CIRCLE ) RETURNS ( LENGTH ) ;
/* "радиус" */ ... ;
END OPERATOR ;
Все операторы, кроме THE_R, применяются к значениям типа ELLIPSE и поэтому заве-
домо и к значениям типа CIRCLE. Оператор THE_R, напротив, применяется лишь к значе-
ниям типа CIRCLE.
Терминология
Прежде чем двигаться дальше, необходимо ввести еще несколько определений и тер-
минов, которые являются относительно простыми.
1. Супертип супертипа сам является супертипом. Например, тип POLYGON— это
супертип типа SQUARE (Квадрат).
2. Каждый тип является супертипом для самого себя. Например, тип ELLIPSE является
супертипом для типа ELLIPSE.
3. Если А— супертип типа В и типы А и В различны, то тип А— действительный
(proper) супертип типа В. Например, тип POLYGON — это действительный супертип
типа SQUARE.
Безусловно, аналогичные замечания справедливы и для подтипов.
4. Подтип подтипа сам является подтипом. Например, тип SQUARE — это подтип типа
POLYGON.
5. Каждый тип является подтипом для самого себя. Например, тип ELLIPSE является
подтипом типа ELLIPSE.
6. Если В — подтип типа А и типы В и А различны, то тип В — действительный под-
тип типа А. Например, тип SQUARE — это действительный подтип типа POLYGON.
Кроме того, дадим дополнительные определения.
7. Если А — супертип типа В и не существует типа С, который был бы действитель-
ным подтипом типа А и действительным супертипом типа В, то А — непосредст-
венный супертип типа В, а В — непосредственный подтип типа А. Например, тип
RECTANGLE — непосредственный супертип типа SQUARE, а тип SQUARE — непосред-
ственный подтип типа RECTANGLE. (Отметим, что в синтаксисе языка Tutorial D
ключевое слово SUBTYPE_OF означает именно “непосредственный подтип”.)
8. Корневой тип — это тип, не имеющий ни одного действительного супертипа. На-
пример, тип PLANE_FIGURE — это корневой тип.
Замечание. Это не означает, что может существовать только один корневой тип.
Однако, если имеются два или более корневых типа, всегда можно ввести тот или
иной вариант “системного” типа, который будет непосредственным супертипом
для всех остальных. Поэтому, не теряя общности, можно считать, что корневой тип
всегда один.
9. Листовой тип — это тип, не имеющий ни одного собственного подтипа. Напри-
мер, тип CIRCLE — это листовой тип.
Глава 19. Наследование типов
731
Замечание. Данное определение несколько упрощено, хотя и вполне удовлетвори-
тельно для наших целей (однако в случае множественного наследования его потре-
буется дополнить [3.3]).
10. Каждый действительный подтип имеет только один действительный супертип.
Замечание. Это явное следствие из сделанного выше допущения о том, что здесь
будет рассматриваться только одиночное наследование. Как уже отмечалось, все
возможные последствия отмены данного допущения (т.е. множественное наследо-
вание) подробно описаны в [3.3].
11. Если в иерархии существует по крайней мере один тип и не существует циклов
(т.е. последовательностей вида Tl, Т2, ТЗ, ..., Тп, таких, что тип Т1 — непо-
средственный подтип типа Т2, тип Т2 — непосредственный подтип типа ТЗ, ...
и Тп — непосредственный подтип типа Т1), то по крайней мере один тип дол-
жен быть корневым.
Замечание. На самом деле никаких циклов быть просто не может (почему?).
Предположение о несвязности
Для упрощения обсуждения примем еще одно допущение. Если Т1 и Т2 — различные
корневые типы или различные непосредственные подтипы некоторого супертипа
(откуда, в частности, следует, что ни один из них не является подтипом другого), то бу-
дем считать, что эти типы являются несвязанными, т.е. не существует значений, при-
надлежащих обоим типам, Т1 и Т2. Например, не существует значений, относящихся од-
новременно к типу ELLIPSE и к типу POLYGON.
Прямыми следствиями этого предположения являются приведенные ниже утверждения.
12. Различные иерархии типов являются несвязанными.
13. Различные листовые типы являются несвязанными.
14. Каждое значение относится ровно к одному конкретному типу. Например, неко-
торое значение может быть именно эллипсом, а не окружностью, т.е. конкретный
тип этого значения — ELLIPSE (в реальном мире некоторые эллипсы не являются
окружностями). В действительности вместо того, чтобы сказать, что конкретный
• тип некоторого значения v есть Т, будет лучше сказать, что множество типов, к ко-
торым относится значение v, — это множество всех супертипов типа Т (множество,
которое, конечно, включает и сам тип Т).
Одно из преимуществ принятия допущения о несвязности заключается в том, что ис-
ключается двусмысленность, которая может иметь место в противном случае. Предпо-
ложим, что некоторое значение v относится к двум типам, Т1 и Т2, причем ни один из
них не является подтипом другого. Далее предположим, что оператор Ор был определен
для типа Т1, а другой, с тем же именем Ор, — для типа Т22. Тогда применение оператора
Ор с аргументом v могло бы привести к неоднозначности.
2 Другими словами, оператор Ор — это полиморфный оператор. Кроме того, полиморфизм в
данном случае мог бы быть либо перегружаемым, либо включаемым. В разделе 19.3 этот вопрос
будет рассмотрен подробнее.
732
Часть V. Дополнительные аспекты
Замечание. Предположение о несвязности имеет смысл, поскольку мы ограничиваем-
ся рассмотрением лишь одиночного наследования, а для множественного наследования
это ограничение должно быть снято. Детальное обсуждение данного вопроса можно най-
ти все в той же работе [3.3].
Физическое представление
Хотя нас интересует, прежде всего, модель наследования, а не ее физическая реали-
зация, все же имеются вопросы, в которых необходимо разобраться подробнее, чтобы
яснее представлять концепцию наследования в целом. Вот один из таких вопросов.
15. Из того, что тип В является подтипом типа А, не следует, что реальное (скрытое)
представление значений типа В то же самое, что и значений типа А3. Например, эл-
липсы реально могут быть представлены их центрами и полуосями, в то время как
окружности — центрами и радиусами (хотя в общем случае не существует каких-
либо требований в отношении того, чтобы реальные представления были точно та-
кими, как вышеназванные).
Для изучения нескольких последующих разделов этот вопрос также будет важен.
19.3. Полиморфизм и заменимость
В этом разделе рассматриваются два ключевых понятия — полиморфизм и замени-
мость, которые вместе составляют основу для возможности повторного использования
кода, упоминавшейся в разделе 19.1. Сразу же отметим, что оба понятия в действитель-
ности представляют собой различные взгляды на одно и то же явление. Тем не менее
рассмотрим сначала понятие полиморфизма.
Полиморфизм
Из самого понятия наследования следует, что если Т' — это подтип типа Т, то все
операторы, которые применимы к значениям типа Т, применимы и к значениям типа Т'.
Например, если оператор AREA(e) является допустимым, где е— некоторый эллипс, то
оператор AREA]с), где с — некоторая окружность, также должен быть допустимым. За-
метим, что необходимо соблюдать аккуратность в отношении отличия параметров в
смысле их типов, объявленных в определении оператора, и соответствующих аргумен-
тов с действительными (конкретными) типами, использованных при вызове этого опе-
ратора. Например, оператор AREA определен с параметром, объявленным относящимся к
типу ELLIPSE (см. раздел 19.2), а действительный (конкретный) тип аргумента в обраще-
нии к оператору AREA( с) — имеющим тип CIRCLE.
3 Действительно, нет никакой логической необходимости даже в том, чтобы все значения
одного и того же типа имели одно и то же реальное представление. Например, одни точки мо-
гут быть представлены в декартовой системе координат, а другие — в полярной системе коор-
динат; одни значения температуры могут быть представлены в градусах по Цельсию, а дру-
гие — в градусах по Фаренгейту; одни целые числа могут быть представлены как десятичные, а
другие— как двоичные и т.д. (Конечно, системе должно быть известно, как преобразовывать
реальные представления во всех таких случаях, чтобы можно было правильно выполнять опера-
ции присвоения, сравнения и т.д.)
Глава 19. Наследование типов
733
Напомним, что эллипсы и окружности (по крайней мере, как мы их определили в раз-
деле 19.2) имеют различные представления.
TYPE ELLIPSE POSSREP ( A LENGTH, В LENGTH, CTR POINT )... ;
TYPE CIRCLE POSSREP ( R LENGTH, CTR POINT )... ;
Поэтому, возможно, могут существовать, хотя это и скрыто от пользователя, две раз-
личные версии оператора AREA: одна позволяет использовать представление ELLIPSE, а
другая — представление CIRCLE. Повторим, это возможно, но в этом может и не быть
необходимости. Например, код оператора для эллипса может выглядеть таким образом.
OPERATOR AREA ( Е ELLIPSE ) RETURNS ( AREA ) ;
RETURN ( 3.14159 * THE_A ( E ) * THE_B ( E ) ) ;
END OPERATOR ;
(Площадь эллипса равна лаЬ.) Этот код, очевидно, дает правильный результат и в том
случае, если вызывается для вычисления площади окружности, а не эллипса. Операторы
ТНЕ_А и ТНЕ_В возвращают радиус г. Однако программист, ответственный за определе-
ние типа CIRCLE, может по разным соображениям предпочесть реализацию отдельной
версии оператора AREA, которая предназначена конкретно для окружностей и в которой
вызывается оператор THE_R вместо операторов ТНЕ_А и ТНЕ_В.
Замечание. На самом деле может быть желательной реализация двух версий операто-
ра, даже если возможные представления одни и те же, в частности по соображениям эф-
фективности. Рассмотрим, например, многоугольники и прямоугольники. Алгоритм вы-
числения площади многоугольников годится, конечно, и для прямоугольников, но все-
таки для прямоугольников более эффективно вычислять площадь как произведение их
ширины и высоты.
Однако отметим, что код для реализации вычисления площади фигуры типа ELLIPSE
не будет пригодным для окружностей, если он написан в терминах реального представ-
ления типа ELLIPSE вместо возможного, поскольку реальные представления для типов
ELLIPSE и CIRCLE отличаются. И вообще, практика реализации операторов в терминах
реальных представлений — это не лучший подход. Кодируйте надежно!
В случае, если код оператора AREA, используемый для типа ELLIPSE, не нужно пере-
писывать заново для типа CIRCLE, можно говорить о повторном использовании кода (т.е.
кода, реализующего оператор AREA).
Замечание. В следующем подразделе речь пойдет о более важном виде повторного
использования.
С точки зрения модели, конечно, не имеет никакого значения, сколько версий оператора
AREA неявно реализовано (что касается пользователя, то для него есть просто один оператор
AREA, который применим для эллипсов, а следовательно, по определению — и для окруж-
ностей). Иными словами, с точки зрения модели оператор AREA— полиморфный, т.е. при
разных обращениях к нему он может принимать разные типы аргументов. Особо отметим,
что такой полиморфизм является логическим следствием наследования: если есть наследо-
вание, то должен быть и полиморфизм, в противном случае не будет и наследования!
Сама по себе идея полиморфизма не нова, как вы уже, по-видимому, поняли. Напри-
мер, в языке SQL есть полиморфные операторы (“=”, “| |” и многие другие); есть та-
кие операторы и в большинстве других языков программирования. В некоторых языках
734
Часть V. Дополнительные аспекты
пользователям даже разрешается вводить собственные полиморфные операторы. Напри-
мер, в языке PL/I эта возможность предоставляется с помощью GENERIC-функций. Одна-
ко наследования как такового ни в одном из данных примеров нет. Все это примеры так
называемого перегружаемого полиморфизма. Вид полиморфизма, демонстрируемый с
помощью оператора AREA, называют включаемым полиморфизмом на том основании, что
связь между, например, окружностями и эллипсами, по сути, равносильна включению
множеств [19.3]. По вполне понятным причинам далее в этой главе не уточненный до-
полнительно термин “полиморфизм” будет использоваться для включаемого полимор-
физма (кроме тех случаев, когда явным образом будет указано противное).
Замечание. Приведенные ниже дополнительные разъяснения помогут вам лучше по-
нять различия между перегружаемым и включаемым полиморфизмом.
Перегружаемый полиморфизм означает, что существует несколько различных
операторов с одним и тем же именем (и пользователь должен знать, что эти опе-
раторы, хотя и довольно похожие, на самом деле разные и имеют семантические
различия). Например, один оператор “+” служит для сложения целых чисел, дру-
гой оператор “+” — для сложения отношений и т.д.
Включаемый полиморфизм означает, что существует ровно один оператор, воз-
можно, с несколькими разными неявными реализациями (но пользователю нет не-
обходимости знать, существует одна или несколько версий его реализации: для
пользователя, повторяем, есть просто один оператор).
Полиморфизм в программировании
Рассмотрим следующий пример. Предположим, необходимо написать программу для
отображения некоторой диаграммы, составленной из квадратов, окружностей, эллипсов
и т.д. Без использования полиморфизма код мог бы быть подобен следующему.
FOR EACH х IN DIAGRAM
CASE ;
WHEN IS_SQUARE ( x ) THEN CALL DISPLAY_SQUARE ... ;
WHEN IS_CIRCLE ( X ) THEN CALL DISPLAY_CIRCLE ... ;
END CASE ;
(Здесь предполагается, что существуют операторы DISPLAY_SQUARE, DISPLAY_CIRCLE
и т.д., которые могут использоваться для проверки принадлежности данного значения
определенному типу.) Благодаря полиморфизму данный код становится гораздо проще и
существенно короче.
FOR EACH х IN DIAGRAM CALL DISPLAY ( x ) ;
Пояснения. В этом варианте оператор DISPLAY является полиморфным. Версия его
реализации, верно отрабатывающая значения типа Т, обычно определяется непосредст-
венно при объявлении типа Т и на данный момент должна быть известна системе. Во
время выполнения, когда системе нужно будет реализовать вызов оператора DISPLAY с
аргументом х, ей потребуется установить конкретный тип аргумента х, а затем вызвать
ту версию оператора DISPLAY, которая соответствует обнаруженному типу. Этот процесс
Глава 19. Наследование типов
735
называют связыванием во время выполнения или поздним связыванием4. Иначе гово-
ря, полиморфизм фактически подразумевает, что выражения и операторы CASE, которые
в противном случае должны были бы присутствовать в коде пользователя, будут скрыты
от него — система самостоятельно выполняет операции CASE, освобождая пользователя
от рутинной работы.
Перечислим некоторые следствия вышесказанного, в частности в отношении сопро-
вождения программ. Предположим, например, что новый тип TRIANGLE (Треугольник)
определен как еще один непосредственный подтип типа POLYGON, и, следовательно, ото-
бражаемая диаграмма теперь может содержать еще и треугольники. Если не использо-
вать полиморфизм, то в каждую программу, которая содержит выражения или операто-
ры CASE, подобные приведенному выше, потребуется добавить код следующего вида.
WHEN ISJTRIANGLE ( х ) THEN CALL DISPLAY_TRIANGLE ... ;
При использовании полиморфизма никакой модификации исходного кода вообще не
потребуется.
Исходя из примеров, подобных приведенному выше, полиморфизм иногда образно
характеризуют как метод, “позволяющий старому коду вызывать новый код”, т.е. благо-
даря ему программа Р фактически сможет вызывать определенную версию определенно-
го оператора, которой даже не существовало на момент написания этой программы Р.
Таким образом, здесь мы имеем другой и более важный случай— пример повторного
использования кода', одна и та же программа Р может быть пригодна для данных типа Т,
которого, повторяем, даже не существовало на момент написания программы Р.
Заменимость
Как указывалось ранее, понятие заменимости на самом деле является просто тем же
понятием полиморфизма, которое рассматривается с несколько иной точки зрения. Мы
уже видели, например, что если оператор AREA(e), где е— эллипс, является допусти-
мым, то оператор AREA(c), где с — окружность, также должен быть допустимым. Иными
словами, везде, где система подразумевает эллипс, его всегда можно заменить окружно-
стью. Или в общем виде это можно сформулировать так: везде, где системой подразуме-
вается некоторое значение типа Т, его всегда можно заменить значением типа Т', где
Т' — подтип типа Т. Это утверждение называют принципом заменимости значения.
Отметим, в частности, что из данного принципа следует, что если некоторое отноше-
ние г имеет атрибут А, объявленный как атрибут типа ELLIPSE, то некоторые значения
атрибута А могут иметь тип CIRCLE, а не именно тип ELLIPSE. Точно так, если некоторый
тип Т имеет возможное представление, которое включает какой-то компонент С, объяв-
ленный относящимся к типу ELLIPSE, то для некоторых значений v типа Т вызов опера-
тора ТНЕ_С( v) может возвращать значение типа CIRCLE, а не типа ELLIPSE.
И наконец заметим, что, поскольку заменимость — это просто полиморфизм в дру-
гом обличье, она также является логическим следствием наследования. Если есть насле-
дование, то должна быть и заменимость; в противном случае не будет и наследования.
4 Связывание во время выполнения ^относится, конечно, к вопросам реализации, а не к модели
Этот вопрос, в отличие от других вопросов реализации, рассматривается здесь дополнительно,
только для того, чтобы упростить правильное понимание концепции наследования в целом.
736
Часть V. Дополнительные аспекты
19.4. Переменные и операция присвоения
Предположим, что имеются две переменные, Е и С, с объявленными типами ELLIPSE и
CIRCLE соответственно.
VAR Е ELLIPSE ;
VAR С CIRCLE ;
Сначала проинициализируем переменную С значением некоторой окружности; ска-
жем для определенности, окружности с радиусом 3 и центром в начале координат.
С := CIRCLE ( LENGTH ( 3.0 ), POINT ( 0.0, 0.0 ) ) ;
В правой части оператора присвоения вызывается операция выбора типа CIRCLE.
(Напомним, что, как указывалось в главе 5, для каждого объявленного возможного пред-
ставления имеется соответствующий оператор выбора с тем же именем и с параметрами,
соответствующими компонентам рассматриваемого возможного представления. Опера-
тор выбора служит для того, чтобы пользователь мог указать или “выбрать” некоторое
значение заданного типа, предоставляя некоторое значение для каждого компонента рас-
сматриваемого возможного представления.)
Теперь рассмотрим следующее присвоение.
Е := С ;
Обычно при отсутствии подтипов и наследования операция присвоения требует, чтобы
переменная, указанная слева в операции присвоения, и значение, указанное в операции при-
своения выражением справа, были одного и того же типа (т.е. одного и того же объявленного
типа в случае переменной). Однако из принципа заменимости значения следует, что там, где
система предполагает некоторое значение типа ELLIPSE, его всегда можно заменить значени-
ем типа CIRCLE, так что показанный выше оператор присвоения является допустимым
(фактически это присвоение представляет собой полиморфный оператор). В результате вы-
полнения этого оператора окружность из переменной С будет скопирована в переменную Е и,
в частности, значение переменной Е после присвоения будет относиться к типу CIRCLE, а не
просто к типу ELLIPSE. Иными словами, можно сделать следующие утверждения.
Значения сохраняют свой наиболее конкретный тип при их присвоении пере-
менным, объявленным с менее конкретным типом. Преобразование типа при та-
ком присвоении не происходит (в нашем примере окружность не становится “просто
эллипсом”). Отметим, что для нас были бы нежелательны такие преобразования, по-
скольку это привело бы к потере наиболее характерного поведения значения и в на-
шем случае, например, могло бы означать, что после присвоения будет невозможно
получить радиус окружности, сохраненной как значение переменной Е.
Замечание. Ниже, в подразделе “Оператор TREAT DOWN”, обсуждается проце-
дура получения этого радиуса.
Из свойства заменимости следует, что переменная объявленного типа Т может
иметь значение, конкретный тип которого будет являться любым подтипом
типа Т. Поэтому нужно строго различать объявленный тип данной переменной и
ее реальный тип, т.е., говоря точнее, конкретный тип (текущее значение). В сле-
дующем подразделе мы возвратимся к этому важному вопросу.
Глава 19. Наследование типов
737
Чтобы продолжить рассмотрение примера, предположим, что у нас есть и другая пе-
ременная А с объявленным типом AREA.
VAR A AREA ;
Рассмотрим приведенное ниже присвоение.
А := AREA ( Е ) ;
В данном случае произойдет следующее.
Во-первых, во время компиляции система выполнит проверку типа в выражении
AREA(E). Проверка даст положительный результат, поскольку переменная Е имеет
объявленный тип ELLIPSE и единственный параметр оператора AREA также имеет
объявленный тип ELLIPSE (см. раздел 19.2).
Во-вторых, во время выполнения система обнаружит, что текущий конкретный
тип для переменной Е — CIRCLE, и поэтому вызовет ту версию оператора AREA, ко-
торая используется для работы с окружностями (иными словами, система осуще-
ствит связывание во время выполнения, что обсуждалось в предыдущем разделе).
Конечно, тот факт, что в данном случае при выполнении оператора AREA вызывается
версия, применяемая для окружностей, а не для эллипсов, должен быть скрыт от пользо-
вателя (для пользователя, повторим, существует единственный оператор AREA).
Скалярные переменные
Мы уже видели, что текущее значение v скалярной переменной V с объявленным ти-
пом Т может относиться к любому подтипу типа Т, равно как и к самому данному типу.
Поэтому можно представить модель V в виде упорядоченной тройки вида <DT,MST,v>.
Указанные параметры имеют следующий смысл.
DT — объявленный тип переменной V.
MST - текущий конкретный тип переменной V.
v - значение конкретного типа MST, а именно — текущее значение переменной V.
Мы используем обозначения DT(V), MST(V) и v(V) соответственно для компонентов
DT, MST и v модели скалярной переменной V. Отметим, что MST(V), конечно же, всегда
является подтипом, хотя и необязательно действительным подтипом наподобие DT(V); в
общем случае MST(V) и v(V) изменяются во времени; в действительности MST(V) следует
из v( V), поскольку каждое значение относится ровно к одному конкретному типу.
Эта модель скалярной переменной полезна, когда необходимо придерживаться точ-
ной семантики различных операций, включая, в частности, операции присвоения. Одна-
ко, прежде чем разбираться в этом вопросе, необходимо показать, как можно расширить
обозначения объявленного типа и текущего конкретного типа для применения к произ-
вольному выражению и, в частности, к скалярным переменным. Пусть X является таким
выражением. Тогда получим следующее.
Выражение X имеет объявленный тип, DT(X) (точнее говоря, его имеет результат
вычисления выражения X), производный очевидным образом от объявленных типов
операндов выражения X (включая объявленные типы результатов любых вызовов
операторов, содержащихся в выражении X) и известный во время компиляции.
738
Часть V. Дополнительные аспекты
Выражение X также имеет текущий конкретный тип, MST(X) (точнее говоря, его
имеет результат вычисления выражения X), производный очевидным образом от
текущих значений операндов выражения X (включая текущие значения результа-
тов любых вызовов операторов, содержащихся в выражении X) и в общем случае
неизвестный до времени выполнения.
Теперь можно точно описать выполнение операции присвоения. Рассмотрим сле-
дующую операцию.
V := X ;
Здесь V— скалярная переменная, а X— скалярное выражение. Тип DT(X) должен
быть подтипом типа DT (V), иначе присвоение недопустимо (эта проверка выполняется во
время компиляции). Если присвоение допустимо, то в результате тип MST(V) станет рав-
ным MST(X), а тип v(V) станет равным v(X).
По ходу заметим, что если текущий конкретный тип переменной V — это тип Т, то
каждый действительный супертип типа Т является также “текущим типом” переменной V.
Например, если переменная Е (объявленного типа ELLIPSE) имеет текущее значение, от-
носящееся к конкретному типу CIRCLE, то типы CIRCLE, ELLIPSE и PLANE_FIGURE все яв-
ляются “текущими типами” переменной Е. Однако выражение “текущий тип X” обычно
применяют, подразумевая, по крайней мере неформально, именно тип MST(X).
Пересмотр понятия заменимости
Рассмотрим следующее определение оператора.
OPERATOR COPY ( Е ELLIPSE ) RETURNS ( ELLIPSE ) ;
RETURNS ( E ) ;
END OPERATOR ;
Благодаря свойству заменимости оператор COPY может, очевидно, быть вызван с ар-
гументом конкретного типа (либо ELLIPSE, либо CIRCLE) и возвратит результат, относя-
щийся к тому же конкретному типу. Отсюда следует, что понятие заменимости имеет
еще одно следствие: если оператор Ор определен и его результат имеет объявленный
тип Т, то реальный результат выполнения оператора Ор может относиться к любому
подтипу типа Т (в общем случае). Другими словами, как ссылка на переменную объяв-
ленного типа Т может в действительности обозначать некоторое значение любого под-
типа типа Т (в общем случае), так и вызов оператора с объявленным типом результата Т
может фактически возвращать некоторое значение любого подтипа типа Т (опять-таки, в
общем случае).
Оператор TREAT DOWN
Еще раз рассмотрим пример, приведенный в начале данного раздела.
VAR Е ELLIPSE ;
VAR С CIRCLE ;
С := CIRCLE ( LENGTH ( 3.0 ), POINT ( 0.0, 0.0 ) ) ;
E := С ;
Глава 19. Наследование типов
739
Здесь тип MST(E) — CIRCLE. Предположим, что требуется получить радиус данной ок-
ружности и присвоить его некоторой переменной L. Можно попытаться сделать это так.
VAR L LENGTH ;
L := THE_R ( Е ) ; /* Ошибка времени компиляции - недопустимый тип!!! */
Однако, как явствует из комментария, этот код во время компиляции выдает сообщение
об ошибке о несоответствии типов. Точнее говоря, ошибка возникает из-за того, что опера-
тор THE_R (“радиус”) в правой части оператора присвоения требует, чтобы его аргумент от-
носился к типу CIRCLE, а объявленный тип его аргумента Е — ELLIPSE, а не CIRCLE.
Замечание. Если бы проверка во время компиляции не выполнялась и текущее значе-
ние Е во время выполнения оказалось бы эллипсом, а не окружностью, возникла бы
ошибка времени выполнения, что еще хуже. В нашем случае, безусловно, заранее извест-
но, что значение во время выполнения будет окружностью, и проблема состоит лишь в
том, что мы знаем об этом, а компилятор — нет.
Чтобы решить эту проблему, введем новый оператор, который неформально будем
называть TREAT DOWN (трактовать). Теперь можно корректно обратиться к оператору
THE_R и получить радиус окружности.
L := THE_R ( TREAT_DOWN_AS_CIRCLE ( Е ) ) ;
Выражение TREAT_DOWN_AS_CIRCLE(E) задается для того, чтобы для переменной Е в
данном случае был объявлен тип CIRCLE и проверка при компиляции завершилась ус-
пешно. При этом во время выполнения произойдет следующее.
Если текущее значение переменной Е относится к типу CIRCLE, значит, выражение
в целом корректно и возвращает радиус данной окружности. А точнее, обращение
к оператору TREAT DOWN дает результат (скажем, Z) с объявленным типом DT (Z),
равным CIRCLE, поскольку задано уточнение ..._AS_CIRCLE, текущим конкретным
типом MST(Z), равным типу MST(E), который в нашем примере имеет значение
CIRCLE, и текущим значением v(Z), равным v(E). В результате при вычислении
выражения THE_R(Z) будет получен требуемый радиус (который может быть при-
своен переменной L).
Однако если текущее значение переменной Е в действительности будет относиться
к типу ELLIPSE, а не к типу CIRCLE, то обращение к оператору TREAT DOWN приве-
дет к ошибке из-за несоответствия типа во время выполнения.
Общее назначение оператора TREAT DOWN — обеспечить, чтобы ошибки несоответ-
ствия типов во время выполнения могли произойти только в рамках вызова оператора
TREAT DOWN.
Замечание. Предположим, что тип CIRCLE, в свою очередь, имеет собственный под-
тип (скажем, O_CIRCLE, где O_CIRCLE — окружность, центр которой расположен в на-
чале координат).
TYPE O_CIRCLE POSSREP ( R LENGTH )
SUBTYPE_OF ( CIRCLE )
CONSTRAINT ( THE_CTR ( O_CIRCLE ) = POINT ( 0.0, 0.0 ) ) ;
740
Часть V. Дополнительные аспекты
Тогда текущее значение переменной Е в данное время может иметь конкретный тип
O_CIRCLE, а не просто CIRCLE. Рассмотрим вызов оператора TREAT DOWN в этом случае.
TREAT_DOWN_AS_CIRCLE ( Е )
Его выполнение завершится нормально, и будет выдан результат (скажем, Z) с объяв-
ленным типом DT (Z), равным CIRCLE, поскольку задано уточнение ..._AS_CIRCLE, теку-
щим конкретным типом MST(Z), равным типу O_CIRCLE, поскольку O_CIRCLE — это кон-
кретный тип переменной Е, и текущим значением v(Z), равным v(E). Короче говоря,
оператор TREAT DOWN всегда возвращает конкретный тип; он никогда не “повышает” тип,
чтобы сделать его менее конкретным, чем он был прежде.
Приведем более формальное изложение семантики вызова оператора
TREAT_DOWN_AS_T (X), где X — некоторое скалярное выражение. Во-первых, тип Т должен
быть подтипом типа DT (X) (это проверяется во время компиляции). Во-вторых, конкрет-
ный тип MST(X) должен быть подтипом типа Т (это проверяется во время выполнения).
Если данные условия удовлетворяются, то после обращения к оператору возвращается
результат Z с типом DT(Z), равным Т, типом MST(Z), равным типу MST(X), и текущим
значением v (Z), равным v (X).
Замечание. В [3.3] также определяется общая форма оператора TREAT DOWN, которая
допускает, чтобы один операнд “трактовался” как имеющий тип другого операнда вме-
сто некоторого явно указанного конкретного типа.
19.5. Специализация по ограничениям
Рассмотрим следующий пример вызова оператора выбора для типа ELLIPSE.
ELLIPSE ( LENGTH ( 5.0 ), LENGTH ( 5.0 ), POINT (...))
Это выражение возвращает эллипс с одинаковыми полуосями. Однако эллипс с оди-
наковыми полуосями фактически является окружностью. Следует ли из этого, что данное
выражение возвращает результат конкретного типа CIRCLE, а не ELLIPSE?
Вопросы, подобные приведенному выше, вызывали (и продолжают вызывать) в лите-
ратуре довольно бурные дискуссии. В нашей модели мы решили (после долгих разду-
мий), что лучше настаивать на том, чтобы выражение действительно возвращало резуль-
тат конкретного типа CIRCLE. В общем виде это можно сформулировать так: если тип Т'
является подтипом типа Т, а в результате вызова оператора выбора для типа Т возвраща-
ется значение, которое удовлетворяет ограничениям типа для типа Т', то (в нашей моде-
ли) результат вызова оператора выбора будет иметь тип Т'5.
Замечание. Предупредим, что лишь немногие существующие в настоящее время
коммерческие реализации, если таковые вообще имеются, реально работают указанным
образом, но мы считаем это просто одним из недостатков существующих систем. В [3.3]
показано, к каким результатам приводит отсутствие подобной функциональности — та-
кие системы вынуждены поддерживать “некруглые окружности”, “неквадратные квадра-
ты” и другие нелепости, чего не скажешь в случае нашего подхода.
5 В [3.3] для достижения подобного эффекта в определении типа Т предлагается использо-
вать фразу SPECIALIZE. Однако впоследствии мы пришли к заключению, что для достижения
желаемого результата никакого специального синтаксиса не требуется.
Глава 19. Наследование типов
741
Из вышесказанного следует (по крайней мере, в нашей модели), что нет значений
конкретного типа ELLIPSE, для которых бы выполнялось равенство а = Ь. Иначе говоря,
значения конкретного типа ELLIPSE относятся только к настоящим эллипсам, которые не
являются окружностями. В других же моделях наследования, напротив, значения кон-
кретного типа ELLIPSE соответствуют эллипсам, которые могут быть пли не быть ок-
ружностями. Мы считаем нашу модель более приемлемой в качестве “реальной модели”.
Идея, согласно которой, например, эллипс с полуосями а = Ь должен относиться к
типу CIRCLE, называют специализацией по ограничениям [3.3], хотя следует предупре-
дить, что некоторые авторы подразумевают под этим понятием совсем иное
(см., например, [19.7] и [19.11]).
Пересмотр оператора ТНЕ псевдопеременная
Напомним, что в главе 5 оператор ТН^_псевдопеременная использовался для обнов-
ления одного компонента переменной, оставляя при этом остальные компоненты неиз-
менными (здесь “компоненты”— это, конечно, компоненты некоторого возможного
представления, а не обязательно реального представления). Пусть, например, переменная
Е имеет объявленный тип ELLIPSE, и пусть текущим значением переменной Е будет эл-
липс с полуосями а = 5 и Ь = 3. Тогда в результате выполнения приведенного ниже
оператора присвоения значение длины оси Ь переменной Е изменится, а длина оси а и
положение центра останутся прежними.
THEJ3 ( Е ) := LENGTH ( 4.0 ) ;
Как отмечалось в разделе 8.2 главы 8, операторы ТНЕ_псевдопеременная не являются
логически необходимыми— фактически это просто удобные сокращения. Например,
предыдущая команда присвоения с оператором ТНЕ_В— это сокращенная запись для
следующего оператора присвоения6.
Е := ELLIPSE ( ТНЕ_А ( Е ), LENGTH ( 4.0 ), THE_CTR ( Е ) ) ;
Итак, рассмотрим приведенную ниже операцию присвоения.
THEJ3 ( Е ) := LENGTH ( 5.0 ) ;
По определению это присвоение эквивалентно следующему оператору.
Е := ELLIPSE ( ТНЕ_А ( Е ), LENGTH ( 5.0 ), THE_CTR ( Е ) ) ;
Следовательно, здесь должна вступить в силу специализация по ограничениям
(поскольку выражение в правой части операции присвоения возвращает эллипс с полу-
осями а = Ь). В результате после выполнения присвоения тип MST(E) должен быть
CIRCLE,а не ELLIPSE.
Рассмотрим еще одну операцию присвоения.
THEJ3 ( Е ) s= LENGTH ( 4.0 ) ;
6 Отметим, кстати, что оператор TREAT DOWN можно было бы использовать и как псевдо-
переменную [3.3], но, опять-таки, это будет просто сокращенная запись.
742
Часть V. Дополнительные аспекты
Теперь переменная Е содержит эллипс с полуосями а = 5 и Ь = 4 (как и предыду-
щий) и ее тип MST(E) снова становится ELLIPSE. Этот эффект мы называем обобщением
по ограничениям.
Замечание. Предположим (как и в конце раздела 19.4), что тип CIRCLE имеет собст-
венный подтип O_CIRCLE (где к типу O_CIRCLE относятся окружности, центр которых
расположен в начале координат).
TYPE O_CIRCLE POSSREP ( R LENGTH )
SUBTYPE_OF ( CIRCLE )
CONSTRAINT ( THE_CTR ( O_CIRCLE ) = POINT ( 0.0, 0.0 ) ) ;
Тогда текущее значение переменной Е в данное время может иметь конкретный тип
O_CIRCLE, а не просто CIRCLE. Предположим, что это так, и рассмотрим приведенную
ниже последовательность операций присвоения:7
ТНЕ_А ( Е ) := LENGTH ( 7.0 ) ;
ТНЕ_В ( Е ) := LENGTH ( 7.0 ) ;
В результате применения обобщения по ограничениям переменная Е после первой опе-
рации присвоения будет содержать “просто эллипс”. Однако после второй операции при-
своения она снова будет содержать окружность. Но будет ли это “окружность класса О”
или “просто окружность”? Очевидно, нам бы хотелось, чтобы это была именно
“окружность класса О”. На самом деле так оно и есть, потому что удовлетворяются ограни-
чения для типа O_CIRCLE (включая ограничения, наследуемые этим типом от типа CIRCLE).
Горизонтальное изменение типов
Снова будем полагать, что переменная Е относится к объявленному типу ELLIPSE. Мы
уже знаем, как можно изменить тип переменной Е, “понизив его” (например, если кон-
кретный тип переменной— ELLIPSE, то нам известно, как следует изменить значение
переменной, чтобы ее текущий конкретный тип стал CIRCLE). Мы также знаем, как мож-
но “повысить” тип переменной Е (например, если ее текущий конкретный тип — CIRCLE,
то нам известно, как следует изменить значение переменной, чтобы ее текущий конкрет-
ный тип стал ELLIPSE). Но как быть, если требуемое изменение типа оказывается
“горизонтальным”? Предположим, что мы расширили пример таким образом, что тип
ELLIPSE имеет два непосредственных подтипа, CIRCLE (Окружность) и NONCIRCLE (Не
окружность)8. Если не слишком вдаваться в детали, то ясно следующее.
Если текущее значение переменной Е принадлежит типу CIRCLE (т.е. а = Ь), то изме-
нение Е, после которого а > Ь, приведет к тому, что MST (Е) станет равным NONCIRCLE.
Если текущее значение переменной Е принадлежит типу NONCIRCLE (т.е. а > Ь), то из-
менение Е, после которого а = Ь, приведет к тому, что MST(E) станет равным CIRCLE.
Таким образом, специализация по ограничениям учитывает также “горизонтальное”
изменение типа.
7 Как указывалось в главе 8, в [3.3] предложена множественная форма операции присвоения, кото-
рая могла бы позволить выполнять последовательность операторов присвоения, как одну операцию.
8 В результате тип ELLIPSE становится фиктивным типом (см. раздел 19.7).
Глава 19. Наследование типов
743
Замечание. Пусть вас не удивляет отсутствие случая изменения переменной Е, в ре-
зультате которого а < Ь; такое изменение невозможно, поскольку оно нарушает ограни-
чение для типа ELLIPSE.
19.6. Операции сравнения
Предположим, имеются две обычные переменные, Е и С, с объявленными типами
ELLIPSE и CIRCLE соответственно. Предположим также, что текущее значение перемен-
ной С присваивается переменной Е.
Е := С ;
Тогда совершенно ясно, что если выполнить сравнение значений этих переменных, то
в результате должно быть получено значение истина.
Е = С
В общем виде соответствующее правило можно сформулировать так. Рассмотрим
операцию сравнения X = Y, где X и Y — скалярные выражения. Объявленный тип DT(X)
должен быть подтипом объявленного типа DT(Y) или наоборот, в противном случае
сравнение будет просто недопустимым (проверяется при компиляции). При допустимом
сравнении в результате получим значение истина, если конкретный тип MST(X) равен
конкретному типу MST(Y) и значение v(X) равно значению v(Y), в противном случае ре-
зультатом будет значение ложь. Отметим, в частности, что два значения нельзя сравнить
“на равенство”, если их конкретные типы различны.
Сравнения в реляционной алгебре
Сравнения на равенство явно или неявно используются во многих операциях реляци-
онной алгебры. И в случае поддержки механизма супертипов и подтипов, на первый
взгляд, может показаться, что некоторые из этих операций будут выполняться в проти-
воречии со здравым смыслом. Рассмотрим отношения RX и RY, представленные на
рис. 19.2. Обратите внимание, что единственный атрибут А в отношении RX имеет объяв-
ленный тип ELLIPSE, а атрибут А в отношении RY имеет объявленный тип CIRCLE. При-
мем, что значения вида Ei — это эллипсы, не являющиеся окружностями, а значения
Ci — это окружности. Конкретные типы для каждого значения выделены на рисунке
строчными буквами и курсивом.
RX А ! ELLIPSE RY A ! CIRCLE
Е1 ! ellipse C2 ' circle
С2 ' circle C3 ' circle
Рис. 19.2. Отношения RX и RY
А теперь рассмотрим результат операции соединения отношений RX и RY. Назовем это
отношение RJ (рис. 19.3). Очевидно, что каждое значение А в отношении RJ обязательно
будет иметь тип CIRCLE (поскольку любое значение А в отношении RX, конкретным ти-
744
Часть V. Дополнительные аспекты
пом которого является ELLIPSE, не может сравниваться с любым значением А в отноше-
нии RY). Поэтому можно подумать, что атрибут А в отношении RJ должен быть объявлен
с типом CIRCLE, а не с типом ELLIPSE. Но рассмотрим следующие рассуждения.
А ! ELLIPSE
С2 ! circle
Рис. 19.3. Соединение RJ отношений RX и RY
Поскольку в отношениях RX и RY только один атрибут А, выражение RX JOIN RY
упрощается до RX INTERSECT RY. Поэтому в данных условиях правило относи-
тельно объявленного типа результирующего атрибута в операции JOIN должно
быть сведено к аналогичному правилу для операции INTERSECT.
Выражение RX INTERSECT RY, в свою очередь, логически эквивалентно выражению
RX MINUS (RX MINUS RY). Пусть результатом второй операции, т.е. RX MINUS RY, бу-
дет RZ. Тогда очевидно следующее.
а) В общем случае второй операнд, т.е. RZ, будет включать некоторые значения А,
имеющие конкретный тип ELLIPSE, и поэтому объявленный тип атрибута А в RZ
должен быть ELLIPSE.
б) Таким образом, исходное выражение преобразуется в RX MINUS RZ, где объяв-
ленный тип атрибута А в обоих отношениях, RX и RZ, — ELLIPSE. Поэтому полу-
чаем окончательный результат, в котором объявленный тип атрибута А в RZ
также должен быть, очевидно, ELLIPSE.
Отсюда следует, что объявленный тип атрибута результата для операции
INTERSECT (а значит, и для JOIN) должен быть ELLIPSE, а не CIRCLE несмотря на
то, что каждое значение этого атрибута фактически должно иметь тип CIRCLE!
Теперь обратимся к реляционному оператору разности MINUS и прежде всего рассмот-
рим выражение RX MINUS RY. Очевидно, что некоторые значения атрибута А в результате
этой операции будут иметь тип ELLIPSE, а не CIRCLE, и поэтому объявленный тип А в таком
результате должен быть ELLIPSE. А какой тип должна иметь разность RY MINUS RX? Ясно,
что каждое значение в результате этой операции будет иметь тип CIRCLE, и поэтому можно
было бы предположить, что объявленный тип результата этой операции должен быть
CIRCLE, а не ELLIPSE. Однако обратите внимание, что выражение RX INTERSECT RY логиче-
ски эквивалентно не только выражению RX MINUS (RX MINUS RY), как было сказано выше,
но и выражению RY MINUS (RY MINUS RX). Исходя из этого легко понять, что если считать,
что в результате операции RY MINUS RX объявленный тип атрибута А будет CIRCLE, то мы
придем к противоречию. Отсюда следует, что объявленный тип атрибута А для операции
MINUS также должен быть ELLIPSE, а не CIRCLE, причем даже в случае операции
RY MINUS RX, где каждое значение должно иметь тип CIRCLE.
И наконец рассмотрим операцию объединения RX UNION RY. В данном случае ее ре-
зультат будет включать некоторые значения атрибута А, в общем случае — конкретного
типа ELLIPSE, и поэтому объявленный тип атрибута А в результирующем отношении этой
Глава 19. Наследование типов
145
операции должен быть ELLIPSE. Таким образом, и для операции объединения в резуль-
тирующем отношении объявленный тип атрибута А также должен быть ELLIPSE (но об
этом частном случае, в отличие от операций JOIN, INTERSECT и MINUS, вряд ли можно
сказать, что он интуитивно непредсказуем).
Теперь сформулируем общее правило.
Пусть гх и гу — отношения с общим атрибутом А, и пусть объявленные типы
атрибута А в отношениях гх и гу — соответственно DT(Ax) и DT(Ay). Рассмот-
рим соединение отношений гх и гу (обязательно по атрибуту А или по край-
ней мере с его участием). Объявленный тип DT(Ax) должен быть подтипом
типа DT(Ay) или наоборот, в противном случае выполнение соединения будет
недопустимо (проверяется во время компиляции). Если соединение допусти-
мо, можно считать, не теряя общности, что DT(Ay) — это подтип DT(Ax). То-
гда объявленный тип атрибута А в результирующем отношении операции бу-
дет DT(Ах).
Аналогичные соображения справедливы и для операций объединения, пересече-
ния и разности. В каждом случае соответствующие атрибуты операндов должны
быть такими, чтобы объявленный тип одного из них был подтипом объявленного
типа другого и объявленный тип соответствующего атрибута результата будет ме-
нее конкретным из двух объявленных типов (здесь под менее конкретным из
двух типов ТиТ', один из которых является подтипом другого, подразумевается
тот, который является супертипом).
Операторы проверки типа
В предыдущем разделе был приведен фрагмент кода, в котором применялись опера-
торы вида IS_SQUARE, IS_CIRCLE и т.д., используемые для проверки, относится ли ука-
занное значение к определенному типу. Рассмотрим эти операторы подробнее. Прежде
всего, будем считать, что определение некоторого типа Т приводит к автоматическому
определению оператора следующего вида.
IS_T ( X )
Здесь X— скалярное выражение, такое, что DT(X) является супертипом типа Т
(проверяется при компиляции). Вычисление выражения в целом дает значение истина,
если выражение X принадлежит типу Т, и значение ложь — в противном случае. Отме-
тим, что объявленный тип указанного аргумента X должен быть супертипом указанно-
го типа Т. Поэтому, например, если С — переменная объявленного типа CIRCLE, то
приведенное ниже выражение будет недопустимым (ошибка типа будет обнаружена
при компиляции).
IS_SQUARE ( С )
С другой стороны, оба следующих выражения допустимы и в результате дают значе-
ние истина.
IS CIRCLE ( С )
IS^ELLIPSE ( С )
746
Часть V. Дополнительные аспекты
Наконец, если Е — переменная объявленного типа ELLIPSE, но конкретный тип ее те-
кущего значения — некоторый подтип типа CIRCLE, то результат приведенного ниже вы-
ражения также будет истиной9.
IS_CIRCLE ( Е )
Мы также подразумеваем, что определение некоторого типа Т приводит к автомати-
ческому определению оператора следующего вида.
IS_MS_T ( X )
Здесь X — скалярное выражение, a DT(X) — супертип типа Т (опять же, это проверя-
ется при компиляции). Вычисление выражения в целом дает значение истина, если вы-
ражение X принадлежит типу Т, и значение ложь — в противном случае.
Замечание. Обратите внимание, что в то время как, например, оператор IS_ELLIPSE
на естественном языке можно лучше всего сформулировать как “является эллипсом”, то
оператор IS_MS_ELLIPSE на естественном языке лучше всего сформулировать как
“является конкретно эллипсом”.
Ниже приводится пример, включающий типы прямоугольника, квадрата и оператор
IS_MS_RECTANGLE.
VAR R RECTANGLE ;
IF IS_MS_RECTANGLE ( R )
THEN CALL ROTATE ( R ) ;
END IF ;
Интуитивно ясно, что оператор ROTATE (Вращать) — это оператор, с помощью кото-
рого заданный в качестве аргумента прямоугольник поворачивается на 90° вокруг цен-
тра, и что в подобном вращении нет никакого смысла, если рассматриваемый прямо-
угольник является квадратом.
Проверка типа также важна для реляционных операторов. Рассмотрим следующий
пример. Пусть переменная-отношение R имеет атрибут А объявленного типа ELLIPSE, и
допустим, что требуется получить такие кортежи переменной-отношения R, в которых
значение атрибута А в действительности является окружностью с радиусом, большим 2.
Можно попытаться решить эту задачу следующим образом.
R WHERE THE_R ( А ) > LENGTH ( 2.0 )
Однако это выражение будет квалифицировано как ошибочное при компиляции, по-
скольку для оператора THE_R требуется, чтобы аргумент имел тип CIRCLE, а атрибут А
имеет объявленный тип ELLIPSE, а не CIRCLE. (Если бы проверка при компиляции не вы-
полнялась, то ошибка была бы, конечно, обнаружена во время выполнения, причем это
произошло бы при обработке первого же из кортежей, который является просто эллип-
сом, а не окружностью.)
9 В [3.3] определяются обобщенные формы всех операторов "проверки типов", которые пред-
ставлены в этом подразделе. Например, обобщенная форма оператора IS Т проверяет, относится
ли один операнд к тому же типу, что и другой. Она может использоваться вместо оператора,
просто проверяющего, принадлежит ли переменная некоторому явно указанному типу.
Глава 19. Наследование типов
747
Очевидно, что необходимо как-то отсеять кортежи, в которых значение атрибута А
является просто эллипсом, и только после этого проверить условие, что радиус должен
быть больше 2. Рассмотрим теперь другую формулировку возможного решения.
R : IS_CIRCLE ( А ) WHERE THE_R ( А ) > LENGTH ( 2.0 )
Согласно этому выражению при выполнении операции должны возвращаться такие
кортежи, в которых значение атрибута А является окружностью с радиусом, большим 2.
Точнее, возвращается отношение, имеющее следующие свойства.
1. Оно имеет тот же заголовок, что и переменная-отношение R, но объявленный тип
атрибута А в нем — CIRCLE, а не ELLIPSE.
2. Его тело содержит те кортежи из переменной-отношения R, в которых значение ат-
рибута А будет иметь тип CIRCLE, т.е. будет окружностью и радиус этой окружно-
сти будет больше 2.
Другими словами, то, что мы только что рассмотрели, — это новый реляционный
оператор следующего вида.
R : IS_T ( А )
Здесь R — реляционное выражение, а А — атрибут отношения (скажем, г), обозна-
чаемого этим выражением. Объявленный тип DT(A) атрибута А должен быть супертипом
типа Т (проверяется при компиляции). Значение данного выражения в целом определяет
отношение со следующими свойствами.
1. Оно имеет тот же заголовок, что и отношение г, но объявленный тип атрибута А в
этом заголовке — Т.
2. Его тело содержит кортежи г, в которых атрибут А имеет значение типа Т, и, кроме
того, объявленный тип атрибута А в каждом из таких кортежей будет Т.
Аналогично определяется другой новый реляционный оператор следующего вида.
R : IS_MS_T ( А )
19.7. Операторы, версии и сигнатуры
Как утверждалось в разделе 19.3, любой заданный оператор может иметь много раз-
личных скрытых версий реализации (что известно также как явная специализация). Это
означает, что по мере продвижения в иерархии типов от некоторого супертипа Т к неко-
торому подтипу Т' необходимо, чтобы по крайней мере существовала возможность пе-
реписать реализацию (по разным соображениям) операторов типа Т для типа Т'. В каче-
стве примера рассмотрим следующий оператор MOVE.
OPERATOR MOVE ( Е ELLIPSE, R RECTANGLE ) RETURNS ( ELLIPSE )
VERSION ER_MOVE ;
RETURN ( ELLIPSE ( THE_A ( E ), THE_B ( E ), R_CTR ( R ) ) ;
END OPERATOR ;
748
Часть V. Дополнительные аспекты
Оператор MOVE выполняет “перемещение” эллипса Е таким образом, что его центр
помещается в центр прямоугольника R. Точнее говоря, он возвращает эллипс, который
в точности соответствует эллипсу, указанному его параметром Е, но центр возвращае-
мого эллипса совпадает с центром прямоугольника, заданного параметром R. Обратите
внимание, что фраза VERSION во второй строке определения вводит еще одно имя,
ER_MOVE, используемое именно для конкретной версии оператора MOVE (подробности
приводятся в следующем разделе). Кроме того, обратите внимание, что неявно пред-
полагается существование оператора R_CTR, который возвращает координаты центра
заданного прямоугольника.
А теперь предположим, что существует механизм явной специализации, т.е. требует-
ся определить другую версию оператора MOVE, выполняющего перемещение окружно-
стей, а не эллипсов10.
OPERATOR MOVE ( С CIRCLE, R RECTANGLE ) RETURNS ( CIRCLE )
VERSION CR_MOVE ;
RETURN ( CIRCLE ( THE_R ( C ), R_CTR ( R ) ) ;
END OPERATOR ;
Аналогично можно было бы получить явную специализацию для оператора MOVE
(скажем, ES_MOVE), если бы аргументы имели соответственно конкретные типы ELLIPSE и
SQUARE, а аргументы конкретных типов CIRCLE и SQUARE, например, — CS_MOVE.
Сигнатуры
Термин “сигнатура” означает сочетание имени некоторого оператора и типов опе-
рандов данного оператора. (Однако отметим, что у разных авторов и в разных языках
программирования в этот термин вкладывается несколько отличный смысл. Например,
иногда считается, что к сигнатуре относится тип результата, а иногда— имена операн-
дов и результата.) Поэтому необходимо уточнить различия между некоторыми указан-
ными ниже понятиями.
1. Различие между аргументами и параметрами.
2. Различие между объявляемыми типами и реальными (конкретными) типами.
3. Различие между операторами с точки зрения пользователей и операторами с точки
зрения системы (имеются в виду явные специализации или скрытые версии этих
операторов, как уже объяснялось выше).
Фактически мы различаем (хотя в литературе часто этого не делают!) по крайней ме-
ре три вида сигнатур, связанных с данным оператором Ор.
Одна сигнатура определения, которая состоит из имени оператора Ор вместе
с объявляемыми типами его параметров в том порядке, в котором параметры
указаны в предоставленном пользователю определении данного оператора.
10 В действительности очень мало смысла в определении новой явной версии именно для дан-
ного конкретного случая. (Почему?)
Глава 19. Наследование типов
749
Эта сигнатура соответствует оператору Ор с точки зрения пользователя. На-
пример, сигнатурой определения оператора MOVE будет просто сигнатура
MOVE (ELLIPSE, RECTANGLE)11.
Набор сигнатур версий, по одной для каждой явной специализации или версии
реализации оператора Ор, в каждой из которых содержатся имя оператора Ор вме-
сте с объявленными типами его параметров в том порядке, в котором эти пара-
метры определены для данной версии. Такие сигнатуры соответствуют различным
частям кода скрытой реализации оператора Ор. Например, сигнатурой версии
CR_MOVE оператора MOVE будет сигнатура MOVE (CIRCLE, RECTANGLE).
Набор сигнатур вызова, по одной для каждого возможного сочетания конкрет-
ных типов аргументов, в каждой из которых содержатся имя оператора Ор вместе
с соответствующим сочетанием конкретных типов аргументов, взятых по порядку.
Эти сигнатуры соответствуют различным возможным вариантам вызова операто-
ра Ор (в соотношении “один ко многим”, поскольку одна сигнатура может соот-
ветствовать многим различным вызовам). Пусть, например, переменные Е и R
имеют соответственно конкретные типы CIRCLE и SQUARE. Тогда для вызова опе-
ратора MOVE (Е, R) будет применяться сигнатура MOVE (CIRCLE, SQUARE).
Таким образом, различные сигнатуры вызова используют один и тот же оператор,
соответствующий, по крайней мере потенциально, различным версиям реализации
данного оператора (т.е. различным скрытым специализациям). Поэтому если не-
сколько версий “одного и того же оператора” выполняются фактически скрыто,
значит, выбор каждой версии, вызываемой в любом конкретном случае, будет за-
висеть от того, какая из версий сигнатуры “лучше подходит” в качестве допусти-
мой сигнатуры вызова. Процесс выбора наиболее подходящей версии, т.е. реше-
ние о том, какую версию необходимо вызывать, — это, конечно, процесс связыва-
ния во время выполнения, как уже отмечалось в разделе 19.3.
Кстати, отметим, что сигнатуры определения — это понятие собственно модели; сиг-
натуры версий — это понятие, относящееся лишь к реализации; сигнатуры вызова — это,
хотя в некотором смысле и понятие модели, на самом деле, как и понятие заменимости,
непосредственное логическое следствие, в первую очередь, основной идеи наследования
типов. В действительности тот факт, что возможно существование различных сигнатур
вызова, является просто частью концепции заменимости.
11 В [3.3] утверждается, что необходимо иметь возможность осуществлять разделение между
сигнатурой определения для данного оператора и определениями всех реализаций (версий) этого опе-
ратора. Основное назначение такого разделения — поддержка фиктивных типов (называемых также
"абстрактными” и “экземпляронеобразующими” типами, или иногда— просто “интерфейсами”),
т.е. типов, которые совсем не имеют конкретного типа какого-либо значения. Эти типы позволяют
определять операторы, которые применимы к нескольким различным обычным типам, являющимся
собственными подтипами фиктивного типа. Любой из таких операторов затем может быть явно
специализирован, т.е. может быть явно определена соответствующая версия оператора для каждого
из этих обычных подтипов. В контексте нашего примера тип PLANE FIGURE в указанном выше смыс-
ле может быть определен как фиктивный тип, после чего сигнатура определения оператора AREA
может быть сформулирована на уровне типа PLANE FIGURE, а явные версии реализации определены
для конкретных типов ELLIPSE, POLYGON и т.д. >
750
Часть V. Дополнительные аспекть1
Операторы чтения и обновления
До сих пор мы негласно подразумевали, что оператор MOVE предназначен лишь для
чтения. Однако давайте предположим, что он был определен как оператор обновления.
OPERATOR MOVE ( Е ELLIPSE, R RECTANGLE ) UPDATES ( E )
VERSION ER-MOVE ;
BEGIN ;
THE_CTR ( E ) := R_CTR ( R ) ;
END ;
END OPERATOR ;
(Напомним, что операторы чтения и обновления иногда называют соответственно на-
блюдателями и мутаторами. См. главу 5, в которой описаны различия между ними.)
Заметим, что в результате вызова этой версии оператора MOVE будет изменен его первый
аргумент (проще говоря, будет “изменен центр” заданного аргумента) и что обновление
выполняется независимо от того, к чему относится первый аргумент: к конкретному типу
ELLIPSE либо к конкретному типу CIRCLE. Иначе говоря, здесь явная специализация для ок-
ружностей не требуется12. Следовательно, преимущество операторов обновления в общем
случае заключается в том, что они могут освободить нас от необходимости явно записы-
вать определенные операторы специализации. В частности, обратите внимание на послед-
ствия в отношении сопровождения программ. Например, что случится, если впоследствии
потребуется ввести тип O_CIRCLE, являющийся подтипом типа CIRCLE?
Изменение семантики оператора
Как мы убедились, при прохождении вниз по иерархии типов всегда можно переопре-
делить реализацию оператора, что имеет одно важное следствие. Появляется вероятность
изменения семантики данного оператора. Например, может случиться так, что реализация
оператора AREA для типа CIRCLE реально возвращает, скажем, длину данной окружности
вместо площади. (Тщательное проектирование типов может помочь в некоторой степени
смягчить эту проблему. Например, если оператор AREA определен как возвращающий ре-
зультат типа AREA, то очевидно, что никакая реализация не сможет возвращать результат
типа LENGTH. Однако она может возвращать неверное значение площади!)
Более того, хотя это покажется неожиданным, можно даже утверждать (и на самом
деле так утверждают), что подобное изменение семантики может быть желательным.
Пусть, например, тип TOLL_HIGHWAY (Платная дорога)— собственный подтип типа
HIGHWAY (Дорога), и пусть оператор TRAVELJTIME (Время проезда) вычисляет время, за-
трачиваемое на движение между двумя заданными пунктами на указанной дороге. Для
платной дороги оно будет вычисляться по формуле (d/s) + (n*t), где d — расстояние,
s — скорость, п — количество касс для оплаты nt — время, затрачиваемое на оплату
проезда возле каждой кассы. Для бесплатной дороги время вычисляется, как частное d/s.
Приведем еще и обратный пример, т.е. пример, когда изменение семантики, безус-
ловно, нежелательно. Снова рассмотрим эллипсы и окружности. По-видимому, нам бы
хотелось, чтобы оператор AREA был определен таким образом, чтобы вычисление площа-
12 На самом деле явная специализация может быть вовсе не нужна, если она поддерживает-
ся ограничениями.
Глава 19. Наследование типов
751
ди данной окружности приводило к одному и тому же результату независимо от того,
рассматривается эта окружность именно как окружность или же как эллипс. Другими
словами, предположим, что перечисленные ниже события происходят в указанной по-
следовательности.
1. Определяются тип ELLIPSE и соответствующая версия оператора AREA. Предполо-
жим для простоты, что код оператора AREA не предусматривает использование ре-
ального представления для эллипсов.
2. Определяется тип CIRCLE как подтип типа ELLIPSE, но пока не определяется от-
дельная версия реализации оператора AREA для окружностей.
3. Вызывается оператор AREA для некоторой конкретной окружности с, чтобы полу-
чить результат, помещаемый, например, в переменную areal. Этот вызов исполь-
зует, естественно, версию оператора AREA для типа ELLIPSE.
4. Определяется собственная версия реализации оператора AREA для окружностей.
5. Вновь вызывается оператор AREA для той же окружности с, чтобы получить резуль-
тат, помещаемый, например, в переменную агеа2 (и на этот раз уже используется
версия оператора AREA для типа CIRCLE).
Нам бы хотелось, конечно, настаивать на том, что условие areal=area2 должно вы-
полняться. Но это возможное требование ничем не обеспечено, поскольку, как уже отме-
чалось, всегда существует вероятность того, что версия оператора AREA, реализованная
для окружностей, может возвращать, например, длину окружности вместо площади или
просто неверное значение площади круга.
Теперь возвратимся к примеру с оператором TRAVEL_TIME. На самом деле мы считаем
этот пример, как и другие подобные ему, крайне неубедительным, т.е. никак не убеж-
дающим нас в том, что в указанных ситуациях может быть желательным изменение се-
мантики оператора. Рассмотрим возможные последствия.
Если тип TOLL_HIGHWAY является настоящим подтипом типа HIGHWAY, это по
определению означает, что каждая отдельная платная дорога является факти-
чески дорогой.
Следовательно, некоторые дороги (т.е. некоторые значения типа HIGHWAY) являют-
ся действительно платными дорогами и имеют кассы для оплаты проезда. Тогда
тип HIGHWAY — это не “дороги без касс для оплаты проезда”, а “дороги с п кассами
для оплаты проезда” (где п может быть равно нулю).
Поэтому оператор TRAVEL_TIME для типа HIGHWAY не “вычисляет время проезда по
дорогам, на которых нет касс”, а “вычисляет время проезда d/s по некоторым до-
рогам, игнорируя кассы для оплаты проезда”.
Оператор TRAVEL_TIME для типа TOLL__HIGHWAY, напротив, “вычисляет время про-
езда (d/s) + (n*t) по некоторым дорогам, не игнорируя кассы для оплаты про-
езда”. Таким образом, эти два оператора TRAVEL TIME — логически разные опера-
торы. Путаница между двумя различными операторами возникает из-за того, что
им присвоили одно и то же имя. Фактически здесь мы имеем дело с перегружае-
мым, а не с включаемым полиморфизмом.
752
Часть V. Дополнительные аспекты
(В качестве дополнительного замечания отметим, что на практике недоразумения
возникают из-за того, что, как это ни печально, многие авторы используют термин пере-
гружаемый полиморфизм для включаемого полиморфизма.)
Подведем итоги. Мы по-прежнему не считаем изменение семантики оператора хорошей
идеей. Как мы убедились, данное требование не гарантируется, однако, безусловно, можно
определить нашу модель наследования таким образом (что мы и делаем), чтобы утвер-
ждать, что если семантика изменилась, то реализация нарушена, т.е. данная реализация
не является реализацией модели и последствия непредсказуемы. Обратите внимание, что
наша точка зрения на этот вопрос (т.е. то, что мы считаем недопустимыми такие измене-
ния) имеет еще одно преимущество: независимо от того, определены ли какие-либо явные
специализации данного оператора, представление пользователя остается одним и тем же.
Иначе говоря, существует оператор {отдельный оператор), называемый Ор; он применим
ко всем значениям аргументов некоторого конкретного типа Т и, следовательно, по опреде-
лению — к значениям аргумента любого собственного подтипа типа Т.
1 9.8. Является ли окружность эллипсом
До сих пор в этой главе подразумевалось, причем довольно обоснованно, что окруж-
ности являются эллипсами. Однако необходимо обратить ваше внимание, что в литера-
туре ведутся горячие споры по этому тривиальному вопросу. Рассмотрим наши обычные
переменные Е и С, имеющие объявленные типы ELLIPSE и CIRCLE соответственно. Пред-
положим, что эти переменные инициализированы следующим образом.
,Е := ELLIPSE ( LENGTH ( 5.0 ), LENGTH ( 3.0 ),
POINT ( 0.0, 0.0 )) ;
С := CIRCLE ( LENGTH ( 5.0 ), POINT ( 0.0, 0.0 )) ;
Обратите внимание, что оба оператора, ТНЕ_А(С) и ТНЕ_В(С), в данном случае имеют
значение 5.
Теперь можно выполнить операцию с переменной Е, например “обновить значение
длины полуоси а”.
ТНЕ_А ( Е ) := LENGTH ( 6.0 ) ;
А что будет, если попытаться выполнить аналогичную операцию с переменной С?
ТНЕ_А ( С ) := LENGTH ( 6.0 ) ;
Мы получим ошибку! Что же это за ошибка? Если бы обновление все-таки произош-
ло, то переменной С предстояло бы содержать “окружность”, которая нарушает ограни-
чение для окружностей, согласно которому а = b (значение а было бы равно б, а значе-
ние Ь, наверное, оставалось бы равным 5, поскольку мы его не изменяли). Иными слова-
ми, переменная С содержала бы “некруглую окружность” и, таким образом, было бы на-
рушено ограничение для типа CIRCLE.
Поскольку “некруглые окружности” противоречат логике и здравому смыслу, навер-
ное, разумно предложить, чтобы такое обновление было недопустимо. Также очевидно,
что достичь этого можно во время компиляции, отбрасывая все подобные операции. Для
этого достаточно определить задаваемую оператором присвоения операцию обновления
так, чтобы отдельное обращение к полуосям а и b для окружностей было синтаксически
Глава 19. Наследование типов
753
недопустимо. Иначе говоря, операторы присвоения ТНЕ_А и ТНЕ_В должны быть непри-
менимы для типа CIRCLE, а попытка подобного обновления должна приводить к ошибке
несовпадения типа во время компиляции.
Замечание. В действительности “очевидно”, что подобные операторы присвоения
должны быть синтаксически недопустимыми. Напомним, что присвоение значения с
помощью оператора У№_псевцопеременная— это просто сокращение. Поэтому, напри-
мер, попытка выполнения операции присвоения с оператором ТНЕ_А, показанная выше,
если бы она была допустима, могла бы быть переписана в таком виде.
С := CIRCLE (...);
Но вызов оператора выбора для типа CIRCLE в правой части оператора присвоения
должен был бы включать как аргумент типа ТНЕ_А с новой длиной полуоси а, равной
LENGTH(6,0). Однако оператор выбора для типа CIRCLE не принимает аргумента типа
ТНЕ_А— он принимает аргументы типов THE_R и THE_CTR. Таким образом, становится
ясно, что исходное присвоение должно быть недопустимым!
Об изменении семантики
Учитывая сказанное выше, сразу же отбросим предложение, суть которого заключа-
ется в попытке реанимировать идею, состоящую в том, что операторы присвоения ТНЕ_А
и ТНЕ_В должны быть допустимы для окружностей. Обычно предлагается, чтобы, напри-
мер, оператор ТНЕ_А был переопределен, иначе говоря, явно специализирован, для окруж-
ностей таким образом, чтобы иметь также побочный эффект присвоения соответствую-
щего значения для оператора ТНЕ_В, так что после обновления окружность по-прежнему
будет удовлетворять ограничению а = Ь. Мы отвергаем это предложение по крайней
мере по следующим трем причинам.
Во-первых, семантика присвоения для операторов ТНЕ_А и ТНЕ_В предписана на-
шей моделью наследования и не должна изменяться предлагаемым способом.
Во-вторых, даже если бы эта семантика присвоения не была предписана нашей
моделью, мы уже доказали, что изменение семантики оператора произвольным
образом — это, вообще говоря, не лучшая идея, а изменение семантики оператора
таким способом, который приводит к побочным эффектам— это еще худшая
идея. Лучше придерживаться общего принципа, который гласит, что операторы
должны делать то, что от них требуется, не больше и не меньше.
И, в-третьих, что наиболее важно, изменение семантики предлагаемым способом
не всегда возможно. Например, пусть тип ELLIPSE имеет другой непосредствен-
ный подтип NONCIRCLE, и пусть ограничение а > Ь применимо для подобных
“неокружностей”. Рассмотрим оператор присвоения ТНЕ_А для “неокружности”,
который устанавливал бы длину полуоси а равной Ь. Какое тогда должно быть со-
ответствующее семантическое переопределение для этого присвоения? Какой
именно побочный эффект был бы подходящим в этом случае?
Существует ли гибкая модель
Итак, мы остались на позициях, когда операторы присвоения ТНЕ_А и ТНЕ_В приме-
нимы для эллипсов вообще, но не применимы для окружностей в частности. Однако до-
полнительно необходимо учесть следующее.
754
Часть V. Дополнительные аспекты
1. Предполагается, что тип CIRCLE является подтипом типа ELLIPSE.
2. Предполагается, что утверждение, согласно которому тип CIRCLE является подти-
пом типа ELLIPSE, подразумевает, что операции, которые применимы к эллипсам
вообще, применимы (т.е. наследуются), в частности, и к окружностям.
3. Однако сейчас мы требуем, чтобы операции присвоения для операторов ТНЕ_А и
ТНЕ_В не наследовались.
Нет ли здесь противоречия? Что же произошло?
Прежде чем попытаться ответить на эти вопросы, подчеркнем серьезность данной про-
блемы. Если определенные операторы не наследуются типом CIRCLE от типа ELLIPSE, то
что мы имеем в виду, когда говорим, что окружность “является” эллипсом? Что означает
“наследование”, если некоторые операторы на самом деле не наследуются? Существует ли
действительно гибкая модель? Или же мы гоняемся за призраком, пытаясь его поймать?
Замечание. Некоторые авторы даже предлагают, причем вполне серьезно, применять
оператор присвоения ТНЕ_А как для окружностей, так и для эллипсов (для окружностей
обновляется радиус), а оператор присвоения ТНЕ_В — только для эллипсов. Но тогда тип
ELLIPSE фактически должен стать подтипом типа CIRCLE! Иными словами, мы получим
перевернутую иерархию типов. Но достаточно хоть на минуту задуматься, чтобы понять,
что это неудачная идея, в частности концепция заменимости в этом случае будет разру-
шена (что такое радиус обычного эллипса?).
Одних авторов рассуждения, аналогичные рассмотренным выше, приводят к выводу,
что гибкой модели наследования не существует (см. аннотацию к [19.1] в разделе
“Список литературы” в конце главы). Другие же авторы предлагают модели наследова-
ния, свойства которых нелогичны или весьма сомнительны. Например, в языке SQL3
разрешены “некруглые окружности” и другие нелепости. Как и язык SQL/92, язык SQL3
фактически не поддерживает ограничений типа, и это большое упущение, в первую оче-
редь, приводит к тому, что подобные нелепости имеют место (см. приложение Б).
Решение проблемы
Исходя из сказанного выше можно сделать вывод, что мы столкнулись со следующей
дилеммой.
Если окружности наследуют операторы присвоения ТНЕ_А и ТНЕ_В от эллипсов,
мы получим некруглые окружности.
Чтобы предотвратить возникновение некруглых окружностей, необходима под-
держка ограничений типа.
Но, если мы поддерживаем ограничения типа, операторы не могут быть на-
следуемыми.
Таким образом, в результате никакого наследования вовсе не может быть!
Как же решить эту дилемму?
Выход заключается (как это часто бывает) в необходимости осознать (и соответст-
венно действовать), что существует значительное логическое различие между значе-
ниями и переменными. Говоря “Каждая окружность является эллипсом”, мы подразу-
меваем, что значение каждой окружности является значением эллипса. Мы, безусловно,
не считаем при этом, что каждая переменная окружности является некоторой переменной
Глава 19. Наследование типов
755
эллипса (переменная объявленного типа CIRCLE не является переменной объявленного
типа ELLIPSE, и она не может содержать значение конкретного типа ELLIPSE). Иначе го-
воря, наследование применимо к значениям, а не к переменным. В случае эллипсов и
окружностей, например, можно сформулировать следующие правила.
Как уже отмечалось, значение каждой окружности является значением эллипса.
Следовательно, все операции, которые применимы к эллипсу, применимы и к ок-
ружности.
Единственное, чего мы не можем делать по отношению к любым значениям, —
это изменять их! Если бы это было возможно, они бы перестали быть значения-
ми. (Конечно, можно изменить “текущее значение” переменной путем ее обновле-
ния, но, повторяем, мы не можем изменить значение как таковое.)
Операции, которые применимы к значениям эллипса, все без исключения являются
операциями, определенными для типа ELLIPSE и предназначенными лишь для чтения.
А операции, которые обновляют переменные типа ELLIPSE, представляются, конечно,
операторами обновления, определенными для этого типа. Следовательно, наше утвер-
ждение, что “наследование применимо к значениям, а не к переменным”, точнее мож-
но сформулировать так.
Операторы, предназначенные лишь для чтения, наследуются с помощью
значений, в том числе с помощью текущих значений переменных. Поэтому
данные операторы могут быть применены без каких-либо нежелательных послед-
ствий к значениям, которые являются текущими значениями переменных.
Эта более точная формулировка также объясняет, почему концепции полиморфизма и
заменимости относятся именно к значениям, а не к переменным. Напомним, что в соот-
ветствии с концепцией заменимости везде, где системой должно обрабатываться значе-
ние типа Т, вместо него можно подставить значение типа Т', если тип Т' — подтип типа
Т. И именно этот принцип рассматривался, когда мы впервые представляли его как прин-
цип заменимости значений.
А как же тогда быть с операторами обновления? По определению такие операторы при-
менимы к переменным, но не к значениям. Можем ли мы тогда сказать, что операторы, кото-
рые применимы к переменным типа ELLIPSE, наследуются и переменными типа CIRCLE?
Нет, в целом, этого сказать нельзя. Например, оператор присвоения THE_CTR приме-
ним к переменным обоих объявленных типов, но, как мы уже убедились, оператор при-
своения ТНЕ_А к ним не применим. Таким образом, наследование не распространяется
на операторы обновления, точнее — наследуемые операторы обновления должны указы-
ваться явно. Рассмотрим пример.
Переменные объявленного типа ELLIPSE имеют операторы обновления MOVE
(версия обновления) и операторы присвоения ТНЕ_А, ТНЕ_В и THE_CTR.
Переменные объявленного типа CIRCLE имеют операторы обновления MOVE (версия
обновления) и операторы присвоения THE CTR и THE_R, но не ТНЕ_А и ТНЕ_В.
Замечание. Оператор MOVE рассматривался в предыдущем разделе.
Безусловно, в случае, когда наследуется и оператор обновления, мы имеем дело
с таким видом полиморфизма и таким видом заменимости, которые применимы
756
Часть И. Дополнительные аспекты
также к переменным, а не только к значениям. Например, если для версии обнов-
ления оператора MOVE в качестве аргумента может быть подставлена переменная
объявленного типа ELLIPSE, можно обратиться к этому оператору и с аргументом,
который представляет переменную объявленного типа CIRCLE. Следовательно,
можно (и нужно) говорить о принципе заменимости переменных, но при этом не
забывать, что данный принцип более ограниченный по сравнению с принципом
заменимости значений.
19.9. Пересмотр специализации ограничением
Продолжая начатое в предыдущем разделе обсуждение, рассмотрим небольшое, но
существенное дополнение. Обратимся к следующему примеру: “Пусть тип CIRCLE имеет
собственный подтип COLORED_CIRCLE (Цветная окружность)”. При этом подразумевается,
что “цветные окружности” являются частным случаем окружностей вообще. Примеры
такого рода весьма распространены в литературе. До сих пор мы говорили, что считаем
их крайне неубедительными и даже в некотором отношении вводящими в заблуждение.
Если говорить конкретно, то в данном случае, по нашему мнению, не имеет смысла рас-
сматривать цветные окружности как отдельный случай окружностей в целом. В конце
концов, “цветные окружности” по определению должны быть изображениями, напри-
мер, на экране дисплея, в то время как окружности вообще представляют собой геомет-
рические фигуры, а не изображения. Поэтому представляется более разумным считать
тип COLORED_CIRCLE не подтипом типа CIRCLE, а совершенно самостоятельным типом.
Такой независимый тип мог бы иметь возможное представление, в котором один ком-
понент имел бы тип CIRCLE, а другой — тип COLOR, но, повторяем, он ни в коем случае не
являлся бы подтипом типа CIRCLE.
Наследование возможных представлений
Рассмотрим конкретные аргументы в пользу нашей позиции по предыдущему вопро-
су. Возвратимся на некоторое время к уже знакомому нам примеру с эллипсами и ок-
ружностями. Еще раз приведем сокращенные определения типов.
TYPE ELLIPSE POSSREP ( A LENGTH, В LENGTH, CTR POINT ) ... ;
TYPE CIRCLE POSSREP ( R LENGTH, CTR POINT ) ... ;
Обратите внимание, что эллипсы и окружности имеют различные объявляемые
возможные представления. Однако возможное представление для эллипсов являет-
ся — обязательно, хотя и неявно — возможным представлением и для окружностей,
поскольку окружности являются эллипсами. Таким образом, окружности могут
“возможно, представляться” своими полуосями а и b (и центром), хотя на самом деле
их полуоси будут равны одному и тому же значению. Обратное, конечно, не верно, т.е.
возможное представление для окружностей не обязательно является возможным
представлением для эллипсов.
Отсюда следует, что мы могли бы считать возможные представления и ограничения до-
полнительными “свойствами”, которые наследуются окружностями от эллипсов или, гово-
<ь*
Глава 19. Наследование типов 757
ря в более общем плане, подтипами от супертипов13. Но (возвращаясь к окружностям и
цветным окружностям) очевидно, что объявленное возможное представление для типа
CIRCLE не является возможным представлением для типа COLORED_CIRCLE, поскольку в нем
нет ничего, что могло бы представлять цвет! Это говорит о том, что цветные окружности не
являются окружностями в том же смысле, что и, например, окружности и эллипсы.
Действительный смысл понятия подтипа
Следующий аргумент связан с предыдущим, но он логически является более строгим.
Не существует способа получения какой-либо цветной окружности из некоторой ок-
ружности посредством специализации по ограничениям.
Для объяснения этого утверждения опять возвратимся к примеру с эллипсами и ок-
ружностями. Ниже вновь приведены соответствующие определения типов.
TYPE ELLIPSE POSSREP ( A LENGTH, В LENGTH, CTR POINT ) ...
CONSTRAINT ( THE_A ( ELLIPSE ) > THE_B ( ELLIPSE ) ) ;
TYPE CIRCLE POSSREP ( R LENGTH, CTR POINT )
SUBTYPE_OF ( ELLIPSE )
CONSTRAINT ( THE_A ( CIRCLE ) = THE_B ( CIRCLE ) ) ;
Как мы видели ранее, фраза CONSTRAINT для типа CIRCLE гарантирует, что эллипс с
равными полуосями а = b будет автоматически специализирован к типу CIRCLE. Но в
случае цветных окружностей и вообще окружностей нет каких-либо предложений
CONSTRAINT, которые можно было бы записать в определении типа COLORED_CIRCLE и ко-
торые по аналогии со случаем с эллипсами и окружностями позволили бы специализиро-
вать некоторую окружность к типу COLORED_CIRCLE. Иными словами, нет ограничений
типа, которые можно было бы сформулировать таким образом, что если бы им удовле-
творяла некоторая данная окружность, то это прямо означало бы, что она в действитель-
ности является цветной.
Поэтому, опять же, представляется более разумным считать типы COLORED_CIRCLE и
CIRCLE совершенно разными типами и, в частности, считать, что тип COLORED_CIRCLE имеет
возможное представление, в котором один компонент относится к типу CIRCLE, а другой —
к типу COLOR. В последнем случае данному типу можно дать следующее определение.
TYPE COLORED_CIRCLE POSSREP ( CIR CIRCLE, COL COLOR ) ... ;
На самом деле мы здесь затронули вопрос, который можно поставить гораздо шире.
Фактически мы считаем, что определение подтипов должно всегда задаваться через спе-
циализацию по ограничениям! Наше предложение заключается в том, что, если тип
Мы не относим их подобным образом к нашей формальной модели, т.е. мы не относим к
модели такие наследуемые возможные представления, как объявленные, поскольку, если бы они
были объявлены, это привело бы к противоречию. А именно, если мы говорим, что тип CIRCLE
наследует возможное представление от типа ELLIPSE, то, как указано в [3.3], требовалось бы,
чтобы для переменной объявленного типа CIRCLE были допустимы операторы присвоения
THE А и THE В, а мы, безусловно, уже знаем, что это не так. Поэтому выражение "Тип CIRCLE
наследует возможное представление от типа ELLIPSE” — это лишь манера выражаться; данное
выражение не несет никакой формальной нагрузки.
758
Часть V. Дополнительные аспекты
Т' — это подтип типа Т, всегда должно существовать такое ограничение типа, что
если оно удовлетворяется некоторым заданным значением типа Т, то рассматри-
ваемое значение на самом деле является некоторым значением типа Т' (и должно
быть автоматически специализировано к типу Т'). Предположим, что Т и Т' — некото-
рые типы и Т' — подтип типа Т (не нарушая общности, можно считать, что Т' — это не-
посредственный подтип типа Т). Тогда будут справедливы следующие рассуждения.
Типы Т и Т' — это, по существу, множества (именованные множества значений),
и Т' является подмножеством Т.
Следовательно, типы Т и Т' оба имеют предикаты члена множества, т.е. такие
предикаты, что их значения являются членами данного множества (поэтому и зна-
чениями данного типа) тогда и только тогда, когда они удовлетворяют данному
предикату. Пусть такими предикатами будут соответственно Р и Р'.
Заметим, что предикат Р' по определению при вычислении дает значение истина
только для значений из числа действительно относящихся к типу Т. Поэтому он
может быть сформулирован не только в терминах значений типа Т',аив терми-
нах значений типа Т.
Именно такой предикат Р', сформулированный в терминах значений типа Т, и
является ограничением, которому должны удовлетворять значения типа Т,
чтобы фактически являться значениями типа Т'. Иными словами, некоторое
значение типа Т специализируется именно к типу Т', если оно удовлетворяет
ограничению Р'.
Поэтому мы утверждаем, что специализация по ограничениям является единствен-
ным концептуально допустимым средством определения подтипов. Вследствие этого мы
не признаем примеров, подобных предлагаемому, в котором тип COLORED_CIRCLE может
быть подтипом типа CIRCLE.
19.10. Резюме
В этой главе были кратко рассмотрены основные понятия модели наследования ти-
пов. Если тип В является подтипом типа А (или, что равносильно, если тип А является
супертипом типа В), то каждое значение типа В также является значением типа А. Поэто-
му операторы и ограничения, которые применимы к значениям типа А, будут также при-
менимы к значениям типа В. Но, кроме того, будут существовать операторы и ограниче-
ния, которые применимы к значениям типа В и не применимы к значениям, относящимся
лишь к типу А. Мы различили одиночное и множественное наследования (но обсуждали
только одиночное наследование), наследование скалярных значений, кортежей и от-
ношений (но рассматривали только наследование скалярных значений) и ввели понятие
иерархии типа. Мы также дали определение понятия действительного подтипа или
супертипа, непосредственного подтипа или супертипа, корневого и листового типов, а
также ввели допущение о несвязанности, согласно которому типы Т1 и Т2 не связаны,
если ни один из них не является подтипом другого. Вследствие этого допущения каждое
значение имеет уникальный конкретный тип (необязательно листовой).
Глава 19. Наследование типов
759
Далее речь шла о концепции включаемого полиморфизма и заменимости значений,
причем оба эти понятия логически следуют из основной концепции наследования. Мы
различали включаемый полиморфизм (который связан с наследованием) и перегру-
жаемый полиморфизм (который с наследованием не связан). Было показано, как благо-
даря связыванию во время выполнения включаемый полиморфизм может способст-
вовать повторному использованию кода.
Затем обсуждалось влияние наследования на операции присвоения. Основное сде-
ланное нами допущение заключается в том, что никаких преобразований типа не проис-
ходит, т.е. значения имеют свои конкретные типы и при их присвоении переменным с
менее конкретным объявленным типом. Поэтому переменная объявленного типа Т может
иметь значение, конкретный тип которого — один из подтипов типа Т. (Аналогично, ес-
ли оператор Ор определен с результатом объявленного типа Т, то результат реального
вызова оператора Ор может быть значением, конкретный тип которого— это один из
подтипов типа Т.) Следовательно, мы моделируем скалярную переменную V или в более
общем случае произвольное скалярное выражение, как упорядоченную тройку вида
<DT,MST,v>, где DT — объявленный тип, MST — текущий конкретный тип и v — текущее
значение. Дополнительно был введен оператор TREAT DOWN, позволяющий выполнять
операции, которые в противном случае приводили бы к ошибкам во время компиляции.
Это операции с выражениями, конкретный тип которых во время выполнения является
подтипом их объявленного типа. (Ошибки во время выполнения по-прежнему могут
иметь место, но теперь лишь в контексте оператора TREAT DOWN.)
После этого более детально были рассмотрены операторы выбора. Мы убедились,
что вызов оператора выбора для типа Т иногда дает в результате значение, тип которого
является собственным подтипом типа Т (по крайней мере в нашей модели, хотя в совре-
менных коммерческих продуктах этого обычно не наблюдается). Такой механизм полу-
чил название специализация по ограничениям. Также подробно обсуждались операто-
ры вида ИНЕ_псевдопеременная. Поскольку они представляют собой лишь сокращенную
запись, при выполнении оператора присвоения Т№_псевдопеременная могут существо-
вать как специализация по ограничениям, так и обобщение по ограничениям.
Далее рассматривались ситуации, возможные при выполнении сравнения значений
подтипов и супертипов, а также при выполнении реляционных операций соединения,
объединения, пересечения и разности. Дополнительно было введено несколько опера-
торов проверки типа: IS_T, IS_MS_T и т.д. Затем обсуждались вопросы, касающиеся
операторов только для чтения и операторов обновления, версий операторов и сиг-
натур операторов. При этом было указано, что возможность определять различные вер-
сии оператора открывает лазейку для изменения семантики данного оператора (но в
нашей модели такие изменения запрещены).
И наконец был рассмотрен дискуссионный вопрос “Являются ли окружности на са-
мом деле эллипсами?”. В результате было сделано заключение, что наследование при-
менимо к значениям, а не к переменным. Точнее, операторы, предназначенные только
для чтения (которые применимы к значениям), могут наследоваться все без исключения
и без каких-либо проблем, но операторы обновления (которые применимы к перемен-
ным) могут наследоваться лишь условно. (Наша модель не соответствует большинству
подходов. При иных подходах обычно требуется, чтобы операторы обновления наследо-
вались безусловно, зато после возникает множество проблем, когда приходится иметь
760
Часть И. Дополнительные аспекты
дело с “некруглыми окружностями” и другими подобными нелепостями.) Завершилось
обсуждение выводом, что специализация по ограничениям, на наш взгляд, — это един-
ственный допустимый способ определения подтипов.
Упражнения
19.1. Дайте определение следующим терминам.
заменимость
корневой тип
листовой тип
непосредственный подтип
нескалярный тип
обобщение по ограничениям
повторное использование кода
полиморфизм
связывание во время выполнения
сигнатура
скалярный тип
собственный подтип
специализация по ограничениям
фиктивный тип
19.2. Объясните действие оператора TREAT DOWN.
19.3. Каковы отличия между следующими понятиями.
а) аргумент и
б) объявленный тип и
в) включаемый полиморфизм и
г) сигнатура вызова и
д) оператор только чтения и
е) значение и
параметр
текущее конкретное значение
перегружаемый полиморфизм
сигнатура определения и сигнатура версии
оператор обновления
переменная
19.4. Используя иерархию типов, изображенную на рис. 19.1, рассмотрите значение е,
которое имеет тип ELLIPSE. Каков конкретный тип е — ELLIPSE или CIRCLE? Каков
наименее конкретный тип е?
19.5. Любая заданная иерархия типов включает несколько подыерархий, каждая из ко-
торых может рассматриваться как отдельная иерархия типов. Например, иерархия
типов, получаемая на рис. 19.1 посредством удаления типов PLANE_FIGURE, ELLIPSE
и CIRCLE (только), может считаться независимой. То же самое можно сказать об
иерархии, получаемой посредством удаления типов CIRCLE, SQUARE и RECTANGLE
(только). С другой стороны, иерархия, полученная посредством удаления типа
ELLIPSE (только), не может считаться единой иерархией типов (по крайней мере,
не может считаться иерархией, производной от иерархии, которая показана на
рис. 19.1), поскольку тип CIRCLE выпал из цепочки наследования, если судить по
исходной иерархии. Вопрос: “Сколько различных иерархий типов (в указанном
смысле) присутствует на рис. 19.1?”.
19.6. Используя синтаксис, кратко изложенный в этой главе, дайте определения типов
RECTANGLE (Прямоугольник) и SQUARE (Квадрат) (для простоты считайте, что все
прямоугольники имеют центр в начале координат, но их стороны необязательно
расположены только вертикально или горизонтально).
Глава 19. Наследование типов
761
19.7. Давая ответ к упр. 19.6, определите оператор поворота указанного прямоугольника
на 90° вокруг его центра. Также представьте явную специализацию этого операто-
ра для квадратов.
19.8. Повторим формулировку примера из раздела 19.6: “Пусть переменная-отношение R
имеет атрибут А объявленного типа ELLIPSE и требуется выбрать из нее такие кортежи,
в которых значение атрибута А в действительности является окружностью с радиусом,
большим 2”. Для данного запроса в разделе 19.6 была дана следующая формулировка.
R : IS_CIRCLE ( А ) WHERE THE_R ( А ) > LENGTH ( 2.0 )
а) Почему нельзя просто поместить выражение проверки типа в предложение
WHERE, например так, как показано ниже?
R WHERE IS_CIRCLE ( А ) AND THE_R ( А ) > LENGTH ( 2.0 )
б) Вот еще один пример возможной формулировки запроса.
R WHERE CASE
WHEN IS_CIRCLE ( A ) THEN
THE_R ( A j ( TREAT_DOWN_AS_CIRCLE ( A ) )
> LENGTH ( 2.0 )
WHEN NOT ( IS_CIRCLE ( A ) ) THEN FALSE
END CASE
Верна ли эта формулировка? Если нет, то почему?
19.9. В [3.3] предлагается поддержка реляционных выражений следующего вида.
R TREAT_DOWN_AS_T ( А )
Здесь R — реляционное выражение, А — атрибут отношения (скажем, г), обозна-
чаемый этим выражением, и Т — некоторый тип. Объявленный тип DT (А) атрибута
А должен быть супертипом типа Т (проверка типа во время компиляции). Значение
всего выражения определяется как отношение со следующими свойствами.
а) Его заголовок такой же, как заголовок отношения г, но тип атрибута А в нем — Т.
б) Его тело составляют те же кортежи, что в отношении г, но значение атрибута А
в каждом из таких кортежей должно рассматриваться как относящееся к типу Т.
Напомним, что приведенный оператор TREAT DOWN является просто сокращением.
Но сокращением чего именно?
19.10. Выражение вида R: IS_T(A) также является сокращением. Сокращением чего именно?
Список литературы
19.1. Atkinson М.Р. et al. The Object-Oriented Database System Manifesto // Proc. First
International Conference on Deductive and Object-Oriented Databases. — Kyoto, Japan,
1989. New York, N.Y.: Elsevier Science. — 1990.
Относительно отсутствия согласия (как уже отмечалось в разделе 19.1) по вопросу,
что должна собой представлять настоящая модель наследования, авторы настоя-
щей статьи высказываются так: “Имеется по крайней мере четыре типа наследова-
ния: наследование заменимости, включаемое наследование, наследование ограни-
762
Часть V. Дополнительные аспекты
чений и наследование специализации... Различные уровни этих четырех типов на-
следования предоставляются существующими системами и прототипами, и мы не
предписываем конкретный стиль наследования”.
Далее приводится еще несколько цитат, которые дополняют ту же основную мысль.
В [19.4] Кливленд (Cleaveland) пишет: “[Наследование может] основываться на
[множестве] различных критериев, и не существует какого-либо общепринятого
стандартного определения”. Он также предлагает восемь возможных интерпре-
таций. (Мейер в [19.8] дает двенадцать.)
Баклавски (Baclawski) и Индурхия (Indurkhya) в [19.2] пишут: “Язык програм-
мирования [просто] предоставляет множество механизмов [наследования]. По-
ка эти механизмы, безусловно, ограничивают и возможности языка, и возмож-
ные представления наследования... они не допускают для самих себя некоторые
представления наследования. Классы, специализации, обобщения и наследова-
ние— это только понятия, и... они не имеют всеобщего объективного значе-
ния... Отсюда следует, что то, как наследование будет включено в конкретную
систему, зависит от проектировщиков [данной] системы; именно это составляет
стратегию разработки, которая должна быть реализована с помощью доступных
механизмов”. Другими словами, нет никакой модели!
19.2. Baclawski К., Indurkhya В. Technical Correspondence И CACM. — September,
1994. —37, №9.
19.3. Cardelli L., Wegner P. On Understanding Types, Data Abstraction, and Polymorphism H
ACM Comp. Surv. — December, 1985. — 17, № 4.
19.4. Cleaveland G.J. An Introduction to Data Types. — Reading, Mass.: Addison-Wesley, 1986.
19.5. Date C.J. Серия статей по наследованию типов на Web-узле DBP&D
ww.dbpd.com. — 1999.
Статьи публиковались с февраля 1999 года. Это расширенная учебная разработка
(с историческими примечаниями) модели наследования, описанной в настоящей
главе и определенной более формально в [3.3].
19.6. Date C.J., Darwen Н. Toward a Model of Type Inheritance // CACM. — December,
1998, —41, № 12.
Короткая заметка, содержащая перечень основных особенностей нашей модели
наследования.
19.7. Mattos N., DeMichiel L.G. Recent Design Trade-Offs in SQL3 // ACM SIGMOD.—
December, 1994. — Record 23, № 4.
В статье обосновывается решение разработчиков не поддерживать в SQL3 ограни-
чения типа (это обоснование базируется на аргументе, который был выдвинут ра-
нее Здоником (Zdonik) и Мейером (Maier) в [19.11]). Однако мы не согласны с та-
ким обоснованием. Фундаментальная проблема заключается в том, что в нем не-
верно различаются значения и переменные (см. упр. 19.3).
19.8. Meyer В. The Many Faces of Inheritance: A Taxonomy of Taxonomy // IEEE
Computer. — May, 1996. — 29, № 5.
19.9. Rumbauch J. A Matter of Intent: How to Define Subclasses // Journal of Object-Oriented
Programming. — September, 1996.
Глава 19. Наследование типов
763
Как указывалось в разделе 19.9, мы придерживаемся мнения, что специализа-
ция ограничением — это единственный логически допустимый способ опреде-
ления подтипов. Поэтому интересно отметить, что объектный мир (по крайней
мере, часть его обитателей) занимает прямо противоположную позицию. Про-
цитируем автора настоящей публикации: “Класс SQUARE — это подкласс класса
RECTANGLE? ...Растяжение прямоугольника по оси X вполне допустимо. Но ес-
ли то же самое сделать с квадратом, он перестанет быть квадратом. Концепту-
ально это не обязательно плохо. Когда вы вытягиваете квадрат, получается
прямоугольник... Но... большинство объектно-ориентированных языков не до-
пускают, чтобы объекты меняли свой класс... Поэтому предлагается следую-
щий принцип проектирования для систем классификации: Подкласс не должен
быть определен через ограничения суперкласса''.
Замечание. Как объясняется в главе 24, в объектном мире часто используется тер-
мин класс для понятия, которое мы называем типом.
Нас поражает, что автор принимает указанную позицию просто потому, что объ-
ектно-ориентированные языки “не допускают, чтобы объекты меняли свой класс”.
Мы бы скорее побеспокоились о получении, прежде всего, правильной модели, а
не о соответствии конкретной реализации.
19.10. TaivaIsaari A. On the Notion of Inheritance // ACM Comp. Surv. — September,
1996, —28, №3.
19.11. Zdonik S.B., Maier D. Fundamentals of Object-Oriented Databases в [24.52]).
Ответы к некоторым упражнениям
19.3. Рассмотрим лишь п. е (значение и переменная), поскольку это фундаментальные
понятия и они еще явно нигде в книге не рассматривались. (Следующие определе-
ния взяты из [3.3].)
Значение— это “отдельная константа” (например, отдельная константа “3”).
Значение не имеет никакого места расположения во времени или пространст-
ве. Однако значения могут иметь в памяти некоторые кодированные представле-
ния, и такие представления, конечно, имеют место расположения во времени и
пространстве (см. следующий абзац). Отметим, что по определению значение не
может быть изменено. Иначе, если бы это было возможно, после такого изме-
нения оно бы не было больше таким значением (вообще).
Переменная — это хранитель кодированного представления некоторого значе-
ния. Она имеет место расположения во времени и пространстве. Также перемен-
ные в отличие от значений, конечно же, могут быть обновлены, т.е. текущее зна-
чение переменной может быть заменено другим значением, возможно, отличным
от предыдущего. (Безусловно, после выполнения операции обновления данная
переменная остается той же переменной.)
Кстати заметим следующее: важно понимать, что значение не обязательно должно
быть таким же простым, как целое число “3”. Наоборот, значения могут быть сколь
угодно сложными. Например, значение может быть массивом, стеком, списком,
отношением, геометрической точкой, эллипсом, Х-лучом, документом, отпечатком
пальца и т.д. Аналогичное замечание, конечно, справедливо и для переменных.
764
Часть V. Дополнительные аспекты
19.4. Наименее конкретный тип любого значения любого типа, показанный на
рис. 19.1, — это, конечно, PLANE_FIGURE.
19.5. Всего 22 иерархии. В их число включена и пустая иерархия.
19.6. Исходя из того, что все прямоугольники имеют центр в начале координат, каждый
заданный прямоугольник может однозначно идентифицироваться любыми двумя
смежными вершинами (скажем, А и В), а заданный квадрат может однозначно
идентифицироваться любой отдельной вершиной (скажем, А). Чтобы определиться
более точно, будем считать, что А — вершина в правом верхнем квадранте плоско-
сти (х > 0, у > 0), а В— вершина в ее правом нижнем квадранте (х > 0, у < 0).
Тогда типы RECTANGLE и SQUARE можно определить следующим образом.
TYPE RECTANGLE POSSREP ( A POINT, В POINT ) ... ;/
TYPE SQUARE POSSREP ( A POINT )
CONSTRAINT ( THE_X ( THE_A
- THE_Y ( THE_B
THE_Y ( THE_A
THE_X ( THE В
( SQUARE ) ) =
( SQUARE ) ) AND
( SQUARE ) ) =
( SQUARE ) ) ) ;
19.7. Приведенные ниже операторы являются операторами обновления. В качестве
вспомогательного упражнения приведите некоторые аналоги этих операторов,
предназначенных только для чтения.
OPERATOR ROTATE ( R RECTANGLE ) UPDATES ( R )
VERSION ROTATE_RECTANGLE ;
BEGIN ;
VAR P POINT ;
VAR Q POINT ;
P := THE_A ( R ) ;
Q := THE_B ( R ) ;
THE_X ( THE_A ( R ) ) := THE_Y ( Q ) ;
THE_Y ( THE_A ( R ) ) := THE_X ( Q ) ;
THE_X ( THE_B ( R ) ) := THE_Y ( P ) ;
THE_Y ( THE_B ( R j ) := THE_X ( P ) ;
RETURN ;
END ;
END OPERATOR ;
OPERATOR ROTATE ( S SQUARE ) UPDATES ( S )
VERSION ROTATE_SQUARE ;
RETURN ;
END OPERATOR ;
19.8.
а) Указанное выражение приведет к ошибке несоответствия типа во время компи-
ляции, поскольку для оператора THE_R требуется, чтобы аргумент имел тип
CIRCLE, а объявленный тип атрибута А был ELLIPSE, а не CIRCLE. (Конечно, если
проверка типа во время компиляции будет отсутствовать, мы получим ошибку
Глава 19. Наследование типов
765
типа во время выполнения, как только встретится кортеж, в котором значение
атрибута А будет просто эллипсом, а не окружностью.)
б) Указанное выражение допустимо, однако оно дает в результате отношение с
таким же заголовком, как и заголовок переменной-отношения R, но в этом от-
ношении объявленный тип атрибута А — CIRCLE, а не ELLIPSE.
19.9. Выражение служит сокращенной записью выражения такого вида.
( ( EXTEND ( R ) ADD ( TREAT_DOWN_AS_T ( А ) ) AS А' )
{ ALL BUT A } RENAME A' AS A
Здесь A' — произвольное имя, не появляющееся в качестве имени атрибута в ре-
зультате вычисления реляционного выражения R.
19.10. Выражение служит сокращенной записью выражения такого вида.
( R WHERE IS_T ( А ) ) TREAT_DOWN_AS_T ( А )
Более того, это последнее выражение само является сокращенной записью для бо-
лее длинного выражения, что было показано в ответе к упр. 19.9.
766
Часть V. Дополнительные аспекты
Глава 20
Распределенные базы
данных
20.1. Введение
В конце главы 2 уже затрагивалась тема распределенных баз данных. При этом ука-
зывалось, что “полная поддержка распределенных баз данных означает, что отдельное
приложение может “прозрачно” обрабатывать данные, распределенные между множест-
вом различных баз данных, управление которыми осуществляют разные СУБД, рабо-
тающие на соединенных коммуникационными сетями машинах разных типов с различ-
ными операционными системами. Здесь понятие “прозрачно” означает, что приложение
выполняет обработку данных с логической точки зрения так, как будто управление дан-
ными полностью осуществляется одной СУБД, работающей на единственной машине”.
В этой главе мы поговорим о распределенных базах данных подробнее, а именно — бо-
лее точно определим, что такое распределенная база данных, почему такие базы данных
играют все более важную роль и какие технические проблемы существуют в области
распределенных баз данных.
Кроме того, в главе 2 обсуждались системы “клиент/сервер”, которые можно рас-
сматривать как простой частный случай распределенных систем вообще. Системы
“клиент/сервер” будут рассмотрены в разделе 20.5.
Общий план данной главы приведен в конце следующего раздела.
20.2. Предварительные сведения
Начнем с рабочих определений, которые на этом этапе неизбежно будут не со-
всем точны.
Система распределенных баз данных состоит из набора узлов (sites), связанных
коммуникационной сетью, в которой:
а) каждый узел — это полноценная СУБД сама по себе, но
б) узлы взаимодействуют между собой таким образом, что пользователь любого
из них может получить доступ к любым данным в сети так, как будто они нахо-
дятся на его собственном узле.
Из этого определения следует, что так называемая “распределенная база данных” в
действительности является виртуальной базой данных, компоненты которой физически
хранятся в нескольких “реальных” базах данных на нескольких различных узлах (в сущ-
ности, являясь логическим объединением этих реальных баз данных). Пример подобной
структуры показан на рис. 20.1.
Глава 20. Распределенные базы данных 161
Рис. 20.1. Пример типичной системы распределенной базы данных
Еще раз отметим, что каждый узел сам по себе является системой базы дан-
ных. Иначе говоря, на каждом узле есть собственные локальные “реальные” базы
данных, собственные локальные пользователи, собственные локальные СУБД и про-
граммное обеспечение управления транзакциями (включая собственные локальные
системы блокировки, ведения журналов, восстановления и т.д.) и собственный ло-
кальный менеджер передачи данных. В частности, любой пользователь может вы-
полнить операции над данными на своем локальном узле точно так же, как если бы
этот узел вовсе не входил в распределенную систему (по крайней мере, так должно
быть). Распределенную систему баз данных можно рассматривать как некоторое
партнерство между отдельными локальными СУБД на отдельных локальных узлах.
Новый программный компонент на каждом узле — логическое расширение локаль-
ной СУБД — предоставляет необходимые функциональные возможности для орга-
низации подобного партнерства. Именно этот компонент вместе с существующими
СУБД составляет то, что обычно называется распределенной системой управле-
ния базами данных (РСУБД).
768
Часть V. Дополнительные аспекты
Чаще всего предполагается, что узлы физически распределены (а возможно, и гео-
графически, как показано на рис. 20.1), хотя в действительности достаточно того, чтобы
они были распределены логически. Два “узла” могут даже сосуществовать на одной и той
же машине (в особенностей на начальном этапе тестирования). Главная цель создания
распределенных систем со временем изменялась. В ранних исследованиях в основном
предполагалась географическая распределенность, но в большинстве первых коммерче-
ских реализаций предполагалось локальное распределение, когда несколько “узлов” раз-
мещалось в одном здании и соединялось с помощью локальной сети (ЛВС). Однако поз-
же стремительное распространение глобальных сетей (ГВС) снова пробудило интерес к
возможности географического распределения. В любом случае это не имеет большого
значения с точки зрения системы баз данных — решать, в основном, требуется одни и те
же технические (связанные с базами данных) проблемы. Поэтому в настоящей главе мы
можем обоснованно рассматривать представленную на рис 20.1 систему как типичного
представителя распределенных систем.
Замечание. Для упрощения изложения будем предполагать, если нет соответствую-
щего явного указания, что система однородна. Однородна в том смысле, что на каждом
узле работает некоторая копия одной и той же СУБД. Будем называть это предположе-
нием о строгой однородности. Возможности и особенности неоднородных систем будут
проанализированы в разделе 20.6.
Преимущества
Зачем нужны распределенные базы данных? Основная причина заключается в том,
что предприятия обычно уже распределены. Распределены по крайней мере логически,
т.е. разделены на подразделения, отделы, рабочие группы и т.д. Очень часто они распре-
делены и физически, т.е. разделены на заводы, фабрики, лаборатории и т.д. Из этого сле-
дует, что данные также обычно распределены, поскольку каждая организационная еди-
ница создает и обрабатывает собственные данные, относящиеся к деятельности этой
единицы. Таким образом, информация предприятия разбивается на части, которые ино-
гда называют островами информации. А распределенная система обеспечивает мосты
для их соединения в единое целое. Иначе говоря, распределенная система позволяет
структуре базы данных отображать структуру предприятия — локальные данные могут
храниться локально, в соответствии с логической принадлежностью, тогда как к удален-
ным данным доступ может осуществляться по мере необходимости.
Для того чтобы лучше в этом разобраться, приведем пример. Рассмотрим еще раз
рис. 20.1. Для простоты предположим, что есть только два узла, Лос-Анджелес и Сан-
Франциско, и что наша система— это банковская система. Данные о счетах Лос-
Анджелеса хранятся в Лос-Анджелесе, а данные о счетах Сан-Франциско— в Сан-
Франциско. Преимущества подобной распределенной системы очевидны: эффективность
обработки (данные хранятся в том месте, где доступ к ним требуется наиболее часто) плюс
расширенные возможности доступа (при необходимости с помощью коммуникационной
сети из Сан-Франциско можно получить доступ к счетам Лос-Анджелеса и наоборот).
Пожалуй, наиболее важным преимуществом распределенных систем является, как
уже было отмечено, отражение ими структуры предприятия. Конечно, существует мно-
жество других преимуществ, которые будут обсуждаться ниже в этой главе вместе с со-
ответствующими аспектами. Однако следует отметить, что подобным системам свойст-
вен и ряд недостатков, наиболее существенным из которых является повышенная слож-
Глава 20. Распределенные базы данных 769
ность распределенных систем, по крайней мере с технической точки зрения. В идеаль-
ном случае, конечно, эта сложность должна быть проблемой реализации, а не проблемой
пользователя, но вполне возможно, что на практике некоторые ее аспекты все-таки будут
видны конечным пользователям. Для того чтобы скрыть от пользователя сложность сис-
темы, требуется весьма тщательная ее проработка.
Примеры распределенных систем
Для ссылок в дальнейшем мы кратко перечислим некоторые известные реализации
распределенных систем. Сначала — прототипы. Среди многочисленных исследователь-
ских систем наиболее известны три системы. Во-первых, система SDD-1, созданная в на-
учно-исследовательском отделении корпорации Computer Corporation of America в конце
70-х и начале 80-х годов [20.34]. Во-вторых, система R* (читается “R-star”), распреде-
ленная версия системы-прототипа System R, созданная в исследовательском отделе ком-
пании IBM в начале 80-х годов [20.39]. И в-третьих, система Distributed Ingres, распреде-
ленная версия прототипа системы Ingres, созданная также в начале 80-х годов в Кали-
форнийском университете в Беркли [20.36].
Что касается коммерческих реализаций, то большинство современных SQL-продуктов
включает определенную поддержку распределенных баз данных, но, конечно, с разными
уровнями функциональных возможностей. Наиболее известные среди них следующие:
Ingres/Star (распределенный компонент базы данных СУБД Ingres), версия для распреде-
ленных баз данных СУБД Oracle и средства распределения данных для СУБД DB2.
Замечание. Безусловно, эти два списка не претендуют на полноту. Их назначение —
лишь указать системы, которые по тем или иным причинам оказывали или оказывают
определенное влияние на развитие данной области либо представляют интерес благодаря
своей внутренней структуре.
Также следует отметить, что все перечисленные выше системы, как прототипы, так
и коммерческие продукты, являются реляционными (по крайней мере, в них поддер-
живается язык SQL). В действительности существует несколько конкретных причин,
по которым для успешной реализации распределенная система должна быть реляци-
онной. Реляционная технология — это необходимое условия для эффективной распре-
деленной технологии [20.15]. Некоторые причины такого положения дел будут рас-
смотрены ниже в этой главе.
Фундаментальный принцип
Теперь сформулируем утверждение, которое может рассматриваться как фундамен-
тальный принцип создания распределенных баз данных [20.14].
Для пользователя распределенная система должна выглядеть так же, как не-
распределенная система.
Другими словами, пользователи распределенной системы должны иметь возможность
действовать так, как если бы система не была распределена. Все проблемы распределен-
ных систем относятся или должны относиться к внутренним проблемам или проблемам
реализации, а не к внешним проблемам или проблемам пользовательского уровня.
Замечание. Понятие “пользователи” в предыдущем абзаце относится к пользователям
(конечным пользователям или прикладным программистам), выполняющим операции
обработки данных. Все операции манипулирования данными должны оставаться логиче-
770
Часть V. Дополнительные аспекты
ски неизменными. Но для операции определения данных, напротив, в распределенной
системе обязательно потребуются некоторые дополнения. Например, пользователь на
узле X должен иметь возможность указать, что данная переменная-отношение будет раз-
делена на “фрагменты”, которые будут храниться на узлах Y и Z (см. обсуждение фраг-
ментации в следующем разделе).
Сформулированный выше фундаментальный принцип имеет следствием определенные
дополнительные правила или цели1. Таких целей всего двенадцать, и каждая из них будет
рассмотрена в следующем разделе. Для последующих ссылок перечислим эти цели.
1. Локальная независимость.
2. Отсутствие опоры на центральный узел.
3. Непрерывное функционирование.
4. Независимость от расположения.
5. Независимость от фрагментации.
6. Независимость от репликации.
7. Обработка распределенных запросов.
8. Управление распределенными транзакциями.
9. Аппаратная независимость.
10. Независимость от операционной системы.
11. Независимость от сети.
12. Независимость от типа СУБД.
Обратите внимание, что не все эти цели независимы одна от другой. Кроме того, они
недостаточно исчерпывающие и не все одинаково важны (разные пользователи могут
придавать различное значение разным целям в различных средах, и, кроме того, некото-
рые из этих целей могут быть вообще неприменимы в некоторых ситуациях). Однако
данные цели полезны как основа для понимания самой распределенной технологии и как
общая схема описания функциональных возможностей конкретных распределенных сис-
тем. Поэтому мы будем использовать список этих целей как организационный принцип
для большей части данной главы. В разделе 20.3 кратко обсуждается каждая из целей. В
разделе 20.4 некоторые конкретные вопросы рассматриваются более подробно, а в раз-
деле 20.5, как уже отмечалось, приводится обсуждение систем “клиент/сервер”. В разде-
ле 20.6 мы детально обсудим некоторые конкретные проблемы, связанные с достижени-
ем независимости от СУБД. И наконец, раздел 20.7 посвящен поддержке языка SQL, а в
разделе 20.8 представлены резюме и несколько заключительных замечаний.
И последний дополнительный вопрос в этом разделе. Важно отличать истинные
обобщенные системы распределенных баз данных от систем, которые предоставляют
просто удаленный доступ к данным (кстати, это все, что на самом деле предоставляет
пользователям система “клиент/сервер”). В системах удаленного доступа к данным ко-
нечный пользователь может оперировать данными на удаленном узле или даже данными
1 “Правила"— это термин, используемый в статье, в которой эти правила впервые были
представлены [20.14]. “Фундаментальный принцип” был назван “Правилом Нуль”. Однако на
самом деле здесь более уместен термин “цели”— “правила” звучит слишком категорично. В
этой главе будет использоваться более умеренное “цели ”.
Глава 20. Распределенные базы данных 771
на нескольких удаленных узлах одновременно, но ему будут видны все “швы”. Пользо-
вателю, несомненно, в той или иной мере будет известно, что данные удалены, и поэтому
он должен поступать соответственно. В истинной системе распределенных баз данных,
напротив, все швы скрыты. (Большая часть этой главы посвящена выяснению вопроса,
что же означает выражение “все швы скрыты”.) Далее термин “распределенная система’'
будет означать именно истинную обобщенную систему распределенной базы данных (в
противоположность обычной системе удаленного доступа к данным), если только явно
не будет указано противоположное.
20.3. Двенадцать основных целей
1. Локальная независимость
Узлы в распределенной системе должны быть независимы, или автономны. Локаль-
ная независимость означает, что все операции на узле контролируются этим узлом. Ника-
кой узел X не должен зависеть от некоторого узла Y, чтобы успешно функционировать
(иначе, если узел Y будет отключен, узел X не сможет функционировать, даже если на са-
мом узле X будет все в порядке; возникновение таких ситуаций, безусловно, нежелательно).
Локальная независимость также означает, что локальные данные имеют локальную при-
надлежность, управление и учет. Все данные “реально” принадлежат одной и той же ло-
кальной базе данных, даже если доступ к ней осуществляется с других, удаленных узлов.
Следовательно, такие вопросы, как безопасность, целостность и представление локальных
данных в памяти, остаются под контролем и в пределах компетенции локального узла.
В действительности локальная независимость не вполне достижима — есть множест-
во ситуаций, в которых узел X должен отказываться в определенной степени от контроля
в пользу узла Y. Поэтому цель достижения локальной независимости точнее можно было
бы сформулировать так: узлы должны быть независимыми в максимально возможной
степени. (См. аннотацию к публикации [20.14], где этот вопрос описан подробнее.)
2. Отсутствие опоры на центральный узел
Локальная независимость предполагает, что все узлы в распределенной системе
должны рассматриваться как равные. Поэтому, в частности, не должно быть никаких
обращений к “центральному” или “главному” узлу с целью получения некоторого цен-
трализованного сервиса. Не должно быть, например, централизованной обработки за-
просов, централизованного управления транзакциями или централизованной службы
присвоения имен, поскольку в таких случаях система в целом будет зависимой от цен-
трального узла. Таким образом, вторая цель на самом деле является следствием первой
цели — если первая цель достигнута, то вторая цель также заведомо достигнута. Но дос-
тижение цели “Отсутствие опоры на центральный узел” полезно само по себе, даже если
полная локальная независимость узлов не будет достигнута. Поэтому отдельная форму-
лировка данной цели также важна.
Опора на центральный узел является нежелательной по крайней мере по двум сле-
дующим причинам. Во-первых, такой центральный узел, скорее всего, станет узким ме-
стом системы, и, во-вторых (что еще хуже), система станет уязвимой — если работа цен-
трального узла будет нарушена, то вся система выйдет из строя (проблема “единого ис-
точника отказа”).
772 Часть V. Дополнительные аспекты
3. Непрерывное функционирование
В общем случае преимущество распределенных систем состоит в том, что они долж-
ны предоставлять более высокую степень надежности и доступности.
Надежность понимается как высокая степень вероятности того, что система будет
работоспособна и будет функционировать в любой заданный момент. Надежность
распределенных систем повышается за счет того, что они не опираются на прин-
цип “все или ничего”; распределенные системы могут непрерывно функциониро-
вать (в сокращенном варианте) даже в случаях отказов части их компонентов, та-
ких как отдельный узел.
Доступность понимается как высокая степень вероятности того, что система ока-
жется работоспособной и будет непрерывно функционировать в течение опреде-
ленного времени. Доступность распределенных систем также повышается — час-
тично по тем же причинам, а также благодаря возможности дублирования данных
(подробности приводятся в комментарии к цели 6).
Предыдущие рассуждения относятся к случаям незапланированного отключения
системы, т.е. к аварийным ситуациям, которые могут возникнуть в системе в любой мо-
мент. Незапланированные отключения системы, безусловно, нежелательны, но их трудно
предупредить! Планируемые отключения системы, напротив, никогда не должны быть
необходимы, т.е. никогда не должна возникать необходимость отключить систему, что-
бы выполнить какую-либо задачу, например добавить новый узел или заменить на уже
существующем узле текущую версию СУБД ее новой реализацией.
4. Независимость от расположения
Основная идея независимости от расположения, или так называемой прозрачности
расположения, проста. Пользователи не должны знать, где именно данные хранятся физи-
чески и должны поступать так (по крайней мере, с логической точки зрения), как если бы
все данные хранились на их собственном локальном узле. Благодаря независимости от рас-
положения упрощаются пользовательские программы и терминальные операции. В частно-
сти, данные могут быть перенесены с одного узла на другой, и это не должно потребовать
внесения каких-либо изменений в использующие их программы или действия пользовате-
лей. Такая переносимость желательна, поскольку она позволяет перемещать данные в сети
в соответствии с изменяющимися требованиями к эффективности работы системы.
Замечание. Нетрудно заметить, что независимость от расположения представляет собой
простое расширение для распределенных систем обычной концепции физической независи-
мости данных. Забегая несколько вперед, следует сказать, что на самом деле каждую из целей,
в названии которой употреблено слово “независимость”, можно рассматривать как расшире-
ние обычной концепции физической независимости данных, в чем мы скоро убедимся. Мы
еще возвратимся к вопросу независимости от расположения в разделе 20.4, в котором будет
обсуждаться присвоение имен объектам (подраздел “Управление каталогом”).
5. Независимость от фрагментации
Система поддерживает независимость от фрагментации, если данная переменная-
отношение может быть разделена на части или фрагменты при организации ее физиче-
ского хранения. Фрагментация желательна для повышения производительности системы.
В этом случае данные могут храниться в том месте, где они чаще всего используются,
Глава 20. Распределенные базы данных 773
что позволяет достичь локализации большинства операций и уменьшения сетевого тра-
фика. Например, рассмотрим переменную-отношение ЕМР с данными о служащих, со-
держание которой представлено на рис. 20.2. В системе, которая поддерживает незави-
симость от фрагментации, два фрагмента этой переменной-отношения можно опреде-
лить следующим образом (см. нижнюю часть рис. 20.2).
FRAGMENT ЕМР AS
N ЕМР AT SITE 'New York' WHERE DEPT# = 'DI'
OR DEPT# = 'D3',
L EMP AT SITE 'London' WHERE DEPT# = 'D2' ;
Восприятие
пользователя
EMP
EMP# DEPT# SALARY
Е1 D1 ДОК
Е2 D1 42К
ЕЗ D2 ЗОК
Е4 D2 35К
Е5 D3 48К
Нью-Йорк
Лондон
N_EMP
EMP# DEPT# SALARY
Е1 D1 ДОК
Е2 D1 42К
Е5 D3 48К
L EMP
EMP# DEPT# SALARY
ЕЗ D2 ЗОК
Е4 D2 45К
Рис. 20.2. Пример фрагментации
Замечание. Здесь подразумевается, что кортежи служащих отображаются в физиче-
ской памяти каким-то непосредственным способом; что номера служащих и номера от-
делов представлены символьными строками, а размер заработной платы — числами; что
D1 и D3 — отделы, расположенные в Нью-Йорке, a D2 — отдел, расположенный в Лондо-
не. Таким образом, кортежи служащих из Нью-Йорка хранятся на узле в Нью-Йорке, а
кортежи служащих из Лондона— на узле в Лондоне. Отметим, что внутрисистемные
имена фрагментов — N_EMP и L_EMP.
Существует два основных вида фрагментации: горизонтальная и вертикальная’, они
соответствуют реляционным операциям выборки и проекции соответственно (на
рис. 20.2 показан пример горизонтальной фрагментации). В более общем случае фраг-
мент можно представить в виде произвольного сочетания операций выборки и проекции,
но со следующими ограничениями.
В случае выборки это должна быть ортогональная декомпозиция в смысле, ука-
занном в разделе 12.6 главы 12.
В случае проекции это должна быть декомпозиция без потерь в смысле, указан-
ном в главах 11 и 12.
774
Часть К Дополнительные аспекты
Благодаря этим двум правилам все фрагменты данной переменной-отношения будут
независимыми, т.е. ни один из фрагментов не может быть представлен как производный
от других фрагментов, а также не может иметь выборку или проекцию, которая была бы
производной от других фрагментов. (Если действительно необходимо хранить одну и ту
же часть данных в нескольких различных местах, можно воспользоваться системным
механизмом репликации', см. следующий подраздел).
Восстановление исходной переменной-отношения из ее фрагментов выполняется с
помощью соответствующих операций соединения и объединения (соединения— для
вертикальных фрагментов, а объединения — для горизонтальных). Кстати, обратите
внимание, что благодаря первому правилу в случае объединения операцию исключения
дубликатов выполнять не потребуется.
Замечание. Необходимо сказать еще несколько слов относительно вертикальной
фрагментации. Как утверждалось выше, несомненно, что такая фрагментация долж-
на выполняться без потерь. Поэтому разбиение переменной-отношения ЕМР на фраг-
менты-проекции, например, вида {ЕМР#,DEPT#} и {SALARY} было бы недопустимым.
Однако в некоторых системах хранимые переменные-отношения рассматриваются
как имеющие скрытый, предоставляемый системой атрибут “идентификатор корте-
жа”, или сокращенно — атрибут TID (tuple ID). Для каждого хранимого кортежа ат-
рибут TID, грубо говоря, является адресом. Очевидно, что он является потенциаль-
ным ключом для соответствующей переменной-отношения. Например, если бы пе-
ременная-отношение ЕМР содержала такой атрибут, то она могла бы быть фрагмен-
тирована на проекции {TID,EMP#,DEPT#} и {TID,SALARY}, поскольку такая фрагмен-
тация уже, конечно, выполняется без потерь. Также обратите внимание, что если,
например, атрибут TID является скрытым, то это никак не нарушает информацион-
ный принцип, поскольку независимость от фрагментации означает, что пользователь
не должен знать чего-либо о фрагментации.
Заметим, между прочим, что простота выполнения фрагментации и восстановле-
ния — это две основные причины, по которым распределенные базы данных должны
быть именно реляционными. Реляционная модель предоставляет все те операции, кото-
рые необходимы для решения этих задач [20.15].
Теперь перейдем к главному вопросу. Система, которая поддерживает фраг-
ментацию данных, должна поддерживать и независимость от фрагментации
(иногда говорят “прозрачность фрагментации”). Другими словами, пользователи
должны иметь возможность работать точно так, по крайней мере с логической
точки зрения, как если бы данные в действительности были вовсе не фрагменти-
рованы. Независимость от фрагментации (как и независимость от расположе-
ния) — это весьма желательное свойство, поскольку она позволяет упростить раз-
работку пользовательских программ и выполнение терминальных операций. В ча-
стности, это гарантирует, что в любой момент данные могут быть заново восста-
новлены (а фрагменты перераспределены) в ответ на изменение требований к эф-
фективности работы системы, причем ни пользовательские программы, ни терми-
нальные операции при этом не затрагиваются.
Таким образом, если обеспечивается независимость от фрагментации, пользователи
получают данные в виде некоторого представления, в котором фрагменты логически
скомбинированы с помощью соответствующих операций соединения и объединения. К
обязанностям системного оптимизатора относится определение фрагментов, к которым
Глава 20. Распределенные базы данных
775
требуется физический доступ для выполнения любого из поступивших запросов пользо-
вателя. В случае варианта фрагментации, показанного на рис. 20.2, пусть, например,
пользователь выдает следующий запрос.
ЕМР WHERE SALARY > 40К AND DEPT# = 'Dl'
Из определений фрагментов (которые хранятся, конечно же, в каталоге) оптимизато-
ру должно быть известно, что весь требуемый результат может быть получен только по
данным узла в Нью-Йорке, а значит, нет никакой необходимости устанавливать связь с
узлом из Лондона.
Рассмотрим этот пример более детально. Переменная-отношение ЕМР, как ее воспри-
нимает пользователь, может рассматриваться (упрощенно) как некоторое представле-
ние, построенное на основе базовых фрагментов N_EMP и L_EMP.
VAR ЕМР VIEW
N_EMP UNION L_EMP ;
Тогда оптимизатор преобразует исходный запрос пользователя в следующее выражение.
(N_EMP UNION L_EMP) WHERE SALARY > 40K AND DEPT# = 'Dl'
В процессе дальнейшей оптимизации это выражение будет преобразовано в сле-
дующее выражение (поскольку операция выборки распределяется по объединению).
( N_EMP WHERE SALARY > 4OK AND DEPT# = 'Dl' )
UNION
( L_EMP WHERE SALARY > 40K AND DEPT# = 'Dl' )
Из определения фрагмента L_EMP в каталоге оптимизатору будет известно, что второй
из этих двух операндов объединения в результате вычисления даст пустое отношение
(условие DEPT# = 'Dl' AND DEPT# = 'D2' никогда не может быть истинным). Таким
образом, все выражение может быть приведено к следующему виду.
N_EMP WHERE SALARY > 40К AND DEPT# = 'Dl'
Теперь оптимизатору станет ясно, что потребуется доступ лишь к данным узла в
Нью-Йорке.
Упражнение. Рассмотрите, какие действия должен будет выполнить оптимизатор при
обработке следующего запроса.
ЕМР WHERE SALARY > 40К
Из предыдущего обсуждения следует, что проблема поддержки операций для
фрагментированных переменных-отношений в некоторых вопросах пересекается с про-
блемой поддержки операций представлений, определенных с помощью операций соеди-
нения и объединения (фактически это одна и та же проблема — она лишь проявляется на
разных уровнях общей системной архитектуры). В частности, проблема обновления
фрагментированных переменных-отношений совпадает с проблемой обновления пред-
ставлений, определенных с помощью операций соединения и объединения (см. главу 9).
Отсюда следует, что обновление некоторого кортежа — опять же, если говорить нестро-
го — может привести к тому, что кортеж будет перенесен из одного фрагмента в другой,
если обновленный кортеж больше не удовлетворяет предикату для того фрагмента, кото-
рому он принадлежал ранее.
776
Часть V. Дополнительные аспекты
6. Независимость от репликации
Система поддерживает репликацию данных, если данная хранимая переменная-
отношение— или в общем случае данный фрагмент данной хранимой переменной-
отношения — может быть представлена несколькими отдельными копиями или репликами,
которые хранятся на нескольких отдельных узлах. Рассмотрим конкретный пример
(рис. 20.3). Обратите внимание, что внутри системы дубликаты имеют имена NL_EMP и LN_EMP.
REPLICATE N_EMP AS
LN_EMP AT SITE 'London' ;
REPLICATE L_EMP AS
NL_EMP AT SITE 'New York' ;
New York ||
N_EMP
EMP# DEPT# SALARY
Е1 Е2 Е5 D1 D1 D3 40К 42К 48К
EMP# DEPT# SALARY
ЕЗ D2 ЗОК
Е4 D2 35К
ма меж маж а ^^а а^^м а^^м ^важ «а а^^м WBi^a MBi^a а^^м а^^м
NL ЕМР (дубликат L ЕМР)
L_EMP |London
EMP# DEPT# SALARY
ЕЗ Е4 D2 D2 ЗОК 35К
ЕМР#”' Е1 Е2 Е5 Е)ЁРТ£2 D1 D1 D3 salary" 40К 42К 48К
LN EMP (дубликат N EMP)
Puc. 20.3. Пример репликации данных
Репликация желательна по крайней мере по двум причинам. Во-первых, она способна
обеспечить более высокую производительность, поскольку приложения смогут обраба-
тывать локальные копии вместо того, чтобы устанавливать связь с удаленными узлами.
Во-вторых, наличие репликации может также обеспечивать более высокую степень дос-
тупности, поскольку любой реплицируемый объект остается доступным для обработки
(по крайней мере для выборки данных), пока хотя бы одна реплика в системе остается
доступной. Главным недостатком репликации, конечно, является то, что если реплици-
руемый объект обновляется, то и все его копии должны быть обновлены (проблема
распространения обновления). В разделе 20.4 мы еще скажем несколько слов относи-
тельно этой проблемы.
Отметим, между прочим, что репликация в распределенных системах представляется
специфическим приложением идеи контролируемой избыточности, которая обсужда-
лась в главе 1.
Очевидно, что репликация, как и фрагментация, теоретически должна быть “прозрачной
для пользователя”. Другими словами, система, которая поддерживает репликацию данных,
также должна поддерживать независимость от репликации (иногда говорят
“прозрачность репликации”). Для пользователей должна быть создана такая среда, чтобы
они, по крайней мере с логической точки зрения, могли считать, что в действительности
данные не дублируются. Независимость от репликации (как и независимость от располо-
жения, и независимость от фрагментации) является весьма желательной, поскольку она уп-
рощает создание пользовательских программ и выполнение терминальных операций. В ча-
Глава 20. Распределенные базы данных
777
стности, независимость от репликации позволяет создавать и уничтожать дубликаты в лю-
бой момент в соответствии с изменяющимися требованиями, не затрагивая при этом ника-
кие из пользовательских программ или терминальных операций.
Из требования независимости от репликации следует, что к обязанностям системного
оптимизатора также относится определение, какой именно из физических дубликатов
будет применен для доступа к данным при выполнении каждого введенного пользовате-
лем запроса. Здесь мы опускаем детали этого вопроса.
Завершая подраздел, отметим, что многие коммерческие продукты в настоящее время
поддерживают такой вид репликации, который не обеспечивает полной независимости
от репликации, т.е. репликация будет не полностью “прозрачна для пользователя”. Неко-
торые дополнительные замечания по этому вопросу будут приведены в подразделе о
распространении обновления в разделе 20.4.
7. Обработка распределенных запросов
Существуют две особенности, касающиеся темы этого раздела, которые необходимо
предварительно прокомментировать.
Во-первых, рассмотрим запрос “Получить сведения о лондонских поставщиках крас-
ных деталей”. Предположим, что пользователь работает на узле в Нью-Йорке, а дан-
ные размещены на узле в Лондоне. Предположим также, что имеется п поставщиков,
которые удовлетворяют данному запросу. Если система реляционная, то выполнение
данного запроса будет, по существу, включать пересылку двух сообщений: одно — с
запросом из Нью-Йорка в Лондон, а другое — с возвращаемым результатом, т.е. набо-
ром из л кортежей, пересылаемых из Лондона в Нью-Йорк. Если, с другой стороны,
система не реляционная и использует операции с таблицами на уровне отдельных за-
писей, выполнение запроса будет, по существу, включать пересылку 2п сообщений —
л сообщений из Нью-Йорка в Лондон, которые запрашивают “следующего” поставщи-
ка, и л сообщений из Лондона в Нью-Йорк, которые возвращают сведения об
“очередном” поставщике. Этот пример показывает, что по производительности рас-
пределенная реляционная система может на порядок превосходить не реляционную.
Во-вторых, оптимизация в распределенных системах даже более важна, нежели в
централизованных. Суть в том, что для запроса, подобного рассмотренному выше,
может потребоваться обращение к нескольким узлам. В такой системе может быть
много возможных способов пересылки данных, позволяющих выполнить рассмат-
риваемый запрос. Поэтому крайне важно, чтобы была найдена эффективная стра-
тегия. Например, запрос для, скажем, объединения отношения Rx, хранимого на
узле X, и отношения Ry, хранимого на узле У, может быть выполнен посредством
пересылки отношения Rx на узел У или отношения Ry на узел X, или обоих отно-
шений на какой-либо узел Z и т.п. Неопровержимая иллюстрация важности опти-
мизации, включающая упомянутый выше запрос (“Получить сведения о лондон-
ских поставщиках красных деталей”), представлена в разделе 20.4. Подводя крат-
кий итог этого примера, можно отметить, что по вопросу обработки данного за-
проса анализируется шесть различных стратегий с учетом определенного набора
вероятных допущений. В результате показано, что время ответа в каждом случае
различно и изменяется в широких пределах от минимального (от одной до десяти
секунд) до максимального (около шести часов!). Таким образом, оптимизация,
778
Часть V. Дополнительные аспекты
несомненно, весьма критична для распределенной системы и, кроме того, на эту
особенность можно взглянуть, как на еще одну причину, по которой распределен-
ные системы всегда должны быть реляционными (ответ прост: реляционные сис-
темы позволяют оптимизировать обработку запросов, а не реляционные — нет).
8. Управление распределенными транзакциями
Как известно, существует два главных аспекта управления транзакциями, а именно:
управление восстановлением и управление параллельностью обработки. Оба этих аспекта
имеют расширенную трактовку в среде распределенных систем. Чтобы разъяснить особен-
ности этой расширенной трактовки, сначала необходимо ввести новое понятие агент. В
распределенной системе отдельная транзакция может включать в себя выполнение кода на
многих узлах, в частности это могут быть операции обновления, выполняемые на несколь-
ких узлах. Поэтому говорят, что каждая транзакция содержит несколько агентов, где под
агентом подразумевается процесс, который выполняется для данной транзакции на отдель-
ном узле. Система должна знать, что два агента являются элементами одной и той же тран-
закции, например два агента, которые являются частями одной и той же транзакции, оче-
видно, не должны оказываться в состоянии взаимной блокировки.
Теперь обратимся непосредственно к управлению восстановлением. Чтобы обеспе-
чить атомарность транзакции (принцип “все или ничего”) в распределенной среде, сис-
тема должна гарантировать, что все множество относящихся к данной транзакции аген-
тов или зафиксировало свои результаты, или выполнило откат. Такого результата можно
достичь с помощью протокола двухфазной фиксации транзакции, который уже обсуж-
дался в главе 14, хотя это обсуждение и не было прямо связано с распределенными сис-
темами. Подробнее об использовании протокола двухфазной фиксации в распределен-
ных системах речь пойдет в разделе 20.4.
Что касается управления параллельностью, то оно в большинстве распределенных
систем базируется на механизме блокирования, точно так, как и в не распределенных
системах. В нескольких более новых коммерческих продуктах была реализована .много-
вариантная блокировка данных [15.1]. Однако на практике обычное блокирование еще,
кажется, по-прежнему остается тем методом, который выбирается в большинстве систем.
Подробнее этот вопрос также будет обсуждаться в разделе 20.4.
9. Аппаратная независимость
По этому вопросу фактически нечего сказать — заголовок раздела говорит сам за себя.
Парк вычислительных машин современных организаций обычно включает множество раз-
ных компьютеров — машины IBM, машины ICL, машины HP, персональные компьютеры,
различного рода рабочие станции и т.д. Поэтому действительно существует необходимость
интегрировать данные всех этих систем и предоставить пользователю “образ единой сис-
темы”. Следовательно, желательно иметь возможность запускать одну и ту же СУБД на
различных аппаратных платформах и, более того, добиться, чтобы различные машины уча-
ствовали в работе распределенной системы как равноправные партнеры.
10. Независимость от операционной системы
Достижение этой цели частично зависит от достижения предыдущей и также не требует
дополнительного обсуждения. Очевидно, что необходима не только возможность функцио-
нирования одной и той же СУБД на различных аппаратных платформах, но и возможность ее
Глава 20. Распределенные базы данных 779
функционирования под различными операционными системами для многих платформ —
включая различные операционные системы на одном и том же оборудовании (например, что-
бы версия СУБД для операционной системы MVS, версия для UNIX и версия для
Windows NT могли совместно использоваться в одной и той же распределенной системе).
11. Независимость от сети
Здесь, опять же, нечего добавить. Если система имеет возможность поддерживать
много принципиально различных узлов, отличающихся оборудованием и операционны-
ми системами, очевидно, необходимо, чтобы она также поддерживала ряд типов различ-
ных коммуникационных сетей.
12. Независимость от типа СУБД
В этом разделе мы рассмотрим, с чем приходится сталкиваться при отказе от требо-
вания строгой однородности системы. Необходимость такого сильного ограничения вы-
зывает сомнения. Действительно, все, что необходимо, — так это то, чтобы экземпляры
СУБД на различных узлах все вместе поддерживали один и тот же интерфейс, и со-
всем необязательно, чтобы это были копии одной и той же версии СУБД. Например,
СУБД Ingres и Oracle обе поддерживают официальный стандарт языка SQL, а значит,
можно добиться, чтобы узел с СУБД Ingres и узел с СУБД Oracle обменивались сообще-
ниями между собой в контексте распределенной системы. Иными словами, распределен-
ные системы вполне могут быть, по крайней мере в некоторой степени, неоднородными.
Поддержка неоднородности весьма заманчива. На практике современное программ-
ное обеспечение обычно используется не только на многих различных компьютерах и в
среде многих различных операционных систем. Оно довольно часто используется и с
различными СУБД, и было бы очень хорошо, если бы различные СУБД можно было ка-
ким-то образом включить в распределенную систему. Иными словами, идеальная рас-
пределенная система должна обеспечивать независимость от СУБД.
Однако эта тема слишком обширна (и важна на практике), поэтому ниже ей посвящен
отдельный раздел (см. раздел 20.6).
20.4. Проблемы распределенных систем
В этом разделе подробно рассматриваются проблемы, которые упоминались в разде-
ле 20.3. Ключевая проблема распределенных систем состоит в том, что коммуникацион-
ные сети, по крайней мере сети с “большой протяженностью” или глобальные сети, пока
являются медленными. Обычная глобальная сеть чаще всего имеет среднюю скорость
передачи данных от 5 до 10 тысяч байтов в секунду. Обычный же жесткий диск имеет
скорость обмена данными около 5-10 миллионов байтов в секунду. (С другой стороны,
некоторые локальные сети поддерживают скорость обмена данными того же порядка,
что и диски.) Поэтому основная задача распределенных систем — минимизировать ис-
пользование сетей, т.е. минимизировать количество и объем передаваемых сообщений.
Эта задача, в свою очередь, сталкивается с проблемами в нескольких дополнительных
областях. Приведем список таких областей, хотя мы и не гарантируем, что он полный.
Обработка запросов
Управление каталогом
780
Часть V. Дополнительные аспекты
Распространение обновлений
Управление восстановлением
Управление параллельностью
Обработка запросов
Чтобы решить задачу минимизации использования сети, процесс оптимизации запро-
сов должен быть распределенным, как и процесс выполнения запросов. Иначе говоря, в
общем случае процесс оптимизации будет содержать этап глобальной оптимизации, за
которым последуют этапы локальной оптимизации на каждом задействованном узле.
Например, предположим, что запрос Q представлен на рассмотрение узлу X, и предполо-
жим, что запрос Q включает объединение отношения Ry, в котором сто кортежей на
узле Y, с отношением Rz, в котором миллион кортежей на узле Z. Оптимизатор на узле X
должен выбрать глобальную стратегию выполнения запроса Q. В данном случае очевид-
но, что было бы выгоднее переслать отношение Ry на узел Z, а не отношение Rz на узел Y
(ну и, конечно же, не оба отношения Ry и Rz на узел X). Затем, после принятия решения о
пересылке отношения Ry на узел Z, реальная стратегия выполнения объединения на
узле Z будет определяться локальным оптимизатором этого узла.
Приведенная ниже подробная иллюстрация процесса выполнения запроса основана
на примере, взятом из [20.13], который, в свою очередь, заимствован из ранней работы
Ротни (Rothnie) и Гудмана (Goodman) [20.33].
База данных поставщиков и деталей (упрощенная)
S { S#, CITY } 10 000 хранимых кортежей на узле А
Р { Р#, COLOR } 100 000 хранимых кортежей на узле Б
SP { S#, P# } 1 000 000 хранимых кортежей на узле А
Предположим, что каждый хранимый кортеж имеет длину 25 байт (200 бит).
Запрос (“Получить номера лондонских поставщиков красных деталей”)
( ( S JOIN SP JOIN Р ) WHERE CITY = 'London' AND
COLOR = COLOR ('Red') ) { S# }
Расчетные количества некоторых промежуточных результатов
Количество красных деталей 10
Количество поставок, выполненных поставщиками из Лондона 100 000
Предполагаемые параметры линий передачи данных
Скорость передачи данных 50 000 бит/с
Задержка доступа 0,1 с
Теперь кратко рассмотрим шесть возможных стратегий выполнения этого запроса, и для
каждой стратегии i рассчитаем общее время Т [ i ] передачи данных по следующей формуле.
( общая задержка доступа ) +
( общий объем данных / скорость передачи данных )
В этом случае она сводится к следующей формуле (время в секундах).
( количество сообщений / 10 ) + (количество битов / 50000 )
Глава 20. Распределенные базы данных
781
1. Пересылка записей о деталях на узел А и обработка запроса на узле А.
Т[1] = 0,1 + ( 100000 * 200 ) / 50000
= 400 с (приблизительно 6,67 мин)
2. Пересылка записей о поставщиках и поставках на узел Б и обработка запроса на узле Б.
Т[2] = 0,2 + ( ( 10000 + 1000000 ) * 200 ) / 50000
= 4040 с (приблизительно 1,12 ч)
3. Соединение отношений поставщиков и поставок на узле А, выборка из результирую-
щего отношения кортежей для поставщиков из Лондона с последующей проверкой на
узле Б для каждого выбранного поставщика соответствующих деталей, является ли
деталь красной. Каждая из таких проверок включает два сообщения: запрос и ответ.
Время передачи этих сообщений будет мало по сравнению с задержкой доступа.
Т[3] = 20000 с (приблизительно 5,56 ч)
4. Выборка красных деталей на узле Б и проверка для каждой из выбранных деталей
на узле А наличия поставок, связывающих эту деталь с поставщиком из Лондона.
Каждая из таких проверок включает два сообщения. Время передачи этих сообще-
ний также будет мало по сравнению с задержкой доступа.
Т[4] = 2 с (приблизительно)
5. Соединение отношений поставщиков и поставок на узле А, выборка из результата
кортежей для поставщиков из Лондона, проекция этих кортежей по атрибутам S# и
P# и пересылка результата на узел Б. Завершение обработки на узле Б.
Т[5] = 0,1 + ( 100000 * 200 ) / 50000
= 400 с (приблизительно 6,67 мин)
6. Выборка красных деталей на узле Б и пересылка результата на узел А. Завершение
обработки на узле А.
Т[6] = 0,1 + ( 10 * 200 ) / 50000
= 0,1 с (приблизительно)
На рис. 20.4 подведены итоги результатов обработки различных вариантов запроса.
Стратегия Метод Время передачи данных
1 Пересылка Р на А 6,67 мин
2 Пересылка S и SP на Б 1,12 ч
3 Для каждой поставки из Лондона проверка красной детали 5,56 ч
4 Для каждой красной детали проверка по- ставщика из Лондона 2,00 с
5 Пересылка поставок из Лондона на Б 6,67 мин
6 Пересылка красных деталей на А 0,10 с (самое малое)
Рис. 20.4. Возможные стратегии распределенной обработки запроса (сводка)
Прокомментируем эти результаты.
Каждая из шести стратегий представляет возможный подход к проблеме, но от-
клонения по времени передачи данных огромны. Наибольшее время в два миллио-
на раз больше, чем наименьшее.
782
Часть V. Дополнительные аспекты
Скорость обмена данными и задержки доступа — важные факторы в выборе
стратегии.
Для плохих стратегий время вычислений и ввода-вывода ничтожно мало по сравне-
нию со временем передачи данных. С другой стороны, для лучших стратегий это со-
отношение может зависеть от дополнительных обстоятельств [20.35]. Такого боль-
шого расхождения может не быть в случае использования быстрых локальных сетей.
Кроме того, некоторые стратегии позволяют выполнять параллельную обработку на
двух узлах, поэтому время ответа системы пользователю может быть даже меньше, чем в
случае, когда окончательный результат запроса определяется на единственном узле.
Управление каталогом
В распределенной системе каталог включает не только обычные для каталога данные,
соответствующие базовым переменным-отношениям, представлениям, полномочиям и
т.д., но также всю необходимую управляющую информацию, которая позволит системе
обеспечить независимость от размещения, фрагментации и репликации. Возникает во-
прос “Где и как должен храниться сам каталог?”. Имеется несколько перечисленных ни-
же возможностей.
1. Централизованное хранение. Единственный общий каталог хранится на отдельном
центральном узле.
2. Полная репликация. Общий каталог целиком хранится на каждом узле.
3. Частичное хранение. Каждый узел поддерживает собственный каталог для объек-
тов, которые на нем хранятся. Общий каталог представляет собой объединение
всех этих несвязанных локальных каталогов.
4. Сочетание подходов 1 и 3. Каждый узел поддерживает свой локальный каталог,
как предусмотрено при подходе 3. Кроме того, отдельный центральный узел со-
провождает объединенную копию всех этих локальных каталогов, как предусмот-
рено при подходе 1.
Каждый подход имеет свои недостатки. При подходе 1, очевидно, нарушается прин-
цип “Отсутствие опоры на центральный узел”. При подходе 2 в значительной мере утра-
чивается независимость узлов, поскольку всякое обновление каталога должно распро-
страняться на каждый узел. При подходе 3 нелокальные операции становятся слишком
затратными (для поиска удаленного объекта требуется досгуп в среднем к половине всех
узлов). Подход 4 более эффективный по сравнению с подходом 3 (для поиска удаленного
объекта требуется доступ лишь к одному удаленному каталогу), но в этом случае вновь
нарушается принцип отсутствия центрального узла. Поэтому на практике системы обыч-
но не используют ни один из этих подходов! В качестве примера рассмотрим подход, ко-
торый применяется в версии R* системы R [20.39].
Прежде чем описать структуру каталога системы R*, необходимо сказать несколько
слов о механизме именования объектов в этой системе. Присвоение имен объектам —
это вообще очень важный вопрос для распределенных систем. Поскольку два отдельных
узла X и Y могут иметь объект (скажем, базовую переменную-отношение) с именем А,
требуется некоторый механизм (обычно — уточнение с помощью имени узла) для того,
чтобы “устранить неоднозначность”, т.е. гарантировать уникальность расширенного сис-
темного имени. Однако, если уточненные имена, такие какХ.А и Y.A, будут предостав-
Глава 20. Распределенные базы данных
783
ляться системой и пользователю, будет нарушено требование независимости от разме-
щения. Поэтому необходимы средства отображения имен для пользователя в соответст-
вующие системные имена.
Теперь изложим подход к рассматриваемой проблеме, принятый в системе R*. В этой
системе различаются печатные имена, с помощью которых пользователи обычно обра-
щаются к объектам (например, в предложении SELECT языка SQL), и общесистемные име-
на, которые представляют собой глобальные уникальные внутренние идентификаторы для
этих же объектов. Расширенные системные имена имеют четыре следующих компонента.
Идентификатор создателя, т.е. идентификатор пользователя, который создал объект.
Идентификатор узла создателя, т.е. идентификатор узла, на котором была введе-
на соответствующая операция CREATE (создать).
Локальное имя, т.е. не уточненное имя объекта.
Идентификатор узла рождения, т.е. идентификатор узла, на котором объект хра-
нился первоначально.
Идентификаторы пользователя уникальны на узле, тогда как идентификаторы узла
уникальны глобально. Рассмотрим, например, следующее расширенное системное имя.
MARILYN 0 NEWYORK . STATS g LONDON
Оно обозначает объект (возможно, базовую переменную-отношение) с локальным
именем STATS, созданный пользователем MARILYN на узле в Нью-Йорке и первоначально
сохраненный2 на узле в Лондоне. Это имя гарантировано защищено от каких-либо
изменений, даже если объект будет перемещен на другой узел (см. ниже).
Как уже указывалось, пользователи обычно ссылаются на объекты с помощью печат-
ных имен. Печатное имя представляет собой простое, не уточненное имя— компонент
“локальное имя” из расширенного системного имени (в примере это STATS) или синоним
для соответствующего расширенного системного имени, который в системе R* определя-
ется с помощью специального оператора CREATE SYNONYM, как, например, показано ниже.
CREATE SYNONYM MSTATS FOR MARILYN 0 NEWYORK . STATS 0 LONDON ;
После выполнения этого оператора пользователь сможет с одинаковым успехом вве-
сти любой из двух приведенных ниже операторов.
SELECT FROM STATS ;
SELECT FROM MSTATS ;
В первом случае, т.е. при использовании локального имени, система будет подразу-
мевать, что все компоненты расширенного системного имени определяются по умолча-
нию, а именно, что объект создан данным пользователем, создан на данном узле и со-
хранен на данном узле. Кстати, благодаря такому допущению по умолчанию старые при-
ложения системы R могут выполняться без каких-либо исправлений в новой версии сис-
темы R* (т.е. после переопределения данных системы R для системы R*; напомним, что
система R была предшествующим прототипом системы R*).
2 В системе R* базовые переменные-отношения физически хранятся так, как они хранятся
почти во всех известных автору системах.
784
Часть V. Дополнительные аспекты
Во втором случае, т.е. при использовании синонима, система для определения рас-
ширенного системного имени проанализирует соответствующую таблицу синонимов.
Таблицы синонимов могут рассматриваться как первый компонент каталога. Каждый
узел поддерживает некоторый набор таких таблиц, созданных для каждого пользователя
данного узла, что позволяет системе отображать известные пользователю синонимы в
соответствующие расширенные системные имена.
Кроме таблиц синонимов, на каждом узле поддерживаются следующие данные.
1. Элементы каталога для каждого объекта, местом рождения которого является дан-
ный узел.
2. Элементы каталога для каждого объекта, хранимого в данный момент на данном узле.
Предположим теперь, что пользователь выдал запрос, содержащий ссылку на сино-
ним MSTATS. Сначала система выполнит поиск соответствующего расширенного систем-
ного имени в подходящей таблице синонимов (простой локальный просмотр). После то-
го как станет известен узел рождения (в нашем примере это узел в Лондоне), можно бу-
дет опросить каталог узла в Лондоне (здесь мы для общности подразумеваем удаленный
просмотр— первое удаленное обращение). Каталог узла из Лондона будет содержать
элемент для объекта в соответствии с п. 1. Если объект по-прежнему хранится на узле в
Лондоне, он будет найден. Однако, если объект перемещен, скажем, на узел в Лос-
Анджелесе, элемент каталога на узле в Лондоне будет содержать сведения об этом и сис-
тема должна будет опросить каталог на узле в Лос-Анджелесе (второе удаленное обра-
щение). Каталог на узле в Лос-Анджелесе будет содержать элемент для искомого объек-
та согласно п. 2. Таким образом, для поиска объекта будет выполнено не более двух уда-
ленных обращений.
Кроме того, если объект вновь потребуется переместить, скажем, на узел в Сан-
Франциско, системой будут выполнены следующие действия.
Вставка элемента в каталог на узле в Сан-Франциско.
Удаление элемента каталога на узле в Лос-Анджелесе.
Обновление элемента каталога на узле в Лондоне, который теперь будет указывать
на узел в Сан-Франциско вместо узла в Лос-Анджелесе.
В результате объект всегда может быть найден с помощью не более двух удаленных
обращений. И это полностью распределенная схема — нет никакого узла с основным ка-
талогом и нет никакого единого источника ошибок внутри системы.
Отметим, что схема идентификации объектов, которая используется в распределен-
ной СУБД DB2, хотя и подобна описанной выше, не полностью совпадает с ней.
Распространение обновлений
Основная проблема репликации данных, как указывалось в разделе 20.3, заключается
в том, что обновление любого заданного логического объекта должно распространяться
на все хранимые копии этого объекта. Сложности, которые немедленно возникают в
этом случае, состоят в том, что некоторый узел, содержащий копию данного объекта, в
момент обновления может оказаться недоступным, поскольку или он сам, или канал дос-
тупа находится в аварийном состоянии. Таким образом, очевидная стратегия немедлен-
Глава 20. Распределенные базы данных
785
ного обновления всех существующих копий будет, вероятно, неприемлема, поскольку
любая операция обновления, а значит, и вся включающая ее транзакция, закончится ава-
рийно, если одна из требуемых копий в момент обновления окажется недоступной. В ка-
ком-то смысле при этой стратегии данные будут менее доступны, чем при отсутствии
репликации. Таким образом, исчезает одно из главных преимуществ репликации, кото-
рое указывалось в предыдущем разделе.
Общая схема решения рассматриваемой проблемы (это не единственное возможное
решение) состоит в использовании так называемой схемы первичной копии, которая
действует следующим образом.
Одна копия для каждого реплицируемого объекта устанавливается как первичная
копия, а все оставшиеся копии — как вторичные.
Первичные копии различных объектов находятся на различных узлах (поэтому
данная схема все же является распределенной).
Операции обновления считаются логически завершенными, как только обновлена
первичная копия. Узел, содержащий такую копию, будет отвечать за распростра-
нение обновления на вторичные копии в течение некоторого последующего вре-
мени. (Это “последующее время”, тем не менее, должно предшествовать операции
завершения транзакции COMMIT, если должны гарантироваться ACID-свойства рас-
пределенных транзакций, т.е. свойства атомарности, согласованности, изолиро-
ванности и долговечности. Дополнительные замечания по этому вопросу будут
приведены ниже.)
Конечно, данная схема порождает несколько дополнительных проблем, обсуждение
большинства которых в этой книге не предусматривается. Отметим также, что эта схема
приводит к нарушению принципа локальной автономии, поскольку транзакция может
теперь завершиться аварийно из-за того, что удаленная (первичная) копия некоторого
объекта недоступна (даже если локальная копия доступна).
Замечание. Как уже указывалось, вследствие требования гарантии соблюдения
ACID-свойств транзакций, весь процесс распространения обновлений должен быть за-
вершен прежде, чем соответствующая транзакция может быть зафиксирована
(“синхронная репликация”). Однако несколько коммерческих продуктов поддержива-
ют менее строгую форму репликации, в которой распространение обновлений откла-
дывается на некоторое более позднее время (возможно, на некоторое указываемое
пользователем время) и не обязательно в рамках соответствующей транзакции
(“асинхронная репликация”). Фактически термин репликация, к сожалению, в какой-то
степени узурпирован этими продуктами, в результате чего, по крайней мере на ком-
мерческом рынке, под ним подразумевается, что распространение обновлений откла-
дывается до тех пор, пока соответствующая транзакция не завершится (например,
[20.1], [20.18] и [20.21]). Проблема подобного подхода с задержкой распространения
обновлений заключается, конечно, в том, что база данных не может больше гаранти-
ровать согласованности всех ее данных в любой момент. В действительности пользо-
ватель даже может не знать, согласованна ли база данных.
Завершая этот подраздел, приведем пару дополнительных замечаний в отношении
подхода с задержкой распространения обновлений.
786
Часть V. Дополнительные аспекты
1. Концепция репликации в системе с задержкой распространения обновлений мо-
жет рассматриваться как применение идеи моментальных снимков, речь о кото-
рых шла в главе 93. На самом деле лучше было бы использовать другой термин
для такого вида репликации. Тогда можно было бы сохранить термин “реплика”
для обозначения того, что понимается под ним в обычном разговоре (а имен-
но — точной копии).
Замечание. Мы не утверждаем, что задержка распространения обновлений — пло-
хая идея. Это, очевидно, самое лучшее, что можно было сделать при определенных
обстоятельствах, как мы убедимся, например, в главе 21. Суть в том, что задержка
распространения подразумевает, что “реплики” — не настоящие реплики, а систе-
ма — не настоящая распределенная система баз данных.
2. Одна из причин (может быть, даже главная причина), по которой репликация в
коммерческих продуктах реализована с задержкой расширения, заключается в
следующем: альтернатива, т.е. обновление всех дубликатов перед выполнением
операции COMMIT, требует поддержки двухфазной фиксации транзакции
(см. ниже), что может существенно повлиять на производительность системы.
Именно по этой причине в компьютерных журналах иногда встречаются статьи с
озадачивающими названиями, например “Репликация или двухфазная фикса-
ция?” (озадачивающими потому, что, по существу, в их названиях сравниваются
качества совершенно разных предметов).
Управление восстановлением
Как уже разъяснялось в разделе 20.3, управление восстановлением в распределенных
системах обычно базируется на протоколе двухфазной фиксации транзакций (или не-
которых его вариантах). Двухфазная фиксация транзакций требуется в любой среде, где
отдельная транзакция может взаимодействовать с несколькими автономными менедже-
рами ресурсов. Однако в распределенных системах ее использование приобретает ис-
ключительную важность, поскольку рассматриваемые менеджеры ресурсов, т.е. локаль-
ные СУБД, функционируют на отдельных узлах и поэтому в значительной мере авто-
номны. Рассмотрим некоторые особенности этого процесса.
1. Принцип “Отсутствие опоры на центральный узел” предписывает, что функции
координатора не должны назначаться одному выделенному узлу в сети, а
должны выполняться на различных узлах для различных транзакций. Обычно
управление транзакцией передается на тот узел, на котором она была иниции-
рована. Поэтому каждый узел должен быть способен выполнять функции коор-
динатора для некоторых транзакций и выступать в качестве участника выпол-
нения остальных транзакций.
2. Для двухфазной фиксации транзакций координатор должен взаимодействовать с
каждым участвующим узлом, что подразумевает повышенный уровень обмена со-
общениями, создающий дополнительную нагрузку на коммуникации.
3 За исключением того, что моментальные снимки предполагается использовать лишь для
чтения (не считая периодического обновления), в то время как некоторые коммерческие систе-
мы разрешают пользователям обновлять “дубликаты" непосредственно (см., например,
[20.21]). Конечно, данная возможность также противоречит независимости репликации.
Глава 20. Распределенные базы данных 787
3. Если узел Y является участником транзакции, выполняемой по протоколу двухфаз-
ной фиксации и координируемой узлом X, узел Y должен делать то, что предписы-
вает ему узел X (фиксацию результатов транзакции или ее откат в зависимости от
того, что именно потребуется), а это означает потерю (хотя и относительно незна-
чительную) локальной независимости.
Давайте повторно рассмотрим процесс двухфазной фиксации транзакций, описанный
ранее, в главе 14. Обратимся к рис. 20.5, на котором показано взаимодействие между коор-
динатором и обычным участником (будем считать его для простоты удаленным узлом).
Рис. 20.5. Двухфазная фиксация транзакции
Время на этом рисунке идет слева направо (более или менее’). Будем считать для
простоты, что для рассматриваемых транзакций выполняется операция COMMIT, а не
ROLLBACK. После получения запроса на операцию COMMIT координатор организует сле-
дующий двухфазный процесс.
Каждому участнику координатор отдает распоряжение “приготовиться к фиксации или
откату” транзакции. На рис. 20.5 показано сообщение “приготовиться”, отосланное в
момент tl и полученное участником в момент t2. Далее участник принудительно по-
мещает запись в журнал локального агента из своего физического журнала, а затем
выдает координатору подтверждение “ОК”. Конечно, если возникнет какая-либо
ошибка (в частности, если произойдет сбой локального агента), будет отослано сооб-
щение “Not ОК”. На рисунке это сообщение, которое для простоты обозначено как
“ОК”, переслано в момент t3 и получено координатором в момент t4. Как уже отме-
чалось выше, участник теперь теряет независимость: он должен делать то, что ему бу-
дет предписывать координатор. Кроме того, любые ресурсы, которые заблокированы
локальным агентом, должны оставаться заблокированными до тех пор, пока участ-
ник, получивший распоряжение координатора, его не выполнит.
После получения подтверждения ото всех участников координатор принимает ре-
шение либо зафиксировать транзакцию, если все ответы — “ОК”, либо выпол-
нить откат транзакции в противном случае. Затем в момент t5 координатор до-
бавляет в журнал запись о своем решении. Время t5 служит границей между пер-
вой и второй фазами фиксации транзакции.
788
Часть V. Дополнительные аспекты
Будем считать, что было принято решение о фиксации транзакции. В этом случае
координатор отдаст распоряжение всем участникам “выполнить”, т.е. запустить
обработку операции фиксации для локального агента. На рис. 20.5 показано сооб-
щение “выполнить”, отосланное в момент t6 и полученное участником в момент
t7. Участник выполняет операцию фиксации для локального агента и отсылает
подтверждение “выполнено” координатору. На рисунке сообщение отослано ко-
ординатору в момент t8 и получено в момент t9.
После того как координатором будут получены все подтверждения, процесс будет
полностью завершен.
На практике, конечно, этот процесс, в целом, значительно сложнее, чем описано вы-
ше, поскольку необходимо еще позаботиться о возможных отказах узла или каналов свя-
зи. Предположим, например, что на узле координатора сбой произошел в некоторый мо-
мент t между отметками времени t5 и t6. В процессе восстановления работы узла про-
цедура повторного пуска обнаружит в журнале сведения о том, что в момент отказа не-
которая транзакция была во второй фазе двухфазного процесса фиксации, после чего
процесс будет продолжен, начиная с пересылки участникам сообщений “выполнить”.
Отметим, что в период от t3 до 17 участник находится в состоянии ожидания заверше-
ния транзакции. Если координатор попал в аварийную ситуацию, как указывалось выше,
в момент t, период ожидания может оказаться достаточно длительным.
Теоретически, конечно, можно было бы считать процесс двухфазной фиксации устой-
чивым к любым возможным сбоям. К сожалению, несложно понять, что эта задача, по су-
ти, недостижима, т.е. не существует какого-либо конечного протокола, который бы гаран-
тировал, что все участники одновременно зафиксируют успешно завершившуюся транзак-
цию или одновременно ее отменят, столкнувшись при выполнении с некоторым отказом.
Предположим противное, т.е. предположим, что такой протокол существует. Пусть N—
минимальное количество сообщений, которые требуются таким протоколом. Предполо-
жим, что последнее из этих N сообщений утеряно из-за сбоев. Тогда или это сообщение не
было необходимым, что противоречит предположению о том, что N— минимальное коли-
чество сообщений, или протокол в этой ситуации работать не будет. И в том, и в другом
случае получаем противоречие, из которого следует, что такого протокола не существует.
Но несмотря на этот удручающий факт существует ряд усовершенствований, которые
можно внести в основной алгоритм для повышения его производительности.
Во-первых, если агент на некотором конкретном узле участника выполняет опера-
ции только чтения, такой участник при завершении первой фазы процесса может
ответить “игнорируйте меня” и координатор действительно может игнорировать
такого участника во второй фазе процесса.
Во-вторых, если все участники в первой фазе процесса ответят “игнорируйте ме-
ня”, вторая фаза вообще может быть полностью опущена.
И в-третьих, существуют два важных варианта основной схемы, которые называ-
ются вариантами предполагаемой фиксации и предполагаемого отката соответ-
ственно [20.15]. Они будут описаны ниже.
В общем случае в результате применения схем предполагаемой фиксации и предпола-
гаемого отката сокращается количество передаваемых сообщений как в удачных случаях
(для предполагаемой фиксации), так и в случаях отказов (для предполагаемого отката).
Глава 20. Распределенные базы данных
789
Прежде чем приступить к объяснению действия этих двух схем, заметим, что основной ме-
ханизм, как описано выше, требует, чтобы координатор помнил о своем решении, пока не
получит подтверждения от каждого участника. Причина, очевидно, заключается в том, что
если некоторый участник попадет в аварийную ситуацию в период ожидания, то при рес-
тарте он будет вынужден вновь отослать координатору запрос, чтобы узнать, каково же
было решение координатора в отношении данной транзакции. Однако как только все под-
тверждения будут получены, координатор будет считать, что все участники выполнили то,
что им было предписано, и поэтому он может “забыть” о данной транзакции.
Рассмотрим теперь схему предполагаемой фиксации. Согласно этой схеме от уча-
стников требуется подтверждение сообщений “откатить” (“отменить”), а не сообщений
“зафиксировать” (“выполнить”). Поэтому координатор может забыть о транзакции после
того, как передаст широковещательное сообщение о своем решении, при условии, что
это решение — “зафиксировать”. Если в период ожидания подтверждения участник по-
падает в аварийную ситуацию, в процессе повторного пуска он, как всегда, опросит ко-
ординатора о состоянии данной транзакции. Если координатор еще помнит о данной
транзакции, т.е. еще ожидает подтверждений от ее участников, его решением должно
быть “откатить”, в противном случае оно должно быть “зафиксировать”.
Схема предполагаемого отката — это противоположная схема. От участников тре-
буется подтверждение сообщений “зафиксировать”, а не сообщений “откатить”. И коор-
динатор может забыть о транзакции после того, как передаст широковещательное сооб-
щение о своем решении, если это решение — “откатить”. Если участник в период ожи-
дания завершения транзакции попадает в аварийную ситуацию, то в процессе рестарта
он должен будет опросить координатора о принятом им решении. Если координатор еще
помнит о данной транзакции, т.е. еще ожидает подтверждений от ее участников, его ре-
шением будет “зафиксировать”, в противном случае — “откатить”.
Интересно, и даже как-то противоестественно, что схема предполагаемого отката
оказывается более предпочтительной по сравнению со схемой предполагаемой фиксации
(“противоестественно”, поскольку, несомненно, большинство транзакций зафиксируется
успешно, а схемой предполагаемой фиксации ограничивается количество сообщений
именно в случае успешной фиксации). Проблема, связанная со схемой предполагаемой
фиксации, состоит в следующем. Предположим, что на узле координатора сбой произо-
шел во время первой фазы, т.е. до принятия решения. После перезапуска узла координа-
тора данная транзакция будет отменена, поскольку она не завершена. Следовательно, не-
которые участники будут запрашивать координатора о его решении относительно дан-
ной транзакции. Координатор такой транзакции не помнит, поэтому предполагается ре-
шение “зафиксировать”, что, конечно же, неверно.
Чтобы избежать такой “ложной фиксации”, координатор (использующий схему пред-
полагаемой фиксации) должен в начале первой фазы поместить в свой физический жур-
нал запись, содержащую список всех участников данной транзакции. (Если теперь на уз-
ле координатора произойдет сбой во время первой фазы фиксации транзакции, то после
его перезапуска он сможет передать всем участникам сообщение “выполнить откат”.)
Необходимость физического ввода-вывода при обращении к журналу координатора таит
в себе опасность для каждой транзакции. Поэтому схема предполагаемой фиксации не
так заманчива, как могло показаться на первый взгляд. В действительности можно без
преувеличения сказать, что ко времени написания данной книги схема предполагаемого
отката стала фактическим стандартом в реализованных системах.
790
Часть V. Дополнительные аспекты
Управление параллельностью
Как объяснялось в разделе 20.3, управление параллельным доступом в большинстве
распределенных систем строится на использовании механизма блокирования, т.е. точно
так, как и в большинстве не распределенных систем. Однако в распределенных системах
запросы на проверку, установку и отмену блокировки становятся сообщениями (если
считать, что рассматриваемый объект расположен на удаленном узле), а сообщения оз-
начают дополнительные накладные расходы. Рассмотрим, например, транзакцию Т, ко-
торой необходимо обновить объект, для которого существуют дубликаты на п удаленных
узлах. Если каждый узел отвечает за блокировку объектов, которые на нем хранятся (как
предполагается в соответствии с принципом локальной независимости), то непосредст-
венная реализация будет требовать по крайней мере 5л сообщений:
л запросов на блокировку;
л разрешений на блокировку;
л сообщений об обновлении;
л подтверждений;
л запросов на снятие блокировки.
Конечно, мы можем разумно воспользоваться, как и в предыдущем случае,
“комбинированными” сообщениями. Например, можно объединить сообщение запроса
на блокировку и сообщение об обновлении, а также сообщение о разрешении блокиров-
ки и сообщение о подтверждении. Но даже в этом случае общее время обновления может
быть на порядок больше, чем в централизованной системе.
Для решения проблемы обычно выбирается стратегия первичной копии, схематиче-
ски описанная выше, в разделе “Распространение обновлений”. Для данного объекта А
узел, содержащий первичную копию объекта А, будет обрабатывать все операции блоки-
ровки для этого объекта (напомним, что первичные копии различных объектов будут в
общем случае размещаться на различных узлах). При использовании этой стратегии на-
бор всех копий объекта можно рассматривать как отдельный объект для блокировки, а
общее количество сообщений будет сокращено с 5л до 2л+3 (один запрос блокировки,
одно разрешение блокировки, л обновлений, л подтверждений и один запрос на снятие
блокировки). Однако обратите внимание, что это решение влечет за собой серьезную по-
терю независимости — транзакция может теперь не завершиться, если первичная копия
окажется недоступной, даже если в транзакции выполнялось лишь чтение и локальная
копия была доступна. (Отметим, что блокировка первичной копии требуется не только
для операций обновления, но и для операций выборки [20.15]. Таким образом, у страте-
гии первичной копии есть нежелательный побочный эффект — снижение уровня произ-
водительности и доступности как для выборки, так и для обновления.)
Другая проблема, касающаяся блокировок в распределенных системах, состоит в том,
что блокировка может привести к состоянию глобальной взаимной блокировки, охва-
тывающей два и более узлов. Обратимся, например, к рис. 20.6.
1. Агент транзакции Т2 на узле X ожидает, пока агент транзакции II на узле X отменит
блокировку.
2. Агент транзакции II на узле X ожидает, пока агент транзакции Т1 на узле Y завер-
шит транзакцию.
Глава 20. Распределенные базы данных
791
3. Агент транзакции Tl на узле Y ожидает, пока агент транзакции Т2 на узле Y отменит
блокировку.
4. Агент транзакции Т2 на узле Y ожидает, пока агент транзакции Т2 на узле X завер-
шит транзакцию. Взаимная блокировка!
СайтХ
СайтУ
Рис 20.6 Пример состояния глобальной взаимной
блокировки
В состоянии глобальной взаимной блокировки, подобном только что рассмотренно-
му, никакой узел не может обнаружить ситуацию взаимной блокировки, используя
лишь собственную внутреннюю информацию. Иными словами, в локальном графе ожи-
даний нет никаких циклов и подобный цикл возникает только при объединении локаль-
ных графов в общий глобальный граф. Поэтому при обнаружении состояния глобальной
блокировки требуются дополнительные коммуникационные расходы, поскольку необхо-
димо, чтобы отдельные локальные графы рассматривались вместе.
Изящная (и распределенная) схема для определения состояния глобальной блокиров-
ки описана в статьях о системе R* (например, [20.39]).
Замечание. Как указывалось в главе 15, в действительности не все системы обнару-
живают состояние взаимной блокировки — некоторые вместо этого просто используют
механизм тайм-аута. По очевидным причинам данное замечание справедливо, в частно-
сти, и относительно распределенных систем.
20.5. Системы “клиент/сервер”
Как отмечалось в разделе 20.1, системы “клиент/сервер” могут рассматриваться как
частный случай распределенных систем в целом. Точнее, система “клиент/сервер” — это
распределенная система, в которой одни узлы — клиенты, а другие — серверы; все дан-
ные размещены на узлах, которые являются серверами; все приложения выполняются на
узлах-клиентах и “швы видны пользователю” (полная локальная независимость не пре-
доставляется). Обратимся к рис. 20.7 (или к рис. 2.5 из главы 2).
792
Часть V. Дополнительные аспекты
Во время написания этой книги повышенный коммерческий интерес проявлялся к
системам “клиент/сервер” и сравнительно небольшой интерес — к настоящим распреде-
ленным системам общего назначения, хотя и начали возникать тенденции к изменению
такого положения, в чем мы убедимся в следующем разделе. Мы по-прежнему считаем,
что настоящие распределенные системы будут представлять важное перспективное на-
правление, поэтому таким системам и уделено особое внимание в данной главе. Но будет
уместно рассказать кое-что и о системах “клиент/сервер”.
Напомним (см. главу 2), что термин “клиент/сервер” под-
разумевает, прежде всего, архитектуру, или логическое раз-
деление обязанностей. Клиент— это приложение, которое
также называют приложением переднего плана (frontend), а
сервер — это СУБД или приложение заднего плана
(backend). Однако именно потому, что всю систему можно
так четко разделить на две части, появилась возможность вы-
полнения ее частей на разных машинах. И эта возможность
по многим причинам оказалась настолько заманчивой
(см. главу 2), что термин “клиент/сервер” на практике подра-
зумевает исключительно случай, когда клиент и сервер дей-
ствительно размещаются на разных машинах4. Хотя это и не-
брежное использование термина, однако оно широко распро-
странено, и поэтому мы будем его придерживаться.
Напомним, что возможны несколько вариантов основ-
ной схемы.
Несколько клиентов могут совместно использовать
один и тот же сервер (фактически это обычная
практика).
Рис. 20.7. Система
“клиент/сервер ”
Отдельный клиент может иметь доступ к несколь-
ким серверам. Эта возможность, в свою очередь,
делится на два случая.
а) Клиент ограничен доступом лишь к одному серверу за один раз, т.е. каждый
отдельный запрос к базе данных должен быть ориентированным на один сер-
вер. Невозможно в пределах одного запроса получить данные с двух или более
различных серверов. Более того, пользователь должен знать, на каком именно
сервере хранятся те или иные части данных.
б) Клиент может иметь одновременный доступ к нескольким серверам,
т.е. отдельный запрос может сочетать данные с нескольких серверов. А это оз-
начает, что несколько серверов представляются клиенту так, как будто это на
самом деле один сервер. Пользователь не должен знать, какие части данных
хранятся на каждом сервере.
Но в случае б фактически описан принцип системы распределенной базы данных
(швы оказываются скрытыми). Это не совсем то, что обычно подразумевают под терми-
ном “клиент/сервер”, поэтому мы данный случай рассматривать не будем.
4 Также по очевидным соображениям используется термин “двухуровневая система”, в ос-
новном, с тем же смыслом.
Глава 20. Распределенные базы данных
793
Стандарты для систем “клиент/сервер”
Существует несколько стандартов, имеющих отношение к системам “клиент/сервер”.
Прежде всего, определенные функции для поддержки систем “клиент/сервер”
включены в стандарт языка SQL, SQL/92 [4.22]. Обсуждение этих возможностей
мы отложим до раздела 20.7.
Кроме того, имеется стандарт ISO для удаленного доступа к данным
(Remote Data Access — RDA) (см. [20.26] и [20.27]). Этот стандарт важен еще
и потому, что нечто близкое к нему уже реализовано членами группы SQL
Access Group (SAG), которая представляет союз производителей программно-
го обеспечения баз данных, принимающих идеи открытых систем и операци-
онной совместимости.
Замечание. Для наших целей не стоит тратить время на перечисление различий
между этими версиями стандарта удаленного доступа к данным. Мы будем ис-
пользовать сокращенное название RDA для общей ссылки на обе эти версии.
Задача RDA— определить форматы и протоколы для соединений в среде
“клиент/сервер”. Подразумевается, что клиент формулирует запрос к базе данных
в стандартной форме языка SQL (по существу, это подмножество стандарта
SQL/92), а сервер поддерживает стандартный каталог (также, в основном, соот-
ветствующий требованиям стандарта SQL/92). Стандарт RDA определяет кон-
кретные форматы передаваемых сообщений (SQL-запросы, данные и результаты,
диагностическая информация) между клиентом и сервером.
Третий, и последний, стандарт, который мы здесь упоминаем, — стандарт ар-
хитектуры распределенных реляционных баз данных (Distributed Relational
Database Architecture — DRJDA), предложенный компанией IBM [20.25] (он яв-
ляется стандартом де-факто, но не де-юре). Стандарты DRDA и RDA имеют
много общего, однако стандарт DRDA отличается от стандарта RDA во многих
важных отношениях. В частности, в стандарте DRDA явно проявляется тенден-
ция к отражению его происхождения в компании IBM. Например, в стандарте
DRDA клиент необязательно должен использовать стандартную версию языка
SQL и разрешено применение какого бы то ни было диалекта языка SQL. След-
ствием этого, возможно, является повышение производительности, поскольку
клиенту разрешается использовать некоторые специфические возможности сер-
вера. Но, с другой стороны, этот подход снижает возможности переносимости,
поскольку подобные специфические функции не являются скрытыми от клиен-
та, т.е. клиенту известно, с каким типом сервера он соединен. Аналогично этому
в стандарте DRDA допускается использование любых конкретных особенностей
структуры каталога сервера. Форматы и протоколы DRDA существенно отли-
чаются от форматов стандарта RDA. По существу, стандарт DRDA базируется
на собственной архитектуре и собственных стандартах IBM, в то время как
стандарт RDA основывается на международных стандартах, независимых от
конкретных поставщиков.
Более подробно эти стандарты в настоящей книге не рассматриваются. (См. [20.23] и
[20.30], где приводится их сравнительный анализ.)
794
Часть V. Дополнительные аспекты
Программирование приложений “клиент/сервер”
Необходимо отметить, что система “клиент/сервер” — это частный случай распреде-
ленных систем в целом. Как указывалось во введении к этому разделу, она может рас-
сматриваться как распределенная система, в которой все запросы создаются на одном
узле, а вся обработка выполняется на другом, если считать для простоты, что имеется
лишь один узел клиента и один узел сервера.
Замечание. Согласно этому простому определению, конечно, узел клиента вовсе не явля-
ется “узлом системы баз данных” в полном смысле этого понятия, и такая система противоре-
чит определению систем распределенных баз данных общего назначения, которое было дано
в разделе 20.2. (Узел клиента может иметь собственную локальную базу данных, однако такие
базы данных не имеют непосредственного отношения к системе “клиент/сервер” как таковой.)
Но, как бы там ни было, подход “клиент/сервер” имеет определенные особенности с точки
зрения программирования (как и распределенные системы в целом). На одну из таких особен-
ностей мы уже указывали при обсуждении распределенной обработки запросов в разде-
ле 20.3, а именно— на то, что реляционные системы по определению и по построе-
нию являются системами, в которых данные обрабатываются на уровне множеств. В систе-
мах “клиент/сервер” (как и в распределенных системах в целом) чрезвычайно важно то, что
программист, пишущий приложение, не просто “использует сервер как некоторый метод дос-
тупа” и пишет код обработки на уровне записей. Функциональность приложения в как можно
большей степени должна быть увязана с запросами на уровне множеств. В противном случае
неизбежны существенные потери в производительности системы, связанные с передачей
слишком большого количества сообщений. (В терминах языка SQL предыдущее высказыва-
ние означает, что требуется в как можно большей степени избегать использования курсоров,
т.е. циклов с оператором FETCH и форм CURRENT для операций UPDATE и DELETE. См. главу 4.)
Количество сообщений между клиентом и сервером может быть сокращено еще
больше, если система предоставляет в распоряжение пользователя некоторый механизм
поддержки хранимых процедур. Хранимые процедуры представляют, по существу,
предварительно откомпилированные программы, которые хранятся на узле сервера (и
известны серверу). Клиент обращается к хранимой процедуре с помощью механизма вы-
зова удаленных процедур (remote procedure call — RPC). Поэтому, в частности, потери
в производительности, связанные с обработкой данных на уровне записей, могут быть
частично компенсированы за счет создания подходящих хранимых процедур, позволяю-
щих выполнить обработку данных непосредственно на узле сервера.
Замечание. Хотя это и не имеет прямого отношения к теме обработки данных в сис-
темах “клиент/сервер”, необходимо отметить, что более высокая производительность —
это не единственное преимущество, которое предоставляют хранимые процедуры. Назо-
вем и другие преимущества хранимых процедур.
Хранимые процедуры могут применяться, чтобы скрыть от пользователя множе-
ство специфических особенностей СУБД и базы данных и благодаря этому дос-
тичь более высокой степени независимости данных, чем она могла бы быть в том
случае, если бы хранимые процедуры не использовались.
Одна хранимая процедура может совместно использоваться многими клиентами.
Оптимизация может быть осуществлена при создании хранимой процедуры, а не
во время выполнения. (Это преимущество, естественно, проявляется лишь в тех
системах, в которых оптимизация обычно осуществляется во время выполнения.)
Глава 20. Распределенные базы данных
795
Хранимые процедуры позволяют обеспечить более высокую степень безопасности
данных. Например, некоторому пользователю может быть разрешено вызывать
определенную процедуру, но не разрешено непосредственно обрабатывать дан-
ные, к которым он может иметь доступ через эту хранимую процедуру.
Недостатком хранимых процедур является то, что поставщики программного обеспе-
чения предоставляют в этой области слишком отличающиеся между собой средства, а
расширение языка SQL для поддержки хранимых процедур появилось, к сожалению,
лишь в 1996 году. Как указывалось в главе 4, это средство называется Persistent Stored
Modules (PSM — постоянные хранимые модули).
20.6. Независимость от СУБД
Вновь обратимся к обсуждению двенадцати общих задач систем распределенных баз
данных. Последняя из перечисленных задач предусматривала обеспечение независимо-
сти от СУБД. Как уже указывалось в разделе 20.3, предположение о строгой однород-
ности оказывается неоправданно строгим: все, что действительно необходимо, — это
поддержка любыми СУБД на различных узлах одного и того же интерфейса. Как указы-
валось в том же разделе, если, например, СУБД Ingres и Oracle поддерживают официаль-
ный стандарт SQL (не больше и не меньше!), можно будет добиться, чтобы они играли
роли партнеров в неоднородной распределенной системе. Фактически такая возмож-
ность — один из первых аргументов, который обычно приводится в пользу стандарта
языка SQL. Здесь мы рассмотрим эту возможность более подробно.
Замечание. Обсуждение будет построено конкретно на примере СУБД Ingres и
Oracle — просто для того, чтобы дать более реальное представление о состоянии дел.
Тем не менее приведенные концепции, конечно же, имеют общее применение.
Шлюзы
Предположим, что имеется два узла (X и Y), на которых установлены СУБД Ingres и
Oracle соответственно. Также предположим, что некоторый пользователь U на узле X же-
лает установить доступ к единой распределенной базе данных, содержащей данные как
из базы данных Ingres на узле X, так и из базы данных Oracle на узле Y. По определению
пользователь U — это пользователь СУБД Ingres, и, следовательно, с точки зрения дан-
ного пользователя, распределенная база данных должна быть базой данных Ingres. В ре-
зультате обязанность предоставлять необходимую функциональную поддержку ложится
на СУБД Ingres. В чем же заключается такая поддержка?
В принципе, все довольно просто: СУБД Ingres должна предоставить специальную
программу, задача которой — “сделать так, чтобы к СУБД Oracle можно было обращать-
ся, как и к СУБД Ingres”. Такие программы обычно называют шлюзами. Посмотрите на
рис. 20.85. Шлюз может функционировать на узле Ingres, на узле Oracle или (как это по-
казано на рисунке) на некотором специальном узле между двумя СУБД. Независимо от
5 Для обозначения архитектурных решений, подобных показанному на рисунке, иногда упот-
ребляется (по очевидным соображениям) термин "трехуровневая система”. Он используется
также по отношению к другим системным конфигурациям, которые аналогично включают три
отдельных компонента (в частности, обратитесь к обсуждению межплатформенного про-
граммного обеспечения, приведенному в следующем подразделе).
796
Часть V. Дополнительные аспекты
того, где именно установлен шлюз, необходимо, чтобы он обеспечивал все перечислен-
ные ниже функции. (Обратите внимание, что при реализации некоторых из этих функций
возникают весьма сложные проблемы. Однако в стандартах RD А и DRDA, которые рас-
сматривались в разделе 20.5, обращено внимание на некоторые из таких проблем.)
Рис. 20.8. Гипотетический шлюз от СУБД Ingres к Oracle
Реализация протоколов для обмена информацией между СУБД Ingres и Oracle. Такая
реализация, кроме всего прочего, должна включать средства отображения формата
сообщений, в котором отсылаются исходные операторы от СУБД Ingres, в формат,
понятный СУБД Oracle, а также средства отображения формата сообщений, в кото-
ром отсылаются результаты от СУБД Oracle, в формат, требуемый СУБД Ingres.
Предоставление возможностей “реляционного сервера” для СУБД Oracle
(функционально он аналогичен интерактивному процессору языка SQL, который в
настоящее время имеется в большинстве продуктов). Другими словами, должна
существовать возможность выполнять с помощью шлюза в базе данных Oracle
произвольные незапланированные операторы языка SQL. Для предоставления
этой функции шлюз должен обеспечивать динамическую поддержку языка SQL
или, скорее всего, интерфейс на уровне запросов (call-level interface — CLI), такой
как SQL/CLI либо ODBC на узле Oracle (см. главу 4).
Замечание. В качестве альтернативы шлюз может обеспечить непосредственное ис-
пользование интерактивного процессора языка SQL, предоставляемого СУБД Oracle.
Отображение между типами данных Ingres и Oracle. Эта задача включает ряд подзадач,
которые должны учитывать различия в процессорах (т.е. различные длины машинных
слов), различия в кодировке символов (иначе сравнения символьных строк и запросы с
предложениями ORDER BY могут дать неожиданные результаты), различия в форматах
чисел с плавающей запятой (широкоизвестная проблема), различия в поддержке дат и
времени (нет двух известных автору СУБД, которые предоставляли бы в настоящее
время идентичную поддержку в этой области) и т.д. Более подробную информацию
можно найти в [20.15], где приводится развернутое обсуждение данных вопросов.
Отображение диалекта языка SQL СУБД Ingres в диалект языка SQL СУБД Oracle,
поскольку фактически ни СУБД Ingres, ни СУБД Oracle не поддерживают точно
стандарт языка SQL в пропорции “не больше и не меньше”. На самом деле каж-
дый продукт поддерживает определенные возможности, которые не поддерживает
другой, а также есть возможности, которые в обоих продуктах имеют один и тот
же синтаксис, но различную семантику.
Глава 20. Распределенные базы данных
797
Замечание. В этой связи необходимо напомнить, что некоторые реализации шлюзов
предоставляют механизм пересылки, с помощью которого пользователь может фор-
мулировать, например, свой запрос сразу на диалекте целевой системы; этот запрос
будет передан через шлюз для выполнения целевой системой в неизмененном виде.
Отображение информации обратной связи от СУБД Oracle (коды возврата и т.д.) в
формат СУБД Ingres.
Отображение каталога СУБД Oracle в формат СУБД Ingres, чтобы узел Ingres и поль-
зователи на узле Ingres могли определить, что же содержится в базе данных Oracle.
Решение множества проблем семантического несоответствия, которые наверняка
имеются между в корне отличными системами (см., например, [20.9], [20.11], [20.16]
и [20.38]). Существуют примеры различий в способах именования (СУБД Ingres мо-
жет использовать имя атрибута EMP# там, где СУБД Oracle использует имя EMPNO);
различий в типах данных (СУБД Ingres может использовать символьную строку для
представления атрибута, который в СУБД Oracle представляется числовой величи-
ной); различий в логических представлениях информации (СУБД Ingres может не
включать кортежи, где СУБД Oracle использует NULL-значения) и т.д. и т.п.
Выполнение обязанностей участника (в варианте СУБД Ingres) в протоколе двухфаз-
ной фиксации (подразумевается, что транзакции Ingres могут выполнять обновления в
базе данных СУБД Oracle). Когда именно шлюз будет на самом деле готов выполнить
эту функцию, зависит от возможностей, предоставляемых менеджером транзакций на
узле Oracle. Стоит подчеркнуть, что на время написания этой книги коммерческие ме-
неджеры транзакций (с некоторыми исключениями) обычно не предоставляли все не-
обходимое в этом отношении, а именно — возможность для прикладных программ пе-
редавать диспетчеру транзакций команду “приготовиться к завершению транзакции”
(как альтернативу безусловной команде завершения, т.е. фиксации или отката).
Контроль блокировки на узле Oracle данных, которые требуются для узла Ingres, т.е.
проверка, действительно ли данные будут заблокированы, когда это потребуется для
узла Ingres. И опять же, будет ли шлюз на самом деле готов выполнить эту функцию,
по-видимому, зависит от ответа на вопрос, соответствует ли архитектура механизма
блокировки СУБД Oracle архитектуре механизма блокировки СУБД Ingres.
До сих пор мы рассматривали независимость от СУБД лишь в контексте реляцион-
ных систем. А как же быть с не реляционными системами? Существует ли возможность
включения не реляционного узла в не соответствующую ему реляционную распределен-
ную систему? Можно ли, например, предоставить доступ к узлу IMS из узла Ingres или
Oracle? Конечно же, такая возможность была бы очень полезной на практике, поскольку
открывала бы доступ к огромному количеству данных, хранящихся в системах СУБД
IMS и других нереляционных систем6. Но можно ли это осуществить?
Если данный вопрос означает “Можно ли это выполнить в стопроцентном объеме?”
(имеется в виду “Могут ли все не реляционные данные стать доступными из реляционно-
го интерфейса, и могут ли все реляционные операции быть применимыми к этим дан-
6 Исходя из обычного здравого смысла, можно заключить, что около 85% производственных
данных до сих пор размещены в таких системах (т.е. в не реляционных системах баз данных и
даже в файловых системах). И очень мало надежд, что пользователи будут когда-либо перено-
сить эти данные в более новые системы.
798
Часть V. Дополнительные аспекты
ным?”), то ответ будет предельно категоричным: “Нет" (по причинам, изложенным во
всех подробностях в [20.16]). Но если вопрос означает “Можно ли предоставить некото-
рый практически пригодный уровень функциональных возможностей?”, тогда, очевидно,
ответ будет— “Да”. Однако здесь мы не станем углубляться в детали. Более подробно
этот вопрос обсуждается в [20.14]—[20.16].
Промежуточное программное обеспечение для доступа
к данным
Шлюзы, которые описаны в предыдущем подразделе, иногда более конкретно назы-
ваются шлюзами типа “точка-точка". Такие шлюзы имеют ряд очевидных недостатков.
Во-первых, они предоставляют ограниченную независимость от размещения. Во-вторых,
для практически одинаковых приложений может потребоваться использовать несколько
отдельных шлюзов (скажем, один — для СУБД DB2, другой — для СУБД Oracle и тре-
тий — для СУБД Informix), не имея при этом никакой поддержки, например, для опера-
ции соединения, которая включает несколько узлов разных типов, и т.д. Вследствие это-
го (и несмотря на технические трудности, указанные в предыдущем подразделе) за не-
сколько последних лет через довольно короткие интервалы времени стали появляться
продукты, реализующие шлюзы со все более сложными функциональными возможно-
стями. Фактически все разработки, которые относились к так называемому промежу-
точному программному обеспечению (middleware) для доступа к данным или к связую-
щему программному обеспечению (mediators), теперь выделились в важное самостоя-
тельное направление в программировании. Очевидно, что указанные выше термины оп-
ределены не совсем точно. Любая часть программного обеспечения, используемая для
сокрытия различий между отдельными системами, которые предназначены для совмест-
ной работы, например монитор выполнения транзакций, может обоснованно считаться
“связующим” программным обеспечением [20.3]. Однако мы сейчас сосредоточимся на
том, что можно назвать промежуточным программным обеспечением для доступа к
данным. Примером такого программного обеспечения могут служить продукты Cohera
компании Cohera, DataJoiner корпорации IBM, а также OmniConnect и InfoHub корпора-
ции Sybase. В качестве примера рассмотрим продукт DataJoiner [20.7] (рис. 20.9).
Охарактеризовать этот продукт можно несколькими способами. С точки зрения
отдельного клиента, он выглядит, как обычный сервер базы данных (т.е. СУБД).
DataJoiner сохраняет данные, поддерживает SQL-запросы (в стиле DB2), предостав-
ляет каталог, выполняет оптимизацию запросов и т.д. (На самом деле его основой
является AIX-версия СУБД DB2 IBM.) Однако данные хранятся, главным образом,
не на узле системы DataJoiner (хотя такая возможность тоже имеется), а на любом
количестве других скрытых “за сценой” узлов, которые контролируются рядом дру-
гих СУБД (или даже менеджерами файлов, подобными, например, VSAM). Таким
образом, DataJoiner фактически предоставляет пользователю все находящиеся “за
сценой” хранилища данных в виде единой виртуальной базы данных. Кроме того,
пользователям разрешается обращаться к этим хранилищам в запросах7 на получе-
7 Ударение здесь следует сделать на слове ‘‘запросах ”. Возможности обновления по необходи-
мости несколько ограничены, особенно (но не исключительно) если система ‘‘за сценой” является,
скажем, СУБД IMS или какой-либо другой не SQL-системой (подробности, опять же, приводятся в
[20.16]). На время написания этой книги продукт DataJoiner поддерживал транзакции обновления
(с двухфазной фиксацией) только между узлами с СУБД DB2, Oracle, Sybase и Informix.
Глава 20. Распределенные базы данных 799
ние данных и применять свои знания о специфических возможностях систем “за
сценой” (а также сетевые характеристики) для составления “глобально оптималь-
ных” планов выполнения запроса.
Рис. 20.9. DataJoiner— пример промежуточного программного обеспечения для дос-
тупа к данным
Замечание. В продукте DataJoiner также эмулируются некоторые возможности язы-
ка SQL СУБД DB2 для систем, которые не поддерживают такие возможности непо-
средственно. Примером может служить опция WITH HOLD для объявления курсора
(см. главу 14).
Система, подобная описанной выше, — еще далеко не полная распределенная сис-
тема баз данных, поскольку множество узлов “за сценой” не знает о существовании
друг друга (т.е. они не могут рассматриваться как равноправные партнеры в совмест-
ном деле). Однако, если “за сценой” будет добавлен любой новый узел, он сможет ис-
пользовать все возможности, предоставляемые узлам клиентов, и, следовательно, вы-
давать запросы через соединитель DataJoiner, который гарантирует доступ к любому
узлу (или сразу ко всем остальным узлам). Значит, в целом, система составляет так на-
зываемую интегрированную систему, которая известна и как система мультибаз
данных [20.19]. Интегрированная система— это распределенная система, обычно не-
однородная, поддерживающая почти полную локальную автономию. Локальные тран-
закции в ней управляются локальными СУБД; реализация же глобальных транзак-
ций — это отдельный вопрос [20.8].
Для каждой системы “за сценой” в состав продукта DataJoiner включается компонент
соединителя', фактически это шлюз “точка-точка” в смысле, описанном в предыдущем
подразделе. (Для доступа к удаленной системе такие соединители обычно предусматри-
вают использование механизма ODBC.) Продукт DataJoiner также поддерживает гло-
бальный каталог, который используется, в частности, для определения действий в си-
туациях, когда встречается семантическое несовпадение между системами.
800
Часть V. Дополнительные аспекты
Отметим, что продукт DataJoiner может применяться сторонними поставщиками, ко-
торые разрабатывают общие средства (например, средства для написания отчетов, стати-
стические пакеты и т.д.), чтобы не слишком заботиться о различиях между теми продук-
тами СУБД, на которых предполагается их использовать.
Заключительное слово
Очевидно, что при попытках предоставить полную независимость от СУБД возника-
ют значительные проблемы, даже если все участвующие СУБД являются SQL-
системами. Однако в будущем эти усилия должны окупиться с лихвой, даже если реше-
ния будут не совсем совершенны. В настоящее время доступно несколько продуктов
промежуточного доступа к данным, и их, безусловно, будет еще больше в ближайшем
будущем. Но предупреждаем, что решения в таких продуктах неизбежно будут далеки от
совершенства, хотя поставщики утверждают обратное (предупреждение автора).
20.7. Средства SQL
В настоящее время в языке SQL отсутствует поддержка настоящих распределенных
систем. Конечно, в области обработки данных никакой поддержки и не требуется —
основная задача распределенной базы данных, с точки зрения пользователя, состоит в
том, чтобы сохранить возможности обработки данных неизменными. Тем не менее тре-
буются операции определения данных, такие как FRAGMENT, REPLICATE и т.д. [20.15]. Од-
нако до сих пор такие операции в языке SQL отсутствуют.
С другой стороны, язык SQL поддерживает некоторые возможности системы построе-
ния “клиент/сервер”, включая, в частности, операторы CONNECT и DISCONNECT для установ-
ления и разрыва соединения. В действительности SQL-приложения должны выполнять
операцию CONNECT для соединения с сервером, прежде чем они смогут выдать какой-либо
запрос к базе данных (хотя такая операция CONNECT может быть и неявной). Как только со-
единение будет установлено, приложение, т.е. клиент, сможет выдать SQL-запрос обычным
порядком и необходимая обработка базы данных будет выполнена сервером.
Язык SQL позволяет клиенту, который подключился к одному серверу, подключиться
и к другому серверу. После установления второго соединения первое соединение стано-
вится пассивным. Поэтому запросы будут выполняться вторым сервером до тех пор,
пока клиент не переключится либо на предыдущий сервер с помощью другой новой опе-
рации SET CONNECTION, либо еще на один сервер, и тогда второе соединение также ста-
нет пассивным, и т.д. Иначе говоря, в любое время у клиента имеется лишь одно актив-
ное соединение и любое количество пассивных соединений и все запросы к базе данных
от этого клиента направляются для обработки к серверу, с которым установлено актив-
ное соединение.
Замечание. Стандарт языка SQL также позволяет (но не требует), чтобы реализация
поддерживала .мультисерверные или многоканальные транзакции. В этом случае кли-
ент может переключаться с одного сервера на другой по ходу выполнения транзакции,
так что одна часть транзакции выполняется на одном сервере, а другая — на другом.
Отметим, в частности, что если для транзакции обновления разрешено охватывать не-
сколько серверов, то реализация должна, по-видимому, поддерживать некий вариант
двухфазной фиксации, чтобы обеспечить атомарность транзакции, как предусмотрено
стандартом языка SQL.
801
Глава 20. Распределенные базы данных
I
И наконец, каждое соединение, обеспечиваемое данным клиентом (то ли активное, то
ли пассивное), рано или поздно должно быть отключено с помощью соответствующей
операции DISCONNECT, хотя в простых случаях такая операция, как и соответствующая
операция CONNECT, может быть неявной.
Дополнительную информацию по данному вопросу можно найти в самом стандарте
языка SQL [4.22] или в учебном пособии по этому языку [4.19].
20.8. Резюме
В настоящей главе кратко рассматривались системы распределенных баз данных. В
качестве плана изложения использовались двенадцать целей для этих систем [20.14].
Однако еще раз подчеркнем, что не все цели равносильны во всех ситуациях. Также
здесь речь шла о технических проблемах, которые возникают в областях обработки за-
просов, управления каталогом, распространения обновлений, управления восста-
новлением и управления параллельностью. Обсуждались те вопросы, попытки реше-
ния которых должны обеспечить независимость от СУБД; в частности, в разделе 20.6
описывались шлюзы и промежуточное программное обеспечение для доступа к данным.
Затем мы познакомились с обработкой данных в системах “клиент/сервер”, которая
может рассматриваться как специальный случай распределенной обработки данных в це-
лом. Популярность подобных программных продуктов, присутствующих на рынке, по-
стоянно возрастает. В частности, в этой главе перечислялись те аспекты языка SQL, ко-
торые отвечают требованиям обработки данных в системах “клиент/сервер”, а также
подчеркивалось, что пользователи должны избегать программирования на уровне за-
писей, т.е. операций с курсором. Кратко была описана концепция хранимых процедур и
вызовов удаленных процедур.
Замечание. Одна из проблем, которую мы не обсуждали совсем, — проблема физиче-
ского проектирования базы данных для распределенных систем. На самом деле, даже
если не учитывать возможность фрагментации и репликации, проблема принятия реше-
ния о том, какие данные и на каких узлах должны храниться (так называемая проблема
размещения), известна как исключительно сложная [20.33]. Фрагментация и репликация
лишь еще больше усложняют этот вопрос.
Заслуживает упоминания тот факт, что на рынке программных продуктов стало за-
метно присутствие некоторых так называемых массовых параллельных компьютерных
систем (см. аннотацию к [17.58] в главе 17). Такие системы обычно содержат большое
количество процессоров, соединенных между собой с помощью высокоскоростной ши-
ны. Каждый процессор имеет собственную основную память, собственные дисковые на-
копители и выполняет собственную копию программного обеспечения СУБД, а полная
база данных распределяется по всему набору дисковых накопителей. Другими словами,
такие системы, по существу, представляют собой систему распределенных баз данных “в
одном пакете”. Безусловно, что для подобных систем остаются справедливыми все наши
рассуждения по таким вопросам, как стратегия обработки запросов, двухфазная фикса-
ция, ситуация глобальной взаимной блокировки и т.д.
В заключение отметим, что двенадцать целей создания распределенных баз данных
(или их подмножество, которое включает по крайней мере цели 4-6 и 8), рассматривае-
мых совместно, похоже, равносильны правилам “независимости от распределения” Код-
да (Codd) для реляционной СУБД [9.5]. Приведем это правило здесь для ссылок.
802
Часть V. Дополнительные аспекты
Независимость от распределения (Кодд): “Реляционная СУБД обладает независи-
мостью от распределения... [которая подразумевает, что] СУБД имеет подъязык
данных, который позволяет пользовательским программам и процедурам терми-
нальной обработки оставаться логически незатронутыми в следующих ситуациях.
а) Когда распределение данных вводится впервые (если первоначально установ-
ленная СУБД оперировала только нераспределенными данными).
б) Когда данные перераспределяются (если СУБД оперирует распределенными
данными)”.
И наконец отметим, что (как уже упоминалось в этой главе) цели 4-6 и 9-12, т.е. все
цели, в названии которых есть слово “независимость”, могут рассматриваться как рас-
ширение привычного понятия независимости данных на случай его применения для рас-
пределенной среды. При этом указанные принципы по сути превращаются в инструмент
защиты инвестиций в приложения.
Упражнения
20.1. Дайте определение понятиям независимости от расположения, независимости от
фрагментации и независимости от репликации.
20.2. Почему почти все системы распределенных баз данных являются реляционными?
20.3. Какими преимуществами обладают распределенные системы? Какие недостатки
им свойственны?
20.4. Объясните следующие термины.
стратегия обновления на основе первичной копии
стратегия блокировки на основе первичной копии
ситуация глобальной взаимной блокировки
двухфазная фиксация
глобальная оптимизация
20.5. Опишите схему присвоения имен объектам в системе R*.
20.6. Успешность реализации шлюзов типа “точка-точка” зависит (помимо многих дру-
гих обстоятельств) от согласования различий в интерфейсах между двумя исполь-
зуемыми СУБД. Рассмотрите любые две знакомые вам SQL-системы и укажите как
можно больше различий между их интерфейсами. Учитывайте как синтаксические,
так и семантические различия.
20.7. Исследуйте любую доступную вам систему “клиент/сервер”. Поддерживаются ли в
ней явным образом операции установления соединения CONNECT и разрыва соеди-
нения DISCONNECT? Поддерживается ли в ней операция SET CONNECTION или какие-
либо другие операции с “соединениями”? Поддерживаются ли в ней
многосерверные транзакции? Поддерживается ли в ней двухфазная фиксация? Ка-
кие форматы и протоколы используются для установки соединений типа
“клиент/сервер”? Какие типы сетевых сред в ней поддерживаются? Какое аппарат-
ное обеспечение поддерживается для узлов клиентов и узлов серверов? Какое про-
граммное обеспечение (операционная система, СУБД) поддерживается для узлов
клиентов и узлов серверов?
Глава 20. Распределенные базы данных
803
20.8. Исследуйте любую доступную вам СУБД, поддерживающую язык SQL. Поддер-
живаются ли в ней хранимые процедуры? Если поддерживаются, то как они соз-
даются? Как они вызываются? На каких языках они пишутся? Полностью ли в ни>
поддерживается стандарт языка SQL? Поддерживаются ли в них условное ветвле-
ние (IF-THEN-ELSE) и циклы? Каким образом результаты возвращаются клиенту*".
Может ли одна хранимая процедура вызвать другую? А на другом узле? Выполня-
ется ли хранимая процедура как часть вызванной транзакции?
Список литературы
20.1. Anderson Т., Breibart Y., Korth Н. F., Wool A. Replication, Consistency, and
Practicality: Are These Mutually Exclusive? // Proc. 1998 ACM SIGMOD Int. Conf, or
Management of Data. — Seattle, Wash., June, 1998.
В этой статье описаны три схемы для асинхронной репликации (называемой здесь
ленивой), схемы, которые гарантируют атомарность транзакций и их глобальную не-
прерывность без использования двухфазной фиксации. Также описывается имитаци-
онное исследование их относительной производительности. Глобальная блокировка,
предложенная в [20.21], используется только в первой схеме. В двух других схемах,
первая из которых пессимистическая, а вторая оптимистическая, используется граф
репликации. В статье делается вывод, что схемы с графом репликации превосходят
схемы с использованием блокировки “обычно с огромным преимуществом”.
20.2. Bell D., Grimson J. Distributed Database Systems. — Reading, Mass.: Addison-Wesley, 1992.
Это одно из нескольких существующих учебных пособий, посвященных теме рас-
пределенных систем (два других упоминаются в [20.10] и [20.31]). Особенностью
книги является подробное изложение учебного материала на основе примера соз-
дания сети в учреждениях здравоохранения. К тому же по сравнению с двумя сле-
дующими публикациями она является более практической.
20.3. Bernstein Р. A. Middleware: A Model for Distributed System Setvices // CACM. —
February, 1996. — 39, № 2.
Из краткого обзора: “Классифицированы различные типы межплатформенного
программного обеспечения, описаны их свойства, а также рассмотрен процесс их
изменения. Предоставлена концептуальная модель для исследования современных
и будущих распределенных систем”.
20.4. Bernstein Р. A., Rothnie J. В., Shipman D. W. (eds.). Tutorial: Distributed Data Base
Management // IEEE Computer Society. — 5855 Naplas Plaza, Suite 301, Long Beach,
Calif., 1978.
Сборник статей, сгруппированных в следующие разделы.
1. Обзор методов управления реляционной базой данных.
2. Обзор методов управления распределенной базой данных.
3. Методы обработки распределенных запросов.
4. Методы управления распределенной параллельностью.
5. Методы обеспечения надежности распределенной базы данных.
20.5. Bernstein Р. A. et al. Query Processing in a System for Distributed Databases (SDD-1) 11
ACM TODS. — December, 1981. — 6, № 4. 1
См. комментарий к [20.34].
804
Часть V. Дополнительные аспекты
20.6. Bernstein P. A., Shipman D. W., Rothnie J. B. Concurrency Control in a System for Dis-
tributed Databases (SDD-1) // ACM TODS. — March, 1980. — 5, № 1.
См. комментарий к [20.34].
20.7. Bontempo C. J., Saracco С. M. Data Access Middleware: Seeking out The Middle
Ground // InfoDB. — August, 1995. — 9, № 4.
Полезное учебное пособие, в котором внимание акцентируется на продукте
DataJoiner корпорации IBM (хотя упоминаются и другие продукты).
20.8. Breitbart Y., Garcia-Molina Н., Silberschatz A. Overview of Multi-Database Transaction
Management // The VLDB Journal. — October, 1992. — 1, № 2.
20.9. Bright Y., Hurson A. R., Pakzad S. Automated Resolution of Semantic Heterogeneity in
Multi-Databases // ACM TODS. — June, 1994. — 19, № 2.
20.10. Ceri S., Pelagatti G. Distributed Databases: Principles and Systems. — New York, N.Y.:
McGraw-Hill, 1984.
20.11. Cohen W. W. Integration of Heterogeneous Databases without Common Domains Using
Queries Bases on Textual Similarity И Proc. 1998 ACM SIGMOD Int. Conf, on Man-
agement of Data. — Seatie, Wash., June, 1998.
Описывается подход, который иногда называют “проблемой ненужных писем”. Он
позволяет определить, когда две различные текстовые строки (скажем, “AT&T Bell
Labs” и “AT&T Research”) ссылаются на один и тот же объект (подразумеваются,
конечно, определенные семантические различия). Данный подход включает воз-
можности определения схожести таких строк, “которые рассчитаны на использо-
вание модели векторного пространства, применяемой в выборке статистических
данных”. По мнению авторов статьи, быстродействие этого подхода значительно
выше, чем быстродействие “простых методов вывода”, и, кроме того, он действи-
тельно дает удивительно точные результаты.
20.12. Daniels D. et al. An Introduction to Distributed Query Compilation in R* // Distributed
Data Bases (ed. H.-J. Schneider): Proc. 2nd Int. Symposium on Distributed Data
Bases. — New York, N.Y.: North-Holland, 1982.
См. комментарий к [20.39].
20.13. Date C. J. Distributed Databases // Date C. J. An Introduction to Database Systems: Vol-
ume II. Chapter 7. — Reading, Mass.: Addison-Wesley, 1983.
Некоторые части данной главы основаны на этой более ранней публикации.
20.14. Date С. J. What is a Distributed Database System? // Date C. J. Relational Database
Writings 1985-1989. — Reading, Mass.: Addison-Wesley, 1990.
В статье введены двенадцать целей для распределенных систем (раздел 20.3 по-
строен строго в соответствии с этой статьей). Как уже упоминалось, требование
локальной автономии не может быть достигнуто на все сто процентов. Поэтому
определенные ситуации требуют принятия в этом отношении компромиссных ре-
шений, кратко перечисленных ниже.
К отдельным фрагментам переменной-отношения обычно не может быть обес-
печен непосредственный доступ даже с того узла, на котором они хранятся.
К отдельным копиям реплицируемой переменной-отношения (или фрагмента)
не может быть обеспечен непосредственный доступ даже с того узла, на кото-
ром они хранятся.
Глава 20. Распределенные базы данных
805
Пусть Р является первичной копией некоторой реплицируемой переменной-
отношения (или фрагмента) R, и пусть Р хранится на узле X. Тогда каждый узел,
который обращается к отношению R, зависит от узла X, даже если на этом узле
хранится другая копия отношения R.
К переменной-отношению, которая фигурирует в ограничении целостности для
многих узлов, нельзя осуществить доступ с целью обновления в локальном кон-
тексте узла, на котором она хранится. Это возможно только в контексте рас-
пределенной базы данных, для которой задано ограничение.
Узел, который действует как участник процесса двухфазной фиксации, должен
строго придерживаться указаний (относительно фиксации или отката) соответ-
ствующего узла-координатора.
20.15. Date С. J. Distributed Database: A Closer Look // Date C. J. and Darwen H. Relational
Database Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
Продолжение публикации [20.14], в которой более подробно обсуждаются многие
из перечисленных в этой главе двенадцати целей (хотя изложение ведется в стиле
учебного пособия).
20.16. Date С. J. Why Is It So Difficult to Provide A relation Interface to IMS? // Relational
Database: Selected Writings. — Reading, Mass.: Addison-Wesley, 1986.
20.17. Epstein R., Stonebraker M., Wong E. A Distributed Query Processing in a Relational
Database System 11 Proc. 1978 ACM SIGMOD Int. Conf, on Management of Data. —
Austin, Tx., May-June, 1978.
См. комментарий к [20.36].
20.18. Goldring R. A Discussion of Relational Database Replication Technology // InfoDB. —
1994. —8, № 1.
Прекрасный обзор асинхронной репликации.
20.19. Grant J., Litwin W., Roussopoulos N., Sellis T. Query Languages for Relational Multi-
Databases 11 The VLDB Journal. — April, 1993. — 2, № 2.
В статье предлагаются расширения реляционной алгебры и реляционного исчис-
ления в отношении систем со многими базами данных. В ней обсуждаются во-
просы оптимизации, а также показывается, что каждое выражение реляционной
алгебры для нескольких отношений имеет эквивалент в реляционном исчислении
для нескольких отношений (“обратная теорема представляет собой интересную
научную задачу”).
20.20. Gray J. N. A Discussion of Distributed Systems H Proc. Congresso AICO 79. — Bari, It-
aly, October, 1979. (Эта статья также опубликована в виде отчета: IBM Research
Report RJ2699. — 1979.)
Краткий, но очень удачный обзор и одновременно учебное пособие.
20.21. Gray J., Helland Р., O’Neil Р., Shasha D. The Dangers of Replication and a Solution //
Proc. 1996 ACM SIGMOD Int. Conf, on Management of Data. — Montreal, Canada,
June, 1996.
Цитата из резюме: “Распространение обновления в общем случае становится все бо-
лее нестабильным при увеличении рабочей нагрузки... Предлагается новый алгоритм,
предусматривающий мобильные (отсоединенные) приложения для предварительных
транзакций обновления, которые затем применяются и к главной копии”.
806
Часть V. Дополнительные аспекты
20.22. Gupta R., Haritsa J., Ramamritham K. Revisiting Commit Processing in Distributed Da-
tabase Systems 11 Proc. 1997 ACM SIGMOD Int. Conf, on Management of Data. —
Tucson, Ariz, May, 1997.
Предлагается новый протокол распределенной фиксации, называемый ОРТ, кото-
рый можно легко реализовать и использовать вместе с традиционными протокола-
ми и который “обеспечивает наиболее высокую эффективность выполнения тран-
закции для различных рабочих нагрузок и системных конфигураций”.
20.23. Hackathorn R. D. Interoperability: DRDA or RDA? // InfoDB. — 1991. — 6, № 2.
20.24. Hammar M., Shipman D. Reliability Mechanism for SDD-1; A System for Distributed
Databases 11 ACM TODS. — December, 1980. — 5, № 4.
См. комментарий к [20.34].
20.25. IBM Form №SC26-4651. IBM Corporation: Distributed Relational Database Architec-
ture Reference.
В стандарте DRDA, разработанном фирмой IBM, заданы четыре уровня функцио-
нальности распределенной базы данных.
1. Удаленный запрос.
2. Удаленная часть работы.
3. Распределенная часть работы.
4. Распределенный запрос.
Поскольку эти термины фактически стали стандартами программного обеспечения, по
крайней мере некоторой его части, здесь следует объяснить их немного подробнее.
Замечание. Термины “запрос” и “часть работы” предложены специалистами фир-
мы IBM для понятий оператор SQL и транзакция соответственно.
1. Удаленный запрос. Означает, что приложение на узле X может отослать для
выполнения отдельный SQL-оператор некоторому удаленному узлу Y. Этот
запрос полностью выполняется и фиксируется (или откатывается) на узле Y.
Исходное приложение на узле X может впоследствии отослать другой запрос
узлу Y (или, возможно, третьему узлу Z) независимо от того, был ли первый
запрос успешным.
2. Удаленная часть работы. Означает, что приложение на одном узле X может
отсылать на некоторый удаленный узел Y для выполнения все запросы к базе
данных в составе некоторой заданной “части работы” (т.е. транзакции). Таким
образом, обработка транзакции для этой базы данных выполняется целиком на
удаленном узле Y. Однако решение о том, будет ли данная транзакция заверше-
на или отменена, принимается на локальном узле X.
Замечание. Удаленная часть работы, по сути, является некоторым процессом в
системе “клиент/сервер” с единственным сервером.
3. Распределенная часть работы. Означает, что приложение на одном узле Y
может отсылать к одному или нескольким удаленным узлам Y, Z, ... для выпол-
нения некоторые запросы или все запросы к базе данных в составе некоторой
заданной “части работы” (т.е. транзакции). Таким образом, обработка транзак-
ции для этой базы данных в общем случае выполняется на нескольких узлах.
Глава 20. Распределенные базы данных
807
Причем каждый индивидуальный запрос может выполняться полностью на от-
дельном узле, а смешанные запросы — на нескольких различных узлах. Однако
локальный узел X все еще остается координатором, т.е. решение о том, будет ли
данная транзакция выполнена, принимается на этом узле.
Замечание. Распределенная часть работы фактически является некоторым про-
цессом в системе “клиент/сервер” с несколькими серверами.
4. Распределенный запрос. Это единственный из всех четырех уровней, который
наиболее близок к понятию поддержки истинной распределенной базы данных.
Понятие “распределенный запрос” означает то же самое, что и “распределенная
часть работы”, плюс разрешение на выполнение индивидуальных запросов
(SQL-операторов) к базе данных с охватом нескольких узлов. Например, со-
гласно запросу, поступившему от узла X, может потребоваться выполнить объе-
динение или соединение таблицы на узле Y и таблицы на узле Z. Отметим, что
только на этом уровне о системе можно сказать, что она обладает истинной не-
зависимостью от расположения. Во всех трех предыдущих случаях пользова-
тель должен иметь сведения о физическом расположении данных.
20.26. Документ ISO DIS 9579-1. Information Processing Systems, Open Systems Interconnection,
Remote Data Access Part 1: Generic Model, Service, and Protocol. — March, 1990.
20.27. Документ ISO DIS 9579-2. Information Processing Systems, Open Systems Intercon-
nection, Remote Data Access Part 2: SQL Specialization. — February, 1990.
20.28. Lindsay B. G. et al. Notes on Distributed Databases 11 IBM Research Report RJ2571. —
July, 1979.
Эта статья некоторыми членами команды разработчиков системы R* разделена на
пять глав.
1. Реплицируемые данные.
2. Права доступа и представления.
3. Введение в управление распределенными транзакциями.
4. Инструменты восстановления.
5. Инициирование, миграция и завершение выполнения транзакции.
В главе 1 обсуждается проблема распространения обновлений. Глава 2, за исключе-
нием нескольких замечаний в самом ее конце, почти полностью посвящена вопросам
предоставления прав доступа в нераспределенной системе (в стиле системы R). В
главе 3 очень кратко рассматриваются вопросы инициирования, миграции и завер-
шения выполнения транзакций, а также управления параллельностью и восстановле-
нием. Глава 4 посвящена восстановлению, опять же, в нераспределенной системе.
Наконец, в главе 5 более подробно обсуждается управление распределенными тран-
закциями, в частности дается детальное описание протокола двухфазной фиксации.
20.29. Mohan С., Lindsay В. G. Effecient Commit Protocols for the Tree of Processes Model of
Distributed Transaction // Proc. 2nd ACM SIGACT-SIGOPS Symposium on Principles
of Distributed Computing. — 1983.
См. комментарий к [20.39].
20.30. Newman S., Gray J. Which Way to Remote SQL? I I DBP&D. — December, 1991. — 4, № 12.
См. комментарий к [20.39].
808
Часть V. Дополнительные аспекты
20.31. Oszu M. T., Valduriez Р. Principles of Distributed Database Systems (2nd edition).—
Englewood Cliffs, N.J.: Prentice-Hall, 1999.
20.32. Rennhackkamp M. Mobile Database Replication 11 DBMS. — October, 1997. — 10, № 11.
Благодаря невысокой стоимости и портативности компьютеров, а также наличию
беспроводных коммуникаций стало возможным появление систем распределенных
баз данных нового типа, которые имеют свои специфические преимущества и не-
достатки. В частности, данные в таких системах могут быть реплицированы бук-
вально на тысячи “узлов”, но эти узлы мобильны, часто отключаются, их операци-
онные характеристики очень отличаются от характеристик обычных узлов
(например, в стоимость соединений входит и использование аккумуляторных бата-
рей, и время соединения) и т.д. Исследования таких систем начаты сравнительно
недавно (см. [20.1], [20.21]). В этой краткой статье освещены некоторые принци-
пиальные концепции и проблемы.
20.33. Rothnie J. В., Goodman N. A Survay of Research and Development in Distributed
Database Management П Proc. 3rd Int. Conf, on Very Large Data Bases. — Tokyo,
Japan, October, 1977. (Эта статья также опубликована в [20.4].)
Очень полезный обзор следующих тем.
1. Синхронизация транзакций обновления.
2. Обработка распределенного запроса.
3. Управление при неисправностях компонентов.
4. Управление каталогом.
5. Проектирование базы данных.
Последняя тема относится к проблеме физического проектирования, которая в раз-
деле 20.8 называется проблемой размещения.
20.34. Rothnie J.B. et al. Introduction to a System for Distributed Databases (SDD-1) И ACM
TODS. — March, 1980. — 5, № 1.
Работы [20.5], [20.6], [20.24], [20.34] и [20.40] связаны с ранним вариантом рас-
пределенной системы SDD-1, которая работала на нескольких компьютерах PDP-
10s фирмы DEC, подключенных к сети Arpanet. В этой системе обеспечивалась
полная независимость от размещения, фрагментации и репликации. Ниже приво-
дится несколько замечаний по поводу некоторых ее особенностей.
Обработка запросов. Оптимизатор запросов в системе SDD-1 (см. [20.5] и [20.40]) в
значительной мере использует оператор полу соединения, который упоминался в гла-
ве 6. Преимущество использования полусоединений при обработке распределенных
запросов заключается в том, что они могут привести к сокращению объема данных,
пересылаемых по сети. Предположим, например, что переменная-отношение по-
ставщиков S хранится на узле А, переменная-отношение поставок SP — на узле В, а
запрос формулируется следующим образом: “Определите результат соединения от-
ношений поставщиков и поставок”. Вместо того чтобы пересылать все отношение S
на узел В, можно выполнить перечисленные ниже действия.
Вычислить проекцию (TEMPI) переменной-отношения SP по атрибуту S# на уз-
ле В.
, Переслать проекцию TEMPI на узел А.
Глава 20. Распределенные базы данных
809
Вычислить полусоединение (ТЕМР2) проекции TEMPI и отношения S по атрибуту
S# на узле А.
Переслать полусоединение ТЕМР2 на узел В.
Вычислить полусоединение проекции ТЕМР2 и отношения SP по атрибуту S# на
узле В. В результате будет получен ответ на сформулированный выше запрос.
Эта процедура, очевидно, приведет к значительному сокращению пересылки дан-
ных по сети тогда и только тогда, когда выполняется следующее условие.
size (TEMPI) + size (ТЕМР2) < size (S)
Здесь функция size() возвращает кардинальность отношения, указанного в качестве
аргумента, умноженную на длину отдельного кортежа (скажем, в битах). Это позволяет
оптимизатору оценивать размер промежуточных результатов типа TEMPI и TEMP2.
Распространение обновления. Алгоритмом распространения обновления в сис-
теме SDD-1 предусматривается “немедленное распространение” (понятие первич-
ной копии в ней не вводится).
Управление параллельностью. Управление параллельностью основано не на
механизме блокировок, а на методе синхронизации с использованием времен-
нб/х отметок. Цель выбора этого метода состоит в попытке избежать допол-
нительных накладных расходов на отправку сообщений о блокировке, однако
расплатой за это будет относительно небольшая степень параллельности! До-
полнительные подробности в этой книге не приводятся, хотя в аннотации к
[15.3] очень кратко описана основная идея. Более подробную информацию
можно получить в [20.6] и [20.13].
Управление восстановлением. Восстановление основано на протоколе четырех-
фазной фиксации, который был выбран для того, чтобы в случае выхода из строя
координирующего узла обеспечить большую гибкость всего процесса, чем при ис-
пользовании обычного протокола двухфазной фиксации. При такой организации
управления, к сожалению, процесс, в целом, значительно усложняется. Дополни-
тельные подробности в этой книге не приводятся.
Каталог. Каталог управляется так же, как и обычные пользовательские данные,
т.е. он может быть произвольно фрагментирован, а сами фрагменты могут быть
реплицированы и распространяться произвольным образом, как и любые другие
данные. Преимущества такого подхода очевидны, а недостатки, к сожалению, со-
стоят в том, что, поскольку система не обладает никакими сведениями о располо-
жении произвольной части каталога, ей для хранения таких сведений необходимо
придерживать каталог более высокого уровня, который полностью реплицируется,
т.е. на каждом узле должна храниться его копия.
20.35. Selinger Р. G., Adiba М Е. Access Path Selection in Distributed Data Base Management
Systems // S.M. Deen and P. Hammersley. Proc. Int. Conf. On Data Bases. — Aberdeen,
Scotland; England: Heyden and Sons Ltd., 1980.
См. комментарий к [20.39].
20.36. Stonebraker M. R., Neuhold E. J. Distributed Data Base Version of Ingres // Proc. 2nd
Berkley Conf. On Distributed Data Management and Computer Networks. — Lowrence
Berkley Laboratory, May, 1977.
810
Часть V. Дополнительные аспекты
Работы [20.17], [20.36] и [20.37] связаны с прототипом распределенной системы
INGRES. Распределенная система Distributed Ingres состоит из нескольких копий
программного обеспечения University Ingres, установленных и запущенных на не-
скольких компьютерах PDP-11s фирмы DEC. Она поддерживает независимость от
расположения (как в системах SDD-1 и R*), независимость от фрагментации, реп-
ликацию данных для фрагментов и независимость от репликации. В отличие от
систем SDD-1 и R* в системе Distributed Ingres не предполагается, что передача
данных в сети обязательно должна быть медленной; наоборот, эта система спроек-
тирована как для медленных сетей дальней связи, так и для сравнительно быстрых
локальных сетей. Причем оптимизатор запросов может обнаружить разницу между
двумя этими случаями. Алгоритм оптимизации запросов является расширением
стратегии декомпозиции системы Ingres, описанной в главе 17. Более подробно он
рассматривается в [20.17].
В системе Distributed Ingres обеспечиваются два алгоритма распространения об-
новления: “эффективный” алгоритм, согласно которому обновляется первичная
копия и управление возвращается данной транзакции (причем распространение
обновлений выполняется параллельно с помощью набора подчиненных процес-
сов), а также “надежный” алгоритм, согласно которому все копии обновляются од-
новременно [20.37]. В обоих случаях управление параллельностью основано на
механизме блокировки, а управление восстановлением — на протоколе двухфаз-
ной фиксации (с некоторыми усовершенствованиями).
Что касается каталога, в системе Distributed Ingres используется полная репликация
для некоторых частей каталога, в основном тех, которые содержат логическое опи-
сание видимых для пользователя переменных-отношений, а также описание того,
как эти переменные-отношения фрагментированы. К тому же с полной репликаци-
ей комбинируются элементы локальных каталогов других частей, например опи-
сывающих локальные физические структуры хранения, локальную статистику базы
данных (используемую оптимизатором), а также ограничения целостности и пра-
вила безопасности.
20.37. Stonebraker М. R. Concurency Control and Consistency of Multiple Copies in Distributed
Ingres // IEEE Transactions on Software Engineering. — May, 1979. — 5, № 3.
См. комментарий к [20.36].
20.38. Wen-Syan Li and Clifton C. Semantic Integration in Heterogeneous Databases Using
Neural Networks // Proc. 20th Int. Conf, on Very Large Data Bases. — Santiago, Chile,
September, 1994.
20.39. Williams R. et al. R*: An Overview of the Architecture 11 P. Scheuermann. Improving
Database Usability and Responsiveness. — New York, N.Y.: Academy Press, 1982.
(Эта работа также опубликована в виде отчета: IBM Research RJ3325. —
December, 1981.)
В работах [20.12], [20.29], [20.35] и [20.39] обсуждается система R*, которая яв-
ляется распределенной версией системы System R. В системе R* обеспечивается
независимость от расположения, но не поддерживаются фрагментация и репли-
кация, а значит, не обеспечивается независимость от фрагментации и реплика-
ции. По той же причине для данной системы не возникает вопрос о распростра-
нении обновления. Управление параллельностью основано на механизме блоки-
Глава 20. Распределенные базы данных
811
ровки (обратите внимание, что существует только одна копия любого блокируе-
мого объекта; при этом вопрос о первичной копии также не возникает). Управ-
ление восстановлением основано на протоколе двухфазной фиксации, но с неко-
торыми усовершенствованиями.
20.40. Wong Е. Retrieving Dispersed Data from SDD-1: A System for Distributed Databases.
(Опубликовано в [20.4].)
См. комментарий к [20.34].
20.41. Yu С. Т., Chang С. С. Distributed Query Processing И ACM Comp. Surv. — 1984. —
16, №4.
Здесь представлен материал по методам оптимизации запросов в распределенных
системах, а также приведена обширная библиография.
812
Часть V. Дополнительные аспекты
Глава
Поддержка принятия
решений
21.1. Введение
Замечание. Первый автор этой главы — Дэвид Мак-Говерн (David McGoveren).
Системы поддержки принятия решений — это системы, которые служат для ана-
лиза деловой информации. Их назначение — помочь “выявить тенденции, определить
проблемы и предложить... разумное решение” [21.7]. Подобные системы создаются на
основе таких теорий, как исследование операций, теория поведения и научная теория
управления, а также методы статистической обработки. Первые теоретические работы в
этой области появились в конце 40-х и начале 50-х годов, т.е. задолго до того, как ком-
пьютеры приобрели широкое распространение. Основной идеей было и по-прежнему ос-
тается накопление производственных операционных данных (см. главу 1) и приведение
их к виду, в котором они могли бы использоваться для анализа хода деловых процессов
и корректировки делового поведения с целью приведения его в разумное русло. По оче-
видным причинам степень преобразования данных на первых порах была почти мини-
мальной — обычно все сводилось к составлению простых итоговых отчетов.
В конце 60-х и начале 70-х годов исследователи Гарвардского университета начали
пропагандировать использование компьютеров в процессе выработки решений [21.23].
Сначала такое использование ограничивалось в основном автоматизацией генерации
отчетов, хотя иногда предусматривались и элементарные аналитические возможности
[21.2], [21.3], [21.6], [21.26]. Первые компьютерные системы сначала назывались ав-
томатизированными системами управления, а позже — системами управления
информацией. Но мы предпочитаем современный термин— системы поддержки
принятия решений, поскольку все информационные системы, включая, например, сис-
тему оперативной обработки транзакций (OLTP), могут или должны считаться
“системами управления информацией” (в конечном счете все они используются и
влияют на управление деловыми процессами). Поэтому в дальнейшем мы будем при-
менять современную терминологию.
В 70-х годах также велись разработки нескольких языков запросов, и на их основе
было создано несколько заказных (внутренних) систем поддержки принятия решений.
Они реализовывались с применением средств генерации отчетов, таких как язык RPG,
или систем поиска данных, таких как Focus, Datatrieve и NOMAD. Эти системы были
первыми из числа тех, которые позволяли соответствующим образом подготовленным
конечным пользователям получать непосредственный доступ к банкам данных на ком-
пьютере. Иначе говоря, они позволяли пользователям формулировать производственные
запросы к банкам данных и выполнять эти запросы, не ожидая помощи от информаци-
онно-технологического подразделения.
Глава 21. Поддержка принятия решений
813
Естественно, то, что мы называем банком данных (data store), тогда чаше всего пред-
ставляло собой просто набор файлов — производственные данные хранились или в от-
дельных файлах, или в не реляционных базах данных (реляционные системы еще только
начинали разрабатываться). И даже в последнем случае данные извлекались из базы дан-
ных и копировались в файлы, прежде чем они могли быть обработаны системой под-
держки принятия решений. Так продолжалось почти до начала 80-х годов, пока для сис-
тем поддержки принятия решений вместо простых файлов не начали использоваться ре-
ляционные базы данных. На самом деле поддержка принятия решений, обработка произ-
вольных (ad hoc) запросов и выдача отчетов были первыми практическими задачами, ис-
пользовавшими реляционную технологию.
Хотя в настоящее время SQL-продукты получили широкое распространение, идея
процесса извлечения, т.е. копирования данных из одной операционной среды в какую-
либо другую среду не утратила своей значимости. Скопированные данные пользователи
могут обрабатывать, как им угодно, без вмешательства в операционную среду. И, конеч-
но, очень часто причиной выполнения таких выборок данных бывает необходимость
поддержки принятия решений.
Из вышесказанного должно быть ясно, что поддержка принятия решений не является
частью самой технологии баз данных. Это скорее одно из применений данной технологии
(хотя и очень важное), или, точнее, несколько видов такого применения, отдельных, но
связанных между собой. Перечислим эти виды: хранилища данных (data warehouse), ма-
газины данных (data mart), банки оперативных данных (operational data store), оператив-
ная аналитическая обработка (OLAP — online analytical processing), многомерные базы
данных и разработка данных. Все эти технологии поддержки принятия решений будут
рассмотрены в последующих разделах.
Предостережение. Сразу же отметим, что единственное, что объединяет упомянутые
технологии, — это то, что в них редко следуют соответствующим логическим принци-
пам проектирования. Практика систем поддержки принятия решений, к сожалению, —
вовсе не наука, как можно было представить, и часто является совершенно надуманной.
В частности, наблюдается тенденция к смещению акцентов в сторону физических, а не
логических соображений (в действительности различия между физическими и логиче-
скими аспектами в области систем поддержки принятия решений часто очень расплыв-
чаты). Отчасти именно поэтому в примерах данной главы будет использоваться язык
SQL, а не Tutorial D. Также мы будем применять “менее строгую” терминологию языка
SQL, употребляя такие термины, как “строки”, “столбцы” и “таблицы”, вместо терминов
“кортежи”, “атрибуты” и “переменные-отношения”. Также мы будем использовать тер-
мины логическая схема и физическая схема в качестве синонимов терминов концепту-
альная схема и внутренняя схема соответственно, как они были названы в главе 2.
План этой главы таков. В разделе 21.2 приводятся аспекты, связанные с практикой проек-
тирования приложений поддержки принятия решений, которые мы считаем неверными. В
разделе 21.3 описан наш собственный подход относительно этих же аспектов. Затем в разде-
ле 21.4 обсуждаются вопросы подготовки данных (т.е. процесс получения оперативных дан-
ных в том виде, в котором они могут быть пригодными для выполнения задач поддержки
принятия решений); здесь же кратко рассказывается о банках оперативных данных. В разде-
ле 21.5 рассматриваются хранилища данных, магазины данных и “многомерные схемы”. В
разделе 21.6 обсуждаются оперативная аналитическая обработка (OLAP) и многомерные базы
данных. Раздел 21.7 посвящен разработке данных, а раздел 21.8 представляет собой резюме.
814
Часть V. Дополнительные аспекты
21.2. Некоторые аспекты технологии
поддержки принятия решений
Базы данных поддержки принятия решений обладают специальными характеристи-
ками, и главная из них — база данных в основном (хотя и не всегда) только читается.
Обновление обычно ограничено периодическими операциями загрузки или обновления.
Из этих операций, в свою очередь, преобладает операция INSERT, операция DELETE вы-
полняется крайне редко, а операция UPDATE не выполняется почти никогда.
Замечание. Иногда операции обновления выполняются в некоторых подчиненных ра-
бочих таблицах, но в обычных процессах поддержки принятия решений как таковых об-
новление самой базы данных почти никогда не используется.
Приведенные ниже характеристики базы данных поддержки принятия решений также
заслуживают внимания (мы еще возвратимся к этим характеристикам в разделе 21.3 и
конкретизируем их). Отметим, что первые три из них — логические, а три оставшиеся —
физические.
. Столбцы чаще всего используются в сочетаниях.
Поддержкой целостности в общем случае не занимаются (подразумевается,
что данные должны быть корректными, поскольку после загрузки они не кор-
ректировались).
Ключи часто содержат временной компонент (глава 22).
Базы данных обычно имеют большой объем, особенно в том случае (как это чаще
всего бывает), когда данные деловых транзакций1 накапливаются в течение доста-
точно продолжительного времени.
В базе данных, как правило, интенсивно применяется индексация.
База данных часто отличается различного рода контролируемой избыточностью
(см. главу 1).
Запросы поддержки принятия решений также имеют специфические особенности, и,
в частности, обычно они довольно сложные. Ниже указано, в чем именно заключается
сложность составляемых запросов.
Сложность булевых выражений. Запросы поддержки принятия решений часто
включают сложные выражения в предложении WHERE. Эти выражения сложно за-
писывать, в них непросто разбираться и также трудно их выполнять. (В частности,
классические оптимизаторы не всегда правильно обрабатывают подобные запро-
сы, поскольку они проектируются для весьма ограниченного числа стратегий дос-
тупа.) Типичные проблемы вызывают запросы, в которых содержится значение
времени. Современные системы обычно не предоставляют удовлетворительной
поддержки, например, для таких запросов, когда требуются строки с максималь-
ным значением временной метки в заданный период времени (глава 22). Если в *
Здесь и далее в данной главе мы будем различать деловые транзакции (например, продажи
продукции) и транзакции в том смысле, который подразумевается в части IV настоящей книги.
При этом для деловых транзакций всегда будет использоваться уточнение "деловые ”, кроме тех
случаев, когда это очевидно из контекста.
Глава 21. Поддержка принятия решений
815
запросах используются какие-нибудь соединения, то они очень быстро становятся
чрезвычайно сложными. И вполне естественно, что в конечном итоге во всех этих
случаях наблюдается низкая производительность.
Сложность соединений. Для запросов в системах поддержки принятия решений
часто требуется доступ ко многим видам информации, вследствие чего в правильно
спроектированной, т.е. полностью нормализованной, базе данных при выполнении
этих запросов обычно осуществляется множество соединений. К сожалению, в тех-
нологических решениях для выполнения операций соединения никогда не преду-
сматривалось обеспечение постоянно растущих потребностей запросов в системах
поддержки принятия решений2. Поэтому проектировщики часто стремятся денор.ма-
лизовать базу данных с помощью “предварительных соединений” определенных
таблиц. Однако, как уже отмечалось в главе 12, этот подход редко приводит к успе-
ху, поскольку проектировщики в таких случаях сталкиваются со многими пробле-
мами, которые потребуется предварительно решить. И кроме того, попытки избе-
жать использования соединений могут привести к неэффективному применению ре-
ляционных операций, поскольку при этом выполнение выборки и соединения ог-
ромных объемов данных просто переносится из СУБД в приложение.
Сложность функций. В запросах систем поддержки принятия решений часто ис-
пользуются статистические и другие математические функции. Но лишь немногие
продукты их поддерживают. Поэтому часто возникает необходимость в разбиении
запроса на последовательность меньших запросов, которые затем выполняются
поочередно с пользовательскими процедурами для вычисления требуемых функ-
ций. В результате такого подхода, к сожалению, может потребоваться извлечение
больших объемов данных, не говоря уже о том, что сам запрос становится значи-
тельно сложнее как для написания, так и для понимания.
Аналитическая сложность. Деловые запросы редко можно сформулировать в виде
одного простого запроса. Чрезмерно сложные запросы представляют значительные
трудности не только для пользователей. Ограничения, свойственные конкретной
реализации языка SQL, могут не позволить системе выполнять обработку подобных
запросов. Одним из путей упрощения подобных запросов является их разбиение на
ряд меньших запросов с сохранением результатов во вспомогательных таблицах.
Указанные выше особенности как баз данных систем поддержки принятия решений,
так и выполняемых в них запросов являются причиной того, что акцент в этом случае
переносится на проектирование с точки зрения повышения производительности, осо-
бенно — производительности пакетного добавления данных и произвольного извлечения
данных. Однако, на наш взгляд (который подробно излагается следующем разделе), та-
2 Автор этой главы (Мак-Говерн), работавший над системой поддержки решений в 1981 го-
ду, в результате собственных наблюдений выяснил, что для соединения трех таблиц даже сред-
них размеров вполне может потребоваться много часов. Соединение же от четырех до шести
таблиц вообще обходится слишком дорого. В современных компьютерах соединение от шести
до десяти очень больших таблиц — обычное дело, и технологией это также, как правило, преду-
смотрено. Однако достаточно просто (и в этом нет ничего необычного) генерировать запросы,
при выполнении которых потребуется соединить столько таблиц, сколько технологически не-
возможно обработать. Запрос на соединение более двенадцати таблиц, скорее, похож на аван-
тюру, но необходимость выполнения подобных запросов встречается довольно часто.
816
Часть V. Дополнительные аспекты
кое состояние дел должно влиять на физическое проектирование, а не на логическое. К
сожалению, как уже отмечалось в разделе 21.1, разработчики и пользователи систем
поддержки принятия решений часто делают ошибку, неверно различая логические и фи-
зические аспекты проектирования3. Фактически они часто вовсе отказываются от созда-
ния логического проекта системы. Вследствие этого, столкнувшись с перечисленными
выше сложностями, они оказываются неподготовленными к ним, и это чаще всего при-
водит к непреодолимым трудностям при попытках сохранить равновесие между кор-
ректностью, возможностью сопровождения, производительностью, возможностью рас-
ширения, эффективностью и практичностью.
21.3. Проектирование базы данных поддержки
принятия решений
Как утверждалось ранее, в частности во введении к части III, по нашему мнению, про-
ект базы данных всегда должен быть выполнен на двух уровнях: логическом и физическом.
1. Прежде всего должен быть выполнен логический проект. На этом уровне основное
внимание уделяется реляционной корректности. Таблицы должны представлять пра-
вильные отношения, гарантируя таким образом, что реляционные операции будут
выполняться так, как им надлежит выполняться, и не будет никаких непредсказуемых
результатов. Далее должны быть описаны домены (типы), на основе доменов опреде-
лены столбцы и указаны зависимости между столбцами (функциональные и др.). На
основании этих данных может быть выполнена нормализация и определены ограни-
чения целостности.
2. Затем создается физический проект, который должен быть производным от логиче-
ского проекта. На этом уровне, конечно, основное внимание уделяется эффектив-
ности хранения данных и производительности. В принципе, допустимо любое
расположение данных при условии, что между логической и физической схемами
имеется сохраняющее информацию преобразование, поддающееся выражению с
помощью реляционной алгебры [2.5]. Отметим, в частности, что из наличия такого
преобразования следует, что существуют реляционные представления физической
схемы, которые отображают ее подобно логической схеме, и наоборот.
Безусловно, логическая схема может впоследствии изменяться, например с целью
включения новых видов данных и новых или только что обнаруженных зависимостей.
Внесенные изменения, естественно, потребуют также соответствующих изменений в фи-
зической схеме. Но этот вопрос нас здесь не беспокоит. Нас больше волнует то, что фи-
зическая схема может измениться, в то время как логическая схема будет оставаться
прежней. Например, предположим, что операция соединения таблиц SP (Поставки) и Р
(Детали) в значительной степени преобладает по сравнению с другими схемами доступа
к данным. Тогда у нас мог бы возникнуть соблазн “предварительно соединить” таблицы
3 Особенно виновны в этом специалисты по хранилищам данных и оперативной аналитической
обработке (OLAP). Они часто утверждают, что реляционный проект просто “непригоден" для
систем поддержки принятия решений, а реляционная модель не способна обеспечить выборку дан-
ных и ее нужно обойти. Такие аргументы почти всегда основываются на неверном понимании раз-
личий между собственно реляционной моделью и ее физическим представлением.
Глава 21. Поддержка принятия решений
817
SP и Р на физическом уровне, сократив таким образом количество операций ввода-
вывода и расходы на соединения этих таблиц. Но логическая схема должна оставаться
неизменной, если достигнута физическая независимость данных. (Конечно, оптимизатор
запросов должен знать о существовании хранимого “предварительного соединения” и
действовать соответственно, чтобы получить желаемое повышение производительно-
сти.) Кроме того, если модель доступа затем изменится на преобладающий доступ к от-
дельным таблицам вместо их соединения, должна существовать возможность вновь из-
менить физическую схему, чтобы физически разъединить таблицы SP и Р, опять же, без
какого-либо влияния на логический уровень.
Из сказанного выше должно быть ясно, что проблема обеспечения независимости фи-
зических данных— это, в основном, проблема обновления представления поддержки
(исключая проблему обновления фрагментов, которая обсуждалась в главе 20 и имеет
совсем другой смысл во всей архитектуре системы). Как мы убедились в главе 9, теоре-
тически все реляционные представления обновляемы. Следовательно, теоретически, если
физическая схема является производной от логической схемы в смысле, который имелся
в виду выше, будет достигнута максимальная физическая независимость данных. Любое
обновление, выраженное в терминах логической схемы, будет автоматически трансли-
руемым в обновление, выраженное в терминах физической схемы, и наоборот, а сами
изменения физической схемы не будут требовать изменений в логической схеме.
Замечание. Отметим, что единственной причиной подобных изменений в физической
схеме должно быть обеспечение эффективности хранения данных и повышение общей
производительности системы.
Однако, к сожалению, современные SQL-продукты не поддерживают в необходимой
мере обновление представлений. Поэтому набор допустимых физических схем в этих
продуктах очень (и совершенно излишне) ограничен. Говоря конкретнее, если мы на ло-
гическом уровне рассматриваем базовые таблицы как представления, а хранимые версии
этих “представлений” на физическом уровне — как базовые таблицы, физическая схема
должна быть такой, чтобы рассматриваемый продукт мог реализовать все логически
возможные обновления таких “представлений” в терминах этих “базовых таблиц”.
Замечание. На практике это возможно благодаря моделированию подходящего меха-
низма обновления представления средствами хранимых процедур, триггерных процедур,
промежуточного программного обеспечения или различных их сочетаний. Однако обсу-
ждение этих методов выходит за рамки данной главы.
Логическое проектирование
Правила логического проектирования не зависят от предполагаемого использования
базы данных. То же самое относится ко всем без исключения видам приложений. Следо-
вательно, в частности, должно быть все равно, какими являются эти приложения: опера-
тивными (OLTP) или приложениями поддержки принятия решений. В любом случае
должна использоваться одна и та же процедура. Еще раз рассмотрим три логические ха-
рактеристики баз данных поддержки принятия решений, определенные в начале разде-
ла 21.2, а также рассмотрим их следствия для логического проектирования.
Использование сочетаний столбцов и уменьшение количества зависимостей
В запросах поддержки принятия решений, а также в обновлениях, если они при-
менимы, сочетания столбцов часто рассматриваются как единое целое. Имеется в
виду, что к входящим в состав подобных сочетаний столбцам никогда не обраща-
818
Часть V. Дополнительные аспекты
ются по отдельности (наглядным примером может служить адрес ADDRESS). Усло-
вимся называть такие сочетания столбцов составными столбцами. Но с логиче-
ской точки зрения подобные составные столбцы ведут себя так, как будто на са-
мом деле они не составные. Предположим, что СС — это составной столбец и С —
какой-либо иной столбец в той же таблице. Тогда зависимости между столбцом С
и компонентами столбца СС сводятся к одной зависимости между столбцом С и со-
ставным столбцом СС как единым целым. Более того, зависимости, включающие
компоненты составного столбца СС и не включающие никакие другие столбцы, из-
лишни и могут просто игнорироваться. В результате общее число зависимостей
сокращается и логический проект становится проще, с меньшим количеством
столбцов и, возможно, даже с меньшим числом таблиц.
Замечание. Стоит еще упомянуть о том, что полная и эффективная поддержка со-
ставных столбцов— задача нетривиальная и зависит от типов, определенных
пользователем. Дополнительный материал по этому вопросу можно найти в
[21.11], а также в главах 5 и 25.
Общие ограничения целостности
Как уже объяснялось, базы данных поддержки принятия решений, главным обра-
зом, только читаются и ограничения целостности проверяются при загрузке (или
обновлении) базы данных. Поэтому часто полагают, что нет никакого смысла в
объявлении ограничений целостности в логической схеме. Однако это звучит не-
убедительно. Если база данных действительно лишь читается, такие ограничения
на самом деле не могут быть нарушены. Но нельзя недооценивать семантическое
значение этих ограничений. Как уже отмечалось в разделе 8.10 главы 8, ограниче-
ния служат для определения смысла таблиц и всей базы данных в целом. Опреде-
ление ограничений предоставляет способ передачи пользователям смысла данных,
а значит, помогает им в формулировании запросов. Кроме того, объявление огра-
ничений может предоставлять критически важную информацию для оптимизатора
(см. обсуждение семантической оптимизации в разделе 17.4 главы 17).
Замечание. В некоторых SQL-продуктах объявление определенных ограничений
приводит к автоматическому созданию соответствующих индексов и других меха-
низмов обеспечения, что может существенно увеличить стоимость загрузки и по-
полнения базы данных. В свою очередь, для проектировщиков это может послу-
жить поводом для отказа от объявлений ограничений. И снова повторим, что эта
проблема возникает из-за путаницы между логическими и физическими аспектами
проектирования. Должна существовать возможность определить ограничения це-
лостности декларативно, на логическом уровне, и независимо указать соответст-
вующий механизм их обеспечения на физическом уровне. К сожалению, совре-
менные SQL-продукты неудовлетворительно проводят разграничение между ло-
гическим и физическим уровнями (более того, разработчики этих продуктов вряд
ли осознают семантическое значение ограничений вообще).
Временные ключи
Оперативные базы данных обычно содержат только текущие данные. Базы данных
поддержки принятия решений, наоборот, обычно содержат архивы исторически
накопленных данных, и поэтому большая часть или даже все данные включают
временной штамп или временную отметку. Ключи в таких базах данных часто
Глава 21. Поддержка принятия решений
819
содержат столбец с подобной отметкой. Например, вновь обратимся к нашей базе
данных поставщиков и деталей. Предположим, что необходимо расширить ее так,
чтобы для каждой поставки был известен конкретный месяц (от 1 до 12), когда
поставка производилась. В этом случае таблица поставок SP может выглядеть, как
показано на рис. 21.1. Обратите внимание, что дополнительный столбец MID
(идентификатор месяца) входит в состав ключа расширенной версии таблицы SP.
Теперь при формулировке запросов, включающих таблицу SP, нужно будет учи-
тывать, что данные имеют различные временные отметки (кроме тех случаев, ко-
нечно, когда в запросе этого специально не нужно учитывать). Мы уже коснулись
данного вопроса в разделе 21.2, а в главе 22 рассмотрим его более детально.
Замечание. В результате добавления столбцов с временными метками может воз-
никнуть необходимость в корректировке проекта базы данных. Предположим, на-
пример, хотя это и несколько надуманно, что количество деталей в каждой по-
ставке зависит от месяца, когда эта поставка производилась (на рис. 21.1 данные
соответствуют этому ограничению). Тогда пересмотренная версия таблицы SP бу-
дет удовлетворять функциональной зависимости MID —» QTY, но не будет удовле-
творять условиям пятой нормальной формы и даже третьей нормальной формы.
Поэтому она должна быть нормализована, как показано на рис. 21.2. К сожале-
нию, проектировщики баз данных поддержки принятия решений редко беспокоят-
ся о том, чтобы учитывать такие включаемые зависимости.
S# P# MID QTY
S1 Р1 3 300
S1 Р1 5 100
S1 Р2 1 200
S1 РЗ 7 400
S1 Р4 1 200
S1 Р5 5 100
S1 Р6 4 100
S2 Р1 3 300
S2 Р2 9 400
S3 Р2 6 200
S3 Р2 8 200
S4 Р2 1 200
S4 Р4 8 200
S4 Р5 7 400
S4 Р5 11 400
Рис. 21.1. Пример таблицы SP, включающей поле идентификатора месяца
Физическое проектирование
В разделе 21.2 было отмечено, что базы данных поддержки принятия решений, как
правило, большие и чрезмерно индексированные, а также часто включают различные ви-
ды контролируемой избыточности. В этом подразделе кратко рассматриваются вопро-
сы, касающиеся физического проектирования.
820
Часть V. Дополнительные аспекты
SP S# P# MID MONTH_QTY MID QTY
S1 Р1 3 1 200
S1 Р1 5 2 600
S1 Р2 1 3 300
S1 РЗ 7 4 100
S1 Р4 1 5 100
S1 Р5 5 6 200
S1 Р6 4 7 400
S2 Р1 3 8 200
S2 Р2 9 9 400
S3 Р2 6 10 100
S3 Р2 8 11 400
S4 Р2 1 12 50
S4 Р4 8
S4 Р5 7
S4 Р5 11
Рис. 21.2. Нормализованный аналог таблицы SP, представленной на рис. 21.1
Сначала разберемся в разбиении таблиц на разделы, что иначе называется фрагмента-
цией. Фрагментация представляет собой возможный подход к решению проблемы
“больших баз данных”. Каждая таблица делится на группу непересекающихся разделов или
фрагментов, предназначенных для независимого физического хранения (см. обсуждение
вопроса о фрагментации в главе 20). Такое разделение может существенно расширить воз-
можности управления и доступа к данной таблице. Обычно за каждым разделом закрепля-
ются определенные выделенные (в той или иной степени) ресурсы, например диск или
процессор, вследствие чего конкуренция между разделами за такие ресурсы минимизиру-
ется. Таблицы разделяются горизонтально4 с помощью функции разделения, которая ис-
пользует значения выбранных столбцов, составляющих ключ раздела, в качестве аргумен-
тов, а возвращает номер раздела или его адрес. Такие функции обычно поддерживают раз-
деление по диапазонам (range), кэшированное (hash) разделение, круговое (round-robin)
разделение и прочие виды разделения (см. аннотацию к [17.58] в главе 17).
Теперь обратимся к индексированию. Известно, что, используя подходящий индекс,
можно резко сократить количество физических операций чтения. В ранних SQL-продуктах
предоставлялся лишь один вид индексов, а именно — индексы, представленные в виде В-
деревьев. Позже, через несколько лет, стали применяться и некоторые другие виды индек-
сов, особенно в связи с использованием баз данных поддержки принятия решений. Среди
них наибольшее распространение получили битовые отображения, кэш-индексы, муль-
титабличные индексы, булевы индексы, функциональные индексы, а также уже известные
нам индексы в виде В-деревьев. Рассмотрим каждый из этих видов индексов.
Индексы в виде В-деревьев. Индексы в виде В-деревьев предоставляют эффектив-
ный доступ для запросов диапазонов значений, за исключением случаев, когда ко-
личество подходящих строк становится слишком большим. Обновление В-
деревьев относительно эффективно.
4 Хотя вертикальное разделение также может иметь определенные преимущества, здесь
оно не рассматривается, поскольку большинство продуктов его не поддерживает.
Глава 21. Поддержка принятия решений
821
Индексы в виде битовых отображений. Предположим, что в индексированной
таблице Т содержится л строк. Тогда индекс в виде битового отображения для
столбца С таблицы Т будет содержать вектор из л бит для каждого значения в до-
мене столбца С и установленный бит будет соответствовать строке R, если в ее
столбце С будет содержаться соответствующее значение. Такие индексы эффек-
тивны для запросов, содержащих набор значений, однако их эффективность сни-
жается, когда этот набор становится слишком большим. Обратите внимание, что
несколько реляционных операций (соединение, объединение, ограничение равен-
ства и т.п.) могут быть выполнены исключительно с индексами посредством буле-
вых операций (AND, OR, NOT) над битовыми векторами. Доступ к реальным данным
не требуется совсем, если не нужен конечный результирующий набор. Обновле-
ние индексов битовых отображений относительно неэффективно.
Кэш-индексы (они также называются кэш-адресацией или просто кэшированием).
Кэш-индексы эффективны для доступа к конкретным строкам, а не к диапазонам.
Вычислительная стоимость линейно зависит от количества строк, поскольку для
кэш-функции не требуется расширение, чтобы разместить дополнительные клю-
чевые значения. Кэширование может также использоваться для эффективной реа-
лизации соединений, как описано в главе 17.
Мультитабличные индексы (иногда они называются индексами соединений). По
существу, элемент мультитабличного индекса содержит указатели на строки в не-
скольких таблицах вместо простых указателей на строки в одной таблице. Такие ин-
дексы позволяют повысить производительность операций соединения и ускорить
проверку ограничений целостности для нескольких таблиц (т.е. для базы данных).
Булевы индексы (более известные как индексы выражений). Булев индекс указы-
вает, для каких строк определенной таблицы определенное логическое выражение
(включающее столбцы рассматриваемой таблицы) будет истинным. Такие индек-
сы чрезвычайно полезны, если соответствующее логическое выражение является
обычным компонентом условия выборки.
Функциональные индексы. Функциональные индексы индексируют строки табли-
цы не на основе значений в этих строках, а на основе результата применения к
этим значениям некоторой функции.
В дополнение к сказанному следует отметить, что предлагаются еще и различные виды
смешанных или гибридных индексов, представляющих собой сочетание перечисленных выше
индексов. Смысл таких гибридов трудно изложить в общих словах. Также предлагается мно-
жество специализированных видов индексов, таких как R-деревья, которые предназначены для
обработки геометрических данных. В этой книге мы не будем пытаться решить такую устра-
шающую задачу, как описание всех видов индексов; заинтересованным читателям можем
предложить обратиться к [25.27], где содержится исчерпывающее изложение этой темы.
И наконец рассмотрим вопрос контролируемой избыточности. Контролируемая из-
быточность — это важный инструмент сокращения количества операций ввода-вывода и
минимизации конкурентного доступа к данным в базе. Как пояснялось в главе 1, избы-
точность контролируема, если она управляется СУБД и скрыта от пользователей.
(Отметим, что по определению избыточность, которая должным образом контролирует-
ся на физическом уровне, не видима на логическом уровне и поэтому не влияет на кор-
ректность на логическом уровне.) Существует два общих вида такой избыточности.
822
Часть V. Дополнительные аспекты
Первый вид включает обслуживание точных копий или реплик базы данных.
Замечание. Управление копированием, которое может рассматриваться как менее
амбициозная форма репликации, также широко поддерживается (см. ниже).
Второй вид включает обслуживание производных данных в дополнение к базе
данных. Наиболее часто используется в форме итоговых таблиц и расчетных
(или вычисленных, или производных) столбцов.
Рассмотрим каждый из этих видов по порядку.
Основные понятия репликации были рассмотрены в разделах 20.3 и 20.4 главы 20 (см., в
частности, подраздел “Распространение обновлений” в разделе 20.4). Здесь мы просто повто-
рим несколько основных пунктов из этих разделов и выскажем некоторые дополнительные
замечания. Прежде всего напомним, что репликация может быть синхронной и асинхронной.
В случае синхронной репликации, если данный дубликат обновлен, все другие
дубликаты того же элемента данных также должны быть обновлены в той же
транзакции. Логически это означает, что существует лишь одна версия данных. В
большинстве продуктов синхронная репликация реализуется с помощью
триггерных процедур (возможно, скрытых и системно управляемых). Однако син-
хронная репликация имеет тот недостаток, что она создает дополнительную на-
грузку при выполнении всех транзакций, в которых обновляются какие-либо реп-
лики (кроме того, могут возникать проблемы, связанные с доступностью данных).
В случае асинхронной репликации обновление одного дубликата распространяется
на другие спустя некоторое время, а не в той же транзакции. Таким образом, при
асинхронной репликации вводится задержка или время ожидания, в течение ко-
торого отдельные реплики могут быть фактически не идентичными (т.е. термин
“реплики” оказывается не совсем верным, поскольку мы имеем дело не с точными
копиями). В большинстве продуктов асинхронная репликация реализуется посред-
ством чтения журнала транзакций или постоянной очереди обновлений, которые
подлежат распространению.
Преимущество асинхронной репликации состоит в том, что дополнительная нагруз-
ка от репликации разъединена с транзакциями обновлений, которые могут быть кри-
тичны ко времени выполнения и весьма чувствительны к требуемому уровню произ-
водительности. К недостаткам этой схемы относится то, что данные могут оказаться
несовместимыми (т.е. несовместимыми с точки зрения пользователя). Например, из-
быточность может проявляться на логическом уровне, а это, строго говоря, означает,
что термин “контролируемая избыточность” в таком случае неприемлем5.
5 Следует отметить, что может возникнуть такая ситуация, когда будет трудно избе-
жать или предупредить возможную несовместимость отдельных реплик. В частности, кон-
фликт может возникнуть из-за порядка, в котором выполняются обновления. Пусть, например,
в транзакции Т1 выполняется вставка строки в реплику RX, а затем в транзакции Т2 эта строка
удаляется, и пусть RY— это реплика таблицы RX. Если обновления будут распространены на
таблицу RY, но поступят к таблице RY в обратном порядке (например, из-за задержек в мар-
шрутизации), то транзакции Т2 нечего будет удалять, а позже в транзакции Т1 будет вставле-
на подлежащая удалению строка. В конечном счете реплика RY будет содержать данную стро-
ку, а реплика RX— нет. Разрешение конфликтов и достижение совместимости между реплика-
ми — это сложная проблема, которая в этой книге не обсуждается.
Глава 21. Поддержка принятия решений
823
Следует отметить, что по крайней мере в коммерческом мире термин “репликация”
стал означать преимущественно (или даже исключительно) асинхронную репликацию
(как уже отмечалось в главе 20).
Основное различие между репликацией и управлением копированием заключа-
ется в следующем. Если используется репликация, то обновление одной реплики в
конечном счете распространяется на все остальные “автоматически”. В режиме
управления копированием, напротив, не существует такого автоматического распро-
странения обновлений. Копии данных создаются и управляются с помощью группо-
вого или фонового процесса, который разделен по времени от обновляющих тран-
закций. Управление копированием, в общем, более эффективно по сравнению с реп-
ликацией, поскольку за один раз могут копироваться большие объемы данных. К не-
достаткам можно отнести то, что большую часть времени копии данных не будут
идентичны данным базы, поэтому пользователи должны знать, когда эти данные
синхронизированы. Обычно управление копированием упрощается благодаря требо-
ванию, чтобы обновления применялись в соответствии со схемой “первичной ко-
пии” того или иного вида (см. главу 20).
Теперь рассмотрим другой вид избыточности — расчетные столбцы и итоговые
таблицы. Эти конструкции особенно важны в контексте систем поддержки принятия
решений. В них содержатся предварительно подсчитанные значения данных — значе-
ния, которые вычисляются на основе других данных, хранящихся где-то в базе дан-
ных. Ясно, что такие конструкции позволяют избежать необходимости каждый раз по-
вторно вычислять эти значения, когда они понадобятся в каком-то запросе. Расчетный
столбец — это такой столбец, значение которого в данной строке является производ-
ным от других значений в той же строке6. Итоговая таблица — это таблица, в кото-
рой содержатся совокупные или обобщенные значения (сумма, среднее значение, ко-
личество строк и т.п.), вычисленные на основе значений в других таблицах. Такие ито-
ги часто предварительно вычисляются для нескольких различных групп одних и тех
же детальных данных (см. раздел 21.6).
Замечание. Если расчетные столбцы и итоговые таблицы действительно явля-
ются экземплярами контролируемой избыточности, то они должны быть полно-
стью скрыты от пользователей, хотя в современных продуктах это правило обыч-
но не соблюдается.
Итоговые таблицы и расчетные столбцы чаще всего реализуются с помощью
триггерных процедур, управляемых системой, хотя они могут быть реализованы и с по-
мощью пользовательских процедур. В первом случае автоматически поддерживается со-
гласованность между данными базы и производными данными, поскольку и те, и другие
обновляются в одной и той же транзакции. (Она может либо выполниться, либо не вы-
полниться, но даже если транзакция завершится успешно, для сохранения согласованно-
сти может оказаться критически важным наличие в системе высокого уровня изоляции
транзакций.) В последнем случае, вероятнее всего, устранение возможной несогласован-
ности будет возложено на пользователя.
6 Возможен и другой подход, при котором вычисленное значение является производным от
значений в нескольких строках той же таблицы или даже в других таблицах. Однако в этом слу-
чае обновление одной строки может повлечь обновление многих других строк, в частности мо-
жет очень негативно отразиться на операциях загрузки и обновления базы данных.
824
Часть V. Дополнительные аспекты
Распространенные ошибки проектирования
В этом подразделе мы вкратце прокомментируем ошибки проектирования в среде
поддержки принятия решений, которые широко распространены на практике.
Дублирование строк. Проектировщики систем поддержки принятия решений час-
то утверждают, что их данные просто не имеют уникальных идентификаторов, и
поэтому допускается дублирование строк. В [5.3] и [5.6] подробно объясняется,
почему разрешение дубликатов является ошибкой. Здесь же мы просто отметим,
что эта “необходимость” возникает из-за того, что физическая схема не является
производной от логической схемы, которая, возможно, никогда и не создавалась.
Также заметим, что в таком проекте строки часто имеют неоднородное значение,
в особенности если в них присутствуют NULL-значения. Иначе говоря, не все
строки являются экземплярами одного и того же предиката (см. раздел 3.4 гла-
вы 3, а также главу 18).
Замечание. Иногда дубликаты допускаются преднамеренно, особенно если проек-
тировщик использует объектно-ориентированную среду (см. последний абзац в
разделе 24.2 главы 24).
Денормализация и связанные с ней действия. При необоснованном стремлении
исключить соединения и тем самым сократить количество операций ввода-вывода
проектировщики часто выполняют предварительные соединения таблиц, вводят
различного рода производные столбцы и т.д. Такая практика может быть прием-
лемой на физическом уровне, но только не тогда, когда все это проявляется на ло-
гическом уровне.
Схемы типа “звезда”. Схемы типа “звезда”, или так называемые многомерные
схемы, чаще всего возникают в результате попытки “предельно упростить” кор-
ректные методы проектирования. Однако от таких упрощений нельзя ожидать ка-
кого-либо выигрыша. В результате при росте базы данных часто снижается произ-
водительность и теряется гибкость, а разрешение возникающих трудностей по-
средством физического перепроектирования требует внесения изменений и в при-
ложения, поскольку схемы типа “звезда” — это в действительности чисто физиче-
ские схемы, хотя они и открыты для приложений. В общем случае проблема за-
ключается в произвольной и необоснованной природе созданного проекта.
Замечание. Схемы типа “звезда” будут подробно рассматриваться в разделе 21.5.
NULL-значения. Проектировщики часто пытаются сберечь пространство, допуская
наличие в столбцах NULL-значений. Этот прием может сработать, если столбец
имеет тип данных переменной длины, а NULL-значения на физическом уровне
представляются пустыми строками. Однако в общем случае такие попытки будут
неправильными. Не только просто возможно (и желательно) проектировать так,
чтобы избежать появления NULL-значений [18.20], но это часто и существенно
выгоднее, поскольку в результате память используется более эффективно и дости-
гается более высокая производительность операций ввода-вывода.
Проектирование итоговых таблиц. Логическое проектирование итоговых таблиц не-
редко игнорируется, вследствие чего возникают неконтролируемая избыточность и
трудности с поддержанием согласованности данных в базе. В результате пользователи
сталкиваются с затруднениями при интерпретации суммарных значений и формули-
Глава 21. Поддержка принятия решений
825
ровке запросов с их участием. Чтобы избежать подобных проблем, все итоговые таб-
лицы, относящиеся к одному и тому же уровню обобщения (раздел 21.6), необходимо
спроектировать так, как если бы они составляли отдельную базу данных. В этом случае
определенные проблемы циклического обновления могут быть решены посредством
запрещения обновлений на уровне обобщенных данных и организации синхронизации
итоговых таблиц исключительно на основе данных детального уровня.
Множественные пути доступа. Проектировщики систем поддержки принятия ре-
шений и их пользователи часто ошибочно говорят о “множественности путей досту-
па” к некоторым необходимым им данным, подразумевая, что одни и те же данные
могут быть получены несколькими разными реляционными выражениями. Иногда
такие выражения действительно равносильны, как в случае, например, A JOIN (В
JOIN С) и (A JOIN В) JOIN С (см. главу 17). Иногда они равносильны благодаря
действию некоторого ограничения целостности (снова см. главу 17), а иногда на са-
мом деле они оказываются вовсе не равносильными. Для иллюстрации последнего
случая предположим, что таблицы А, В и С имеют общий столбец К. Тогда “путь сле-
дования по значениям в столбце К от А к В, а оттуда к С”, определенно, не то же са-
мое, что “путь следования по значениям в столбце К напрямую от А к С”.
Ясно, что в таких ситуациях пользователи могут быть поставлены в тупик. Они не
знают, какое именно выражение необходимо применять и будут ли одинаковыми
полученные результаты. Конечно, частично эта проблема может быть решена за
счет дополнительного обучения пользователей. Еще часть проблемы можно ре-
шить за счет обеспечения правильной работы оптимизатора. Однако часть про-
блемы возлагается и на проектировщиков, которые разрешают избыточность в ло-
гической схеме и/или предоставляют пользователям непосредственный доступ к
физической схеме. Следует отметить, что эта часть проблемы может быть решена
только за счет правильного проектирования.
В заключение отметим, что, по нашему мнению, многие затруднения при проектиро-
вании, якобы возникающие из-за специфических требований систем поддержки приня-
тия решений, могут быть успешно преодолены в результате строгого следования пра-
вильному подходу. В действительности большинство подобных проблем вызвано именно
отказом от строгого следования правильному подходу, но, по правде говоря, эти затруд-
нения часто усугубляются еще и проблемами, свойственными самому языку SQL.
21.4. Подготовка данных
Многие из вопросов, связанных с системами поддержки принятия решений, в первую
очередь, касаются задач получения и подготовки данных. Эти данные следует извлечь из
разных источников, очистить, преобразовать и консолидировать, после чего загрузить
в базу данных поддержки принятия решений. Впоследствии загруженные данные долж-
ны периодически обновляться. Каждая операция заслуживает отдельного обсуждения7.
Рассмотрим каждую из них поочередно, а затем завершим раздел кратким обсуждением
банков оперативных данных.
7 Отметим, между прочим, что в этих операциях часто могли бы использоваться преимуще-
ства обработки на уровне множеств, свойственные реляционным системам, хотя на практике
это происходит редко.
826
Часть V. Дополнительные аспекты
Извлечение данных
Извлечение данных — это процесс выборки данных из оперативных баз данных и
других источников. Для извлечения данных существует множество инструментов, вклю-
чая утилиты, предоставляемые системой, пользовательские программы извлечения и
коммерческие продукты извлечения данных (общего назначения). В процессе извлечения
обычно интенсивно используется система ввода-вывода, что может послужить помехой
для выполнения критически важных операций. Поэтому извлечение данных часто осу-
ществляется в параллельном режиме (т.е. как множество параллельно выполняемых
подпроцессов) и на физическом уровне. Однако такое “физическое извлечение” может
вызвать проблемы при последующей обработке, поскольку они могут сопровождаться
потерей информации (особенно — данных о связях), которая представляется каким-либо
физическим способом, например с помощью указателей или физической смежности. По
этой причине программы извлечения иногда предоставляют средства защиты такой ин-
формации с помощью полей последовательных номеров записей и замены указателей
значениями внешнего ключа.
Очистка данных
Лишь немногие источники данных обеспечивают удовлетворительный контроль ин-
формации. Вследствие этого, прежде чем данные будут введены в базу данных поддерж-
ки принятия решений, обычно требуется выполнить их очистку (как правило, это пакет-
ная операция). Обычно очистка предусматривает заполнение отсутствующих значений,
корректировку опечаток и других допущенных при вводе данных ошибок, определение
стандартных сокращений и форматов, замену синонимов стандартными идентификато-
рами и т.д. Данные, которые определяются как ошибочные и не могут быть исправлены,
отбрасываются.
Замечание. Полученная при выполнении очистки информация иногда используется
для выявления ошибок в источниках данных и последующего повышения качества со-
держащейся в них информации.
Преобразование и консолидация данных
После очистки данных полученная информация, скорее всего, еще не будет отвечать
требованиям системы поддержки принятия решений и, следовательно, будет нуждаться в
соответствующем преобразовании. Обычно данные подготавливаются в виде набора
файлов, по одному файлу для каждой таблицы, определенной в физической схеме. По-
этому процедура преобразования данных будет предусматривать построчное разбиение
или объединение исходных записей, как объяснялось в разделе 1.5 главы 1.
Замечание. Ошибки, которые не были исправлены во время очистки, иногда всплы-
вают в процессе преобразования данных. Как и при очистке, любая некорректная запись
в общем случае отбрасывается. Аналогичным образом информация об Ьшибках, полу-
ченная в ходе преобразования данных, может использоваться для повышения качества
источников данных.
Процедура преобразования приобретает особую важность, когда необходимо слить
данные, поступившие из нескольких разных источников. Этот процесс называется кон-
солидацией. В таком случае любая неявная связь между данными из отдельных источ-
ников должна быть преобразована в явную путем введения явных значений. Кроме того,
Глава 21. Поддержка принятия решений
827
если значения дат и времени связаны и имеют определенный деловой смысл, они долж-
ны быть проконтролированы и приведены в соответствие между отдельными источни-
ками. Этот процесс называется синхронизацией времени.
По соображениям производительности операции преобразования часто выполняются
параллельно. Они могут интенсивно использовать как систему ввода-вывода, так и цен-
тральный процессор.
Замечание. Синхронизация времени может оказаться довольно сложной задачей. Пред-
положим, например, что необходимо найти средний доход от заказчика на одного продавца
за квартал. Предположим также, что данные о доходах от заказчиков ведутся по финансо-
вым кварталам в базе данных бухгалтерии, а данные о продавцах, обслуживающих каждого
заказчика, ведутся по календарным кварталам в базе данных отдела сбыта. Очевидно, что
необходимо слить данные двух указанных баз. Консолидация данных о заказчиках не
сложна — она предусматривает простую проверку соответствия идентификаторов заказчи-
ков. Однако вопрос синхронизации времени значительно сложнее. Мы можем вычислить
доходы заказчика за финансовый квартал (из базы данных бухгалтерии), но мы не можем
сказать, какие продавцы обслуживали каждого из заказчиков в конкретное время, как не
можем определить доходы от заказчика за календарный квартал.
Загрузка данных
Разработчики СУБД придают большое значение эффективности операций загрузки
данных. В нашем случае “операцию загрузки данных” разобьем на следующие этапы: а)
пересылка преобразованных и консолидированных данных в базу данных поддержки при-
нятия решений; б) проверка согласованности данных (т.е. проверка их целостности); в) по-
строение всех необходимых индексов. Кратко прокомментируем каждый из этих этапов.
Пересылка данных. Современные СУБД обычно предоставляют утилиты парал-
лельной загрузки данных. Иногда, прежде чем будет выполнена настоящая загруз-
ка, данные преобразуются во внутренний физический формат, требуемый целевой
СУБД. (Альтернативный и более эффективный метод предусматривает загрузку в
рабочие таблицы, состав которых отражает структуру целевой схемы. На этих ра-
бочих таблицах может быть выполнена необходимая проверка целостности, а за-
тем для пересылки данных из рабочих таблиц в целевые таблицы может использо-
ваться операция INSERT, выполняемая на уровне множеств.
Проверка целостности. Большая часть процесса проверки целостности загружае-
мых данных может быть выполнена еще до реальной загрузки, без обращения к
данным, уже находящимся в базе. Однако некоторые ограничения все же не могут
быть проверены без обращения к существующей базе данных. Например, ограни-
чение, контролирующее уникальность значений, в общем случае должно прове-
ряться во время реальной загрузки (или, если загрузка выполняется в пакетном
режиме, после ее завершения).
Построение индексов. Наличие индексов может резко замедлить процесс загрузки
данных, поскольку большинство продуктов выполняет обновление индексов при
вставке в таблицу каждой строки. Поэтому иногда выгодно удалить индексы перед
загрузкой данных, а затем, после ее завершения, создать их заново. Однако такой
подход не будет целесообразным, если количество новых данных по отношению к
уже существующим данным мало; в этом случае затраты на создание индексов для
828
Часть V. Дополнительные аспекты
всей таблицы будут существенно больше затрат на обновление индексов. Кроме
того, создание индексов для большой таблицы может быть причиной неустрани-
мых ошибок выделения памяти, причем вероятность их возникновения увеличива-
ется по мере увеличения объема таблицы.
Замечание. Большинство СУБД поддерживает режим параллельного создания ин-
дексов, призванный ускорить процессы загрузки данных и построения индексов.
Обновление данных
В большинстве баз данных поддержки принятия решений (но не во всех) требуется
периодическое обновление данных для поддержания их актуальности. Обновление
обычно предусматривает частичную загрузку, хотя для некоторых систем поддержки
принятия решений требуется удаление всех данных и их полная перезагрузка. При об-
новлении возникают те же проблемы, что и при загрузке, и, кроме того, может потребо-
ваться, чтобы обновление выполнялось в то время, когда пользователи обращаются к ба-
зе данных. (См. раздел 9.5 главы 9, а также [9.2] и [9.6].)
Банки оперативных данных
Банки оперативных данных представляют собой “предметно-ориентированные, ин-
тегрированные, изменчивые, т.е. обновляемые, текущие, или почти текущие, коллекции
данных” [21.19]. Другими словами, банки оперативных данных — это специализирован-
ные базы данных. Термин предметно-ориентированные означает, что рассматриваемые
данные представляют некоторую конкретную предметную область, например заказчи-
ков, продукты и т.п. Банки оперативных данных могут использоваться для разных целей:
как область накопления для физической реорганизации извлеченных оперативных дан-
ных, для выдачи оперативных отчетов, а также для поддержки оперативных решений.
Кроме того, банки оперативных данных могут служить местом консолидации данных,
если оперативные данные поступают из нескольких источников. Поэтому они могут
быть предназначены для многих целей.
Замечание. Поскольку банки оперативных данных не накапливают исторические дан-
ные, обычно они не разрастаются до слишком больших объемов. С другой стороны, бан-
ки оперативных данных обычно достаточно часто или даже непрерывно обновляются
информацией из источников оперативных данных8. Проблемы синхронизации времени
(см. подраздел “Преобразование и консолидация данных”) в операционных хранилищах
данных могут успешно преодолеваться, если обновление выполняется достаточно часто.
21.5. Хранилища данных и магазины данных
Оперативные системы с базами.данных обычно характеризуются жесткими требова-
ниями к производительности, предсказуемым уровнем общей нагрузки, небольшими
единицами работы и высоким коэффициентом использования. Системы поддержки при-
нятия решений, напротив, обычно имеют различные требования к производительности,
непредсказуемый уровень нагрузки, большие единицы работы и характеризуются нере-
5 Иногда для этих целей используется асинхронная репликация из источников оперативных
данных непосредственно в банки оперативных данных. В этом случае состояние данных может
отличаться от текущего всего лишь на несколько минут
Глава 21. Поддержка принятия решений
829
гулярным использованием. Из-за этих различий могут возникнуть трудности в отноше-
нии совмещения функционирования оперативной системы обработки данных и системы
поддержки принятия решений внутри единой системы. Особенно это касается планиро-
вания объемов, управления ресурсами и настройки производительности системы. По-
этому системные администраторы обычно неохотно разрешают устанавливать приложе-
ния поддержки принятия решений на своих системах, особенно если имеют практиче-
ский опыт работы с двумя системами одновременно.
Замечание. Отметим в качестве небольшого отступления, что так было не всегда. Рань-
ше системы поддержки принятия решений реализовались на базе оперативных систем, но с
низким приоритетом или во время так называемых “пакетных окон”. При наличии доста-
точных вычислительных ресурсов этот подход имеет несколько преимуществ, и, пожалуй,
наиболее очевидным из них является то, что он позволяет избежать всевозможных затрат-
ных процедур копирования и переформатирования данных, а также дополнительных опе-
раций передачи информации, необходимых при работе с двумя отдельными системами. На
практике преимущества от совместного функционирования оперативных систем и систем
поддержки принятия решений находят все большее понимание. Однако подробное рас-
смотрение интеграции этих систем выходит за рамки данной главы.
Тем не менее, несмотря на сказанное в предыдущем абзаце, остается неоспоримым тот
факт, что, по крайней мере на время написания книги, данные систем поддержки принятия
решений обычно извлекаются из различных оперативных систем (часто в корне отличных
по своей организации) и помещаются в собственное хранилище, реализованное на отдель-
ной платформе. Такое отдельное хранилище данных называют хранилищем данных.
Хранилище данных
Подобно банкам оперативных данных (а также магазинам данных; см. следующий
подраздел), хранилище данных — это специальная база данных. Этот термин возник,
по-видимому, в конце 1980 года [21.13], [21.17], хотя соответствующая концепция поя-
вилась несколько позднее. В [21.18] хранилище данных определяется как “предметно-
ориентированное, интегрированное, постоянное, изменяемое во времени хранилище
данных для поддержки управленческих решений”. Здесь термин постоянное означает,
что, будучи введенными, данные впоследствии не изменяются, хотя и могут быть удале-
ны. Хранилища данных появились по двум причинам: во-первых, для систем поддержки
принятия решений необходимо было предоставить отдельный, чистый, согласованный
источник данных и, во-вторых, этой цели следовало достичь, не оказывая влияния на
функционирование оперативных систем.
Согласно определению ожидаемая рабочая нагрузка на хранилище данных— это
ожидаемая рабочая нагрузка в системе поддержки принятия решений. Поэтому можно
ожидать, что хранилище данных будет подвергаться частым обращениям с запросами, а
также периодической пакетной обработке для обновления данных. Кроме того, для хра-
нилищ данных характерен весьма большой объем занимаемой памяти — часто он пре-
вышает 500 Гбайт и может увеличиваться на 50% в год. Вследствие этого бывает трудно
добиться высокой производительности системы, хотя и нельзя сказать, что это невоз-
можно. Также могут возникнуть проблемы, связанные с расширяемостью базы данных.
Причины подобных затруднений обычно кроются в ошибках проектирования базы дан-
ных (обсуждавшихся в последнем подразделе раздела 21.3), неэффективном использова-
нии реляционных операций (что обсуждалось в разделе 21.2), наличии недостатков в
830
Часть V. Дополнительные аспекты
реализации реляционной модели в целевой СУБД, недостаточных возможностях расши-
рения, реализованных в самой целевой СУБД, наличии ошибок в архитектуре проекта,
ограничивающих объемы и препятствующих масштабированию платформы. Обсуждение
двух последних причин выходит за рамки книги, а две первые уже рассматривались в
этой главе. Единственная оставшаяся причина обсуждается в других частях этой книги.
Магазины данных
Хранилища данных в общем случае представляют собой единый источник информа-
ции для любой обработки, связанной с поддержкой принятия решений. Однако в начале
90-х годов, когда хранилища данных только приобретали популярность, было обнаруже-
но, что чаще всего пользователи составляли пространные отчеты и выполняли различ-
ные операции анализа данных на относительно небольшом подмножестве полного объе-
ма информации в хранилище данных. И действительно, пользователи повторяли те же
самые операции на том же самом подмножестве данных каждый раз после их обновле-
ния. Более того, некоторые из этих операций— например, предикативный анализ
(прогноз), имитация, моделирование “что если” на основе деловых данных — включали
создание новых схем и данных с последующим обновлением этих новых данных.
Неоднократное повторное выполнение таких операций на одном и том же подмножестве
информации полного хранилища данных, безусловно, не очень эффективно. Поэтому возник-
ла очевидная идея построения некоторого ограниченного “хранилища” специального назна-
чения, которое подходило бы для достижения рассматриваемых целей. Кроме того, в некото-
рых случаях можно извлекать и обрабатывать данные непосредственно из локальных источ-
ников, предоставляя более быстрый доступ к данным по сравнению с тем, который мог быть
предоставлен при синхронизации со всеми остальными данными, загруженными в полное
хранилище. Подобные соображения привели к появлению концепции магазинов данных.
На самом деле вокруг точного определения термина магазин данных еще ведутся
споры. Для наших целей магазин данных можно определить как “специализированное,
предметно-ориентированное, интегрированное, непостоянное, изменяемое во времени
хранилище данных для поддержки конкретного подмножества управленческих реше-
ний”. Как видим, ключевое отличие между магазинами данных и хранилищами данных
заключается в том, что магазины данных — специализированные и непостоянные. Под
характеристикой специализированные подразумевается, что они содержат данные для
поддержки лишь некоторой конкретной области делового анализа, а под характеристи-
кой непостоянные подразумевается, что пользователи могут обновлять данные и, воз-
можно, даже создавать в каких-то целях новые данные, например новые таблицы.
Существует три основных подхода к созданию магазинов данных.
Данные просто извлекаются из хранилища данных — по существу, следуя подхо-
ду “разделяй и властвуй” по отношению к процессу поддержки принятия решений
в целом. Это позволяет достичь более высокого уровня производительности и
масштабируемости. Обычно извлеченные данные загружаются в базу данных с
физической схемой, которая имеет близкое сходство с соответствующим подмно-
жеством хранилища данных. Часто такая схема может быть даже несколько упро-
щена благодаря узкой специализации магазинов данных.
Несмотря на то что хранилища данных подразумевают предоставление информа-
ции с “единой точки зрения”, независимо вполне могут создаваться еще и магази-
ны данных (т.е. поддерживаемые не посредством извлечения данных из хранили-
Глава 21. Поддержка принятия решений
831
ща данных). Такой подход может быть приемлемым, когда хранилище данных по
каким-то причинам недоступно, например по финансовым, оперативным или даже
политическим (или же хранилища данных может еще просто не существовать;
см. комментарии к следующему подходу).
В некоторых установках используется обратный подход: сначала создаются необ-
ходимые магазины данных, а полное хранилище данных впоследствии строится
как объединение информации из различных магазинов данных.
Для последних двух подходов обычно характерны проблемы, связанные с семантиче-
ским несоответствием. Независимые магазины данных особенно чувствительны к таким
проблемам, поскольку не существует очевидных способов проверить семантическое не-
соответствие, если базы данных спроектированы независимо. Консолидация магазинов
данных в одно хранилище данных в общем случае заканчивается неудачно, кроме тех си-
туаций, когда сначала создается единая логическая схема для хранилища данных, а уже
затем — схемы для отдельных магазинов данных, производные от схемы полного храни-
лища данных. (Безусловно, при необходимости схема для хранилища данных может по-
степенно расширяться — с целью включения данных о каждом новом магазине; конечно,
если она была должным образом спроектирована.)
Замечание по проектированию магазинов данных. При проектировании базы данных
поддержки принятия решений важно определиться с уровнем детализации базы данных.
Под термином уровень детализации здесь подразумевается самый низкий уровень обобще-
ния данных, предназначенных для хранения в базе данных. Для большинства приложений
поддержки принятия решений рано или поздно требуется доступ к детальным данным, так
что с уровнем детализации для хранилищ данных определиться несложно. Но для магази-
нов данных это сделать несколько труднее. Если уровень детализации занижен и данные
нижнего уровня используются не очень часто, то извлечение больших объемов детальных
данных из хранилища данных и их сохранение в магазине данных может оказаться весьма
неэффективным решением. С другой стороны, иногда трудно точно установить, какой
именно нижний уровень детализации реально необходим. В тех случаях, когда вместе с
обобщенными данными, сохраняемыми в магазинах данных, необходимы еще и детальные
данные, можно обращаться непосредственно в хранилище данных. В то же время полное
обобщение данных вообще невозможно, поскольку в результате применения множества
способов обобщения данных будут получены очень большие объемы итоговых данных.
Далее, в разделе 21.6 , мы обсудим этот вопрос подробнее.
И еще одно замечание. Поскольку пользователи магазинов данных часто применя-
ют определенные аналитические инструменты, в физическом проекте обычно указыва-
ется, по крайней мере частично, какие именно конкретные инструменты должны ис-
пользоваться (см. обсуждение двух видов аналитической обработки ROLAP и MOLAP
в разделе 21.6). Такое неудовлетворительное состояние дел может привести к созда-
нию “многомерных схем” (рассматриваются ниже), которые не отвечают правилам на-
дежного проектирования.
Многомерные схемы
Предположим, что необходимо накапливать исторические сведения о выполнении
производственных транзакций для последующего анализа. Как отмечалось в разде-
ле 21.1, ранние системы поддержки принятия решений сохранили бы эту историю в виде
обыкновенного файла, доступ к которому осуществлялся бы посредством последова-
832
Часть V. Дополнительные аспекты
тельного просмотра. Однако по мере роста объема данных для просмотра файла все бо-
лее выгодной (с различных точек зрения) становится поддержка прямого доступа к запи-
сям файла. Например, может быть желательно, чтобы существовала возможность поиска
всех производственных транзакций, включающих конкретный продукт, или всех произ-
водственных транзакций, относящихся к определенному заказчику.
Один из методов организации данных, обеспечивающий подобный тип доступа, на-
зывался “многокаталоговой” базой данных9. Такие базы данных могли бы содержать
большие основные файлы данных, включающие данные производственных транзак-
ций, вместе с тремя отдельными файлами “каталогов” для продуктов, периодов време-
ни и заказчиков. Рассматриваемые файлы каталогов схожи с индексами, в которых со-
держатся указатели на записи в файле данных, но элементы каталога могут размещать-
ся пользователем явно (“обслуживание каталога”) и каталоги могут содержать допол-
нительную информацию (например, адрес заказчика), которая затем может быть уда-
лена из файла данных. Следует отметить, что файлы каталогов обычно малы по срав-
нению с файлами данных.
При такой организации данных более эффективно используется память и затраты на
ввод-вывод гораздо меньше, чем при использовании первого проекта, предполагающего
наличие простых линейных файлов данных. Отметим, в частности, что информация о
продукте, периоде времени и заказчике в основном файле данных теперь сводится про-
сто к идентификаторам продукта, периода времени и заказчика.
Если этот подход имитировать в реляционной базе данных, то файл данных и файлы
каталогов станут таблицами (образами соответствующих файлов), указатели в каталогах
файлов станут первичными ключами в таблицах, которые служат образами файлов ката-
логов, а идентификаторы в файле данных станут внешними ключами в таблице, соответ-
ствующей этому файлу данных. Обычно эти первичные и внешние ключи полностью ин-
дексированы. При таком соответствии образ файла данных называют таблицей фактов,
а образы файлов каталогов — таблицами размерностей. Весь проект называют много-
мерным или имеющим схему типа “звезда” из-за его вида, если начертить соответст-
вующую диаграмму “сущность/связь” (таблица фактов будет окружена таблицами раз-
мерностей и связана с ними).
Замечание. Смысл термина “размерность” разъясняется в разделе 21.6.
В целях демонстрации предположим, что снова необходимо модифицировать базу
данных поставщиков и деталей, на этот раз так, чтобы показать каждую поставку за оп-
ределенное время, когда эта поставка осуществлялась. Присвоим поставке за определен-
ный период идентификатор #ТР и введем еще одну таблицу ТР, чтобы связать идентифи-
каторы с соответствующими периодами. Теперь исправленная таблица SP и новая табли-
ца периодов времени будут выглядеть так, как показано на рис. 21.310. В соответствии с
терминологией схем типа “звезда” таблица поставок SP представляет собой таблицу фак-
тов, а таблица периодов времени ТР — таблицу размерностей (также в эту схему входят
таблица поставщиков S и таблица деталей Р, как показано на рис. 21.4).
Замечание. Напомним, что общие вопросы обработки данных, представляющих пе-
риоды времени, будут подробно рассмотрены в главе 22.
9 Не имеет ничего общего с каталогами баз данных в современном смысле этого термина.
Ю В столбцах FROM и ТО таблицы ТР содержатся данные типа временной отметки. Для упро-
щения на рисунке показаны не реальные значения временных отметок, а символические обозначения.
Глава 21. Поддержка принятия решений
833
s# P# TP# QTY
si Pl TP3 300
SI Pl TP 5 100
SI P2 TP1 200
SI P3 TP2 400
SI P4 TP1 200
SI P5 TP5 100
SI P6 TP4 100
S2 Pl TP3 300
S2 P2 TP4 400
S3 P2 TP1 200
S3 P2 TP3 200
S4 P2 TP1 200
S4 P4 TP3 200
S4 P5 TP2 400
S4 P5 TP1 400
TP# FROM TO
ТР1 ta tb
ТР2 tc td
ТРЗ te tf
ТР4 tg th
ТР5 ti ti
Рис. 21.3. Пример таблицы фактов (SP) и таблицы размерностей (ТР)
Рис. 21.4. Схема типа “звезда” для базы данных поставщиков и
деталей (с периодами времени)
При обработке запросов в схеме типа “звезда” таблицы размерности обычно ис-
пользуются для поиска всех необходимых сочетаний внешних ключей, после чего най-
денные сочетания используются для доступа к таблице фактов. Предположим, что
доступ к таблице размерности и соответствующий доступ к таблице фактов связаны в
единый запрос. Тогда лучшим способом реализации такого запроса, как правило, яв-
ляется так называемое звездообразное соединение. Звездообразное соединение пред-
ставляет собой специальную стратегию реализации операции соединения, которая от-
личается от обычных стратегий тем, что соединение преднамеренно начинается с вы-
числения декартова произведения, а именно — декартова произведения таблиц раз-
мерностей. Как мы уже видели в главе 17, оптимизаторы запросов обычно пытаются
избежать вычисления декартова произведения [17.54], [17.55]. Однако в данном случае
формирование, в первую очередь, декартова произведения таблиц значительно мень-
шей размерности, а затем использование результата для просмотра таблицы фактов
очень больших размеров с помощью индексов почти всегда эффективнее любой дру-
гой стратегии. Поэтому для эффективной обработки запросов в схеме типа “звезда”
традиционные оптимизаторы нуждаются в переработке.
834
Часть V. Дополнительные аспекты
У читателя может возникнуть вопрос, в чем же отличие схемы типа “звезда” от
схемы, которую можно было считать настоящим реляционным проектом. Действи-
тельно, простая схема типа “звезда”, подобная рассмотренной выше, может показать-
ся очень похожей на настоящий реляционный проект (и даже идентичной ему). Одна-
ко, к сожалению, в общем случае при использовании схем типа “звезда” возникает це-
лый ряд проблем.
1. Прежде всего, эта схема— произвольная, поскольку она основывается на интуи-
ции, а не на принципах. Из-за недостатка строгости возникают сложности, когда
схему требуется надлежащим образом изменить, например, чтобы добавить в ба-
зу новые типы данных или изменить зависимости. На практике схемы типа
“звезда” часто конструируются посредством простого редактирования предыду-
щего проекта, а предыдущий проект, в свою очередь, конструировался методом
проб и ошибок.
2. Схемы типа “звезда” в действительности физические, а не логические, хотя о них и
говорят как о логических. Проблема заключается в том, что при данном подходе
отсутствует концепция логического проектирования, отдельного от физического.
3. Подход с использованием схем типа “звезда” не всегда позволяет получить в ре-
зультате правильный физический проект (т.е. проект, который сохраняет всю ин-
формацию корректного реляционного логического проекта). Этот недостаток ста-
новится все более очевидным по мере усложнения схемы.
4. Поскольку отсутствует строгий подход, проектировщики часто включают в одну
таблицу фактов несколько различных типов фактов. Вследствие этого строки и
столбцы таблицы фактов обычно не имеют единой интерпретации. Более того, оп-
ределенные столбцы часто применяются только к определенным типам фактов.
При этом подразумевается, что рассматриваемые столбцы должны разрешать
NULL-значения. По мере включения все большего количества типов фактов табли-
цу становится все сложнее обслуживать и понимать, а доступ становится все менее
эффективным. Например, допустим, нужно модифицировать таблицу поставок для
отслеживания закупок и поставок деталей. Тогда необходим некоторый столбец с
“флажками”, указывающими, какие строки относятся к закупкам, а какие к постав-
кам. В концептуально правильном проекте была бы создана отдельная таблица
фактов для каждого типа фактов.
5. Опять же, из-за отсутствия строгости таблицы размерностей Могут оказаться
неоднородными. Такая ошибка обычно возникает, когда таблица фактов ис-
пользуется для размещения данных из разных уровней обобщения. Например,
мы могли бы (ошибочно) добавить в таблицу поставок строки, содержащие
итоговые количества деталей, поставленных за каждый день, каждый месяц,
каждый квартал, каждый год и даже сводный текущий итог. Прежде всего, об-
ратите внимание, что такое изменение приводит к тому, что столбцы иденти-
фикатора периода (#ТР) и количества (QTY) в таблице SP будут иметь не едино-
образные значения. Предположим теперь, что столбцы FROM и ТО в таблице
размерности ТР заменены комбинациями столбцов YEAR, MONTH, DAY и т.д. Тогда
все эти столбцы YEAR, MONTH, DAY и др. должны будут допускать NULL-
значения. Кроме того, возможно, потребуется также столбец флажка, указы-
вающего тип соответствующего периода времени.
Глава 21. Поддержка принятия решений
835
6. Таблицы размерностей часто не полностью нормализованы11. Желание избежать
использования операций соединения часто приводит проектировщиков к решению
объединить разные данные в одной таблице, хотя лучше было бы сохранять их от-
дельно. В самом крайнем случае столбцы, к которым лишь иногда осуществляется
совместное обращение, также содержатся все вместе в одной и той же таблице раз-
мерностей. Должно быть ясно, что следование таким крайностям и отсутствие ре-
ляционной строгости почти наверняка приведут к неконтролируемой (а может
быть, даже к такой, которую невозможно контролировать) избыточности.
И наконец отметим, что одним из вариантов схемы типа “звезда” является схема ти-
па “снежинка”, которая предусматривает нормализацию таблицы размерности. Назва-
ние схемы также произошло от ее изображения в виде диаграммы “сущность/связь”. Из-
редка можно услышать термины схема типа “созвездие ” и схема типа “метель ” с оче-
видным (?) смыслом.
21.6. Оперативная аналитическая обработка
Термин оперативная аналитическая обработка (OLAP— online analytical
processing) впервые был упомянут в докладе для корпорации Arbor Software Corp, в 1993
году [21.10], хотя концепция, как и в случае с хранилищами данных, появилась значи-
тельно позже. Это понятие может быть определено как “интерактивный процесс созда-
ния, обслуживания и анализа данных и выдачи отчетов”. Кроме того, обычно добавляют,
что рассматриваемые данные должны восприниматься и обрабатываться так, как будто
они сохранены в “многомерном массиве”. Но, прежде чем приступить к обсуждению не-
посредственно многомерного представления, давайте рассмотрим соответствующие идеи
в терминах традиционных SQL-таблиц.
Первая особенность состоит в том, что при аналитической обработке непременно
требуется некоторое обобщение данных, обычно выполняемое сразу по многим различ-
ным критериям группирования. В сущности, одной из основных проблем аналитической
обработки является то, что количество всевозможных группирований очень скоро стано-
вится слишком большим. Тем не менее пользователям необходимо рассмотреть все или
почти все группирования. Конечно, сейчас реляционные языки поддерживают такие аг-
регации, но в результате выполнения каждого отдельного запроса на таком языке воз-
вращается только одна таблица, в которой все строки имеют один и тот же формат и од-
ну и ту же интерпретацию. Поэтому, чтобы получить п различных группирований, необ-
ходимо выполнить п отдельных запросов и создать в результате п отдельных таблиц. На-
пример, рассмотрим последовательность запросов, выполняемых в нашей базе данных
поставщиков и деталей.
1. Определить общее количество поставок.
2. Определить общее количество поставок по поставщикам.
3. Определить общее количество поставок по деталям. *
Приведем совет из книги по хранилищам данных: “[Откажитесь] от нормализации... Попытки
нормализовать любую из таблиц в многомерной базе данных исключительно ради сохранения дискового
пространства — напрасная трата времени.. Таблицы размерности не должны быть нормализованы...
Нормализованные таблицы размерности разрушают возможности просмотра" [21.21].
836
Часть V. Дополнительные аспекты
4. Определить общее количество поставок по поставщикам и деталям.
Замечание. “Общее” количество для данного поставщика и для данной детали —
это, конечно, просто фактическое количество для данного поставщика и данной де-
тали. Пример был бы более реалистичным, если бы использовалась база данных
поставщиков, деталей и проектов. Но, чтобы не усложнять его, мы все же остано-
вились на обычной базе поставщиков и деталей.
Предположим, что есть только две детали, с номерами ' Р1' и ' Р2', а таблица поста-
вок выглядит так.
S# P# QTY
S1 Р1 300
S1 Р2 200
S2 Р1 300
S2 Р2 400
S3 Р2 200
S4 Р2 200
Тогда формулировки на языке SQL12 для четырех указанных выше запросов и соот-
ветствующие результаты их выполнения будут следующими.
1. SELECT SUM(QTY) AS TOTQTY 2. SELECT S#
FROM SP SUM(QTY) AS TOTQTY
GROUP BY () ; FROM SP
GROUP BY (S#) ;
TOTQTY S# TOTQTY
1600 S1 500
S2 700
S3 200
S4 200
3. SELECT P# 4. SELECT S#, P#
SUM(QTY) AS TOTQTY SUM(QTY) AS TOTQTY
FROM SP FROM SP
GROUP BY (P#) ; GROUP BY (S#,P#) ;
P# TOTQTY
Pl 600
P2 1600
s# P# TOTQTY
SI Pl 300
SI P2 200
S2 Pl 300
S2 P2 400
S3 P2 200
S4 P2 200
I? Возможно, следовало сказать "формулировки на языке псевдоЛ^Ь ”, поскольку по стан-
дарту SQL/92 не допускается, чтобы операнды предложения GROUP BY были заключены в скобки
или чтобы предложение GROUP BY было вовсе без операндов (хотя отсутствие предложения
GROUP BY логически равносильно предложению GROUP BY без операндов).
Глава 21. Поддержка принятия решений
837
Недостатки этого подхода очевидны. Формулирование такого большого количества
простых, но отдельных запросов утомительно для пользователя. Выполнение же всех необ-
ходимых запросов (их запуск по одним и тем же датам снова и снова), вероятно, будет
слишком расточительным по времени. Поэтому стоит попытаться найти какой-то способ,
чтобы в одном запросе можно было получить несколько уровней обобщения и таким обра-
зом попытаться реализовать возможность вычисления всех этих обобщенных данных более
эффективно, т.е. за один проход. Именно этими соображениями руководствовались разра-
ботчики, создавая опции GROUPING SETS, ROLLUP и CUBE предложения GROUP BY.
Замечание. Эти опции уже поддерживаются в нескольких коммерческих продуктах.
Они также включены в новый стандарт SQL3 (см. приложение Б).
Опция GROUPING SETS позволяет пользователю точно указать, какое именно группи-
рование должно быть выполнено. Например, приведенный ниже SQL-оператор пред-
ставляет собой сочетание запросов 2 и 3.
SELECT S#, Р#, SUM(QTY) AS TOTQTY
FROM SP
GROUP BY GROUPING SETS ( (S#), (P#) ) ;
Здесь с помощью предложения GROUP BY фактически запрашивается выполнение двух
запросов, для одного из которых осуществляется группирование по атрибуту S#, а для
другого — по атрибуту Р#.
Замечание. Внутренние скобки в этом примере на самом деле не требуются, посколь-
ку каждое “группируемое множество” включает просто один столбец. Мы показали их
для наглядности.
Идея объединения нескольких отдельных запросов в один простой оператор указан-
ным способом сама по себе могла бы не вызывать возражений (хотя необходимо все же
сказать, что мы бы предпочли, чтобы этот очень общий вопрос был решен более общим,
семантическим и независимым способом). Однако, к сожалению, создатели языка SQL
пошли по пути объединения результатов этих логически отдельных запросов в одну ре-
зультирующую таблицу!13 В рассматриваемом примере таблица результатов могла бы
выглядеть так.
S# P# TOTQTY
S1 NULL 500
S2 NULL 700
S3 NULL 200
S4 NULL 200
NULL Pl 600
NULL P2 1000
Этот результат действительно можно считать таблицей (во всяком случае, SQL-
таблицей), но вряд ли каким-то отношением. Обратите внимание, что строки по постав-
щикам (они содержат NULL-значения в столбце Р#) и строки по деталям (они содержат
Эта отдельная таблица могла бы рассматриваться как “внешнее объединение ” (следует
отметить, крайне странная форма внешнего объединения!) результатов. Должно быть ясно
(см. главу 18), что даже в ее наименее странной форме операция “внешнего объединения” не яв-
ляется приемлемой реляционной операцией.
838
Часть V. Дополнительные аспекты
NULL-значения в столбце S#) имеют совершенно различные интерпретации. Значения
TOTQTY различаются в зависимости от того, относятся ли они к строкам по поставщикам
или к строкам по деталям. Так каким же может быть предикат для такого “отношения”?
Отметим, что NULL-значения в этом результате представляют еще и некоторый другой
вид “отсутствующей информации”. Они, определенно, не означают, что “значение неизвест-
но” или “значение не используется”, но что конкретно они означают, совершенно неясно.
Замечание. В языке SQL предоставляется возможность отличить эти новые NULL-
значения от других видов, но детали такой процедуры весьма утомительны. Пользователь вы-
нужден рассматривать выполнение операции с таблицей как последовательность операций,
обрабатывающих по одной строке. Здесь мы опускаем подробности, однако некоторое пред-
ставление можно получить, рассмотрев следующий пример (он показывает, что приведенный
выше пример с опцией GROUPING SETS на практике может выглядеть несколько иначе).
SELECT CASE GROUPING (S#) — см. приложение А по CASE
WHEN 1 THEN '?????'
ELSE S#
AS S#,
CASE GROUPING (P#) — см. приложение A no CASE
WHEN 1 THEN '!!!!!!'
ELSE P#
AS P#,
SUM(QTY) AS TOTQTY
FROM SP
GROUP BY GROUPING SETS ( (S#), (P#) ) ;
Возвратимся к предложению GROUP BY. Две другие опции предложения GROUP BY,
ROLLUP и CUBE, по сути являются сокращениями для определенных сочетаний в предло-
жении GROUPING SETS. Сначала рассмотрим опцию ROLLUP.
SELECT S#, Р#, SUM(QTY) AS TOTQTY
FROM SP
GROUP BY ROLLUP ( S#, P# ) ;
Предложение GROUP BY в данном случае будет равносильно следующему.
GROUP BY GROUPING SETS ( (S#,P#), (S#), () ) ;
Другими словами, этот запрос объединяет формулировки запросов 4, 2 и 1. Результат
его выполнения выглядит так.
S# Pit TOTQTY
S1 Pl 300
S1 Р2 200
S2 Pl 300
S2 Р2 400
S3 Р2 200
S4 Р2 200
S1 NULL 500
S2 NULL 700
S3 NULL 200
S4 NULL 200
NULL NULL 1600
Глава 21. Поддержка принятия решений
839
Термин ROLLUP (накопить) принят из-за того, что в данном примере количества
“накапливаются” для каждого поставщика (т.е. накапливаются “по размерности постав-
щика”; см. приведенный ниже подраздел “Многомерные базы данных”). В общем, пред-
ложение GROUP BY ROLLUP (А,В, ... Z), или, проще говоря, “накопить по размерности
А”, означает “сгруппировать по всем следующим сочетаниям”.
(А,В,
(А,В, ...)
(А,В)
(А)
Обратите внимание, что в общем случае выполняется много отдельных “накоплений по
размерности А” (это зависит от того, как перечислены в списке ROLLUP другие столбцы).
Также отметим, что предложения GROUP BY ROLLUP (А,В) и GROUP BY ROLLUP (В,А) име-
ют различные значения, т.е. предложение GROUP BY ROLLUP (А,В) не симметрично относи-
тельно А и В.
А теперь рассмотрим опцию CUBE. В качестве примера возьмем следующее.
SELECT S#, Р#, SUM(QTY) AS TOTQTY
FROM SP
GROUP BY CUBE ( S#, P# ) ;
Предложение GROUP BY здесь будет логически эквивалентно предложению, приведен-
ному ниже.
GROUP BY GROUPING SETS ( (S#,P#), (S#), (P#), () ) ;
Другими словами, этот запрос объединяет формулировки всех четырех запросов: 4, 3,
2 и 1. Результат его выполнения выглядит так.
S# P# TOTQTY
S1 Pl 300
S1 Р2 200
S2 Pl 300
S2 Р2 400
S3 Р2 200
S4 Р2 200
S1 NULL 500
S2 NULL 700
S3 NULL 200
S4 NULL 200
NUL Pl 600
NUL P2 1000
NULL NULL 1600
Бесполезный термин CUBE (куб) был принят из-за того, что в терминологии тех-
нологии OLAP, по крайней мере в многомерной, значения данных могут восприни-
маться как хранимые в ячейках многомерного массива или гиперкуба. В нашем слу-
840
Часть V. Дополнительные аспекты
чае значения данных — это количества; “куб” имеет лишь два измерения — измере-
ние поставщиков и измерение деталей (такой “куб” лучше бы назвать плоскостью!);
эти два измерения имеют неравные размеры (так что данный “куб” даже не является
квадратом; скорее, это прямоугольник). Но как бы то ни было, предложение GROUP
BY CUBE (А,В, ... Z) означает “сгруппировать по всем возможным подмножест-
вам множества {А, В, ..., Я}”.
Любое предложение GROUP BY может включать произвольные сочетания опций
GROUPING SETS, ROLLUP и CUBE.
Многокоординатные таблицы
Продукты OLAP часто отображают результаты запросов не в виде SQL-таблиц, а в
виде многокоординатных таблиц или перекрестных таблиц (cross tabulation, или со-
кращенно — crosstab). Вновь рассмотрим запрос 4. (“Определить общее количество по-
ставок по поставщикам и деталям”). Ниже представлены результаты его выполнения в
виде многокоординатной таблицы. Отметим, кстати, что количества детали с номером
'Р1' для поставщиков с номерами 'S3' и 'S4' показаны (корректно) как нуль. В языке
SQL, напротив, для этих количеств мы бы получили NULL-значения (см. главу 18). В
действительности таблица, которая выдается в языке SQL в ответ на запрос 4, не содер-
жит строк для ('S3', 'Р1') или ('S4', 'Р1'), поэтому создать из нее многокоординат-
ную таблицу — отнюдь непростая задача.
Р1 Р2
S1 300 200
S2 300 400
S3 0 200
S4 0 200
Эта многокоординатная таблица, безусловно, предоставляет более компактный и на-
глядный способ представления результата выполнения запроса 4. Кроме того, она не-
сколько похожа на реляционную таблицу. Обратите внимание, что количество столбцов
в этой “таблице” зависит отреачъных данных, а точнее, для каждого вида детали име-
ется один столбец, и поэтому структура многокоординатной таблицы и значение строк
зависят от реальных данных. Следовательно, многокоординатная таблица— это не от-
ношение, а отчет', точнее — отчет, который отформатирован, как простой массив.
(Отношения имеют предикат, который можно вывести из предикатов отношений, произ-
водными которых они являются. Однако “предикат” для многокоординатной таблицы
(если сделать допущение, что таковой существует) не может быть производным от пре-
дикатов соответствующих отношений, поскольку, как мы убедились, многокоординатная
таблица зависит от значений данных.)
О многокоординатных таблицах, подобных показанной выше, часто говорят, что они
имеют два измерения', в данном случае это поставщики и детали. Измерения обрабаты-
ваются, как будто это независимые переменные, а “ячейки” на пересечениях содержат
значения соответствующих зависимых переменных. Дальнейшие пояснения изложены в
подразделе “Многомерные базы данных”.
Ниже приведен другой пример многокоординатной таблицы, которая представляет
собой результат примера с опцией CUBE.
Глава 21. Поддержка принятия решений
841
Р1 Р2 Итого
S1 300 200 500
S2 300 400 700
S3 0 200 200
S4 0 200 200
Итого 600 1000 1600
В крайнем справа столбце содержатся итоги по строкам, т.е. итоги для указанных по-
ставщиков по всем деталям. В нижней строке содержатся итоги по столбцам, т.е. итоги
для указанных деталей по всем поставщикам. В крайней справа нижней ячейке содер-
жатся общий итог, который представляет итог по строке итогов по столбцам или итог по
столбцу итогов по строкам.
Многомерные базы данных
До сих пор предполагалось, что OLAP-данные хранятся в обычной базе данных, ис-
пользующей язык SQL (не считая того, что пару раз мы все же касались терминологии и
концепции “многомерных баз данных”). Фактически мы неявно описывали так называе-
мую систему ROLAP (“реляционную OLAP”). Однако многие считают, что использова-
ние системы MOLAP (“многомерной OLAP”) — более перспективный путь. В этом под-
разделе принципы построения систем MOLAP будут рассмотрены подробнее.
Система MOLAP подразумевает ведение многомерных баз данных, в которых дан-
ные концептуально хранятся в ячейках многомерного массива.
Замечание. Хотя и было сказано о “концептуальном” хранении, в действительности
физическая организация данных в MOLAP очень похожа на их логическую организацию.
Поддерживающая СУБД называется многомерной. В качестве простого примера
можно привести трехмерный массив, представляющий соответственно товары, заказчи-
ков и периоды времени. Значение каждой отдельной ячейки может представлять общий
объем указанного товара, проданного заказчику в указанный период времени. Как отме-
чалось выше, многокоординатные таблицы из предыдущего подраздела также могут счи-
таться такими массивами.
Если о совокупности данных имеется достаточно четкое представление, могут быть
установлены и все существующие между данными связи. Более того, “переменные” та-
кой совокупности (не в смысле обычных языков программирования), грубо говоря, мо-
гут быть разделены на зависимые и независимые. В предыдущем примере продукт, за-
казчик и период времени можно считать независимыми переменными, а количество —
единственной зависимой переменной. В общем случае независимые переменные — это
переменные, значения которых вместе определяют значения зависимых переменных
(точно так, как, если воспользоваться реляционной терминологией, потенциальный ключ
является множеством столбцов, значения которых определяют значения остальных
столбцов). Следовательно, независимые переменные составляют размерность массива, с
помощью которого организуются данные, а также образуют схему адресагр/и для данно-
го массива14. Значения зависимых переменных, которые представляют реальные данные,
сохраняются в ячейках массива.
Ячейки массива адресуются символически, а не числовыми индексами, которые обычно ас-
социируются с массивами.
842
Часть V. Дополнительные аспекты
Замечание. Различие между значениями независимых или “размерных” переменных и
значениями зависимых или “неразмерных” переменных иногда характеризуют как раз-
личие между размещением и содержанием.
К сожалению, предыдущая характеристика многомерных баз данных слишком упро-
щена, поскольку большинство совокупностей данных изначально понимаемы не в пол-
ной мере. По этой причине мы обычно стремимся, в первую очередь, проанализировать
данные, что позволяет лучше их понимать. Часто недостаточное понимание может быть
настолько серьезным, что заранее невозможно определить, какие переменные независи-
мые, а какие зависимые. Независимые переменные часто выбираются по текущему пред-
ставлению о них (т.е. по предположению), а результирующий массив затем тестируется
для проверки его соответствия требованиям заказчика (см. раздел 21.7). Подобный под-
ход приводит к тому, что выполняется множество итераций процесса проб и ошибок.
Поэтому система обычно допускает замену размерных и неразмерных переменных, и эту
операцию называют заменой ведущих элементов (pivoting). Другие поддерживаемые
операции включают транспозицию массива и размерное переупорядочение. Имеются
также возможности добавления размерностей.
Между прочим, из предыдущего описания должно быть ясно, что ячейки массива
часто будут пустыми, поэтому массивы обычно являются разреженными. Предполо-
жим, например, что товар р не продавался заказчику с в течение всего времени t. То-
гда ячейка (crprt) будет пустой (или в лучшем случае содержать значение нуль).
Многомерные СУБД поддерживают различные методы хранения разреженных масси-
вов в более эффективном сжатом представлении15. К этому следует добавить, что пус-
тые ячейки соответствуют “отсутствующей информации”, и, следовательно, системам
необходимо предоставлять некоторую вычислительную поддержку для пустых ячеек.
Такая поддержка действительно обычно имеется, и стиль ее, к сожалению, похож на
стиль, принятый в языке SQL. Обратите внимание на тот факт, что если данная ячейка
пуста, то информация или неизвестна, или не была введена, или непригодна, или уйму
других причин (см. главу 18).
Независимые переменные часто связаны в иерархии, определяющие пути, по кото-
рым зависимые данные могут объединяться. Например, существует временная иерархия,
связывающая секунды с минутами, минуты с часами, часы с днями, дни с неделями, не-
дели с месяцами, месяцы с годами. Или другой пример: возможна иерархия, связываю-
щая детали с комплектом деталей, комплект деталей с узлом, узел с панелью, панель с
изделием. Часто одни и те же данные могут быть объединены многими разными спосо-
бами, т.е. одна и та же независимая переменная может принадлежать многим различным
иерархиям. Система предоставляет операторы для “прохождения вверх” (drill up) и
“прохождения вниз” (drill down) по такой иерархии. Прохождение вверх означает пере-
ход от нижнего уровня объединения к верхнему, а прохождение вниз— в противопо-
ложном направлении. Для обработки иерархий имеются и другие операции, например
операция для переупорядочения уровней иерархии.
1$ Обратите внимание на отличие от реляционных систем. В настоящем реляционном ана-
логе этого примера в строке (C,p,t) не было бы пустой “ячейки”; просто строка (C,p,t) от-
сутствовала бы. Поэтому в реляционной модели нет необходимости в понятии “разреженных
массивов”, или скорее “разреженных таблиц”, а значит, не нужны и искусные методы сжатия
для представления таких таблиц.
Глава 21. Поддержка принятия решений
843
Замечание. Между операциями “пройти вверх” и “накопить” есть одно различие: опера-
ция “накопить” — операция создания необходимых группирований и объединений, а опе-
рация “пройти вверх” — операция доступа к таким объединениям. Примером операции
“пройти вниз” мог бы быть такой запрос: Дано итоговое количество поставок; получить
итоговые количества для каждого отдельного поставщика. Конечно, для ответа на такой
запрос должны быть доступны (или вычисляемы) данные более детальных уровней.
В продуктах многомерных баз данных также предоставляется ряд статистических и
других математических функций, которые помогают формулировать и проверять гипоте-
зы (т.е. предполагаемые связи). Также предоставляются инструменты визуализации и ге-
нерации отчетов, помогающие решать подобные задачи. Однако, к сожалению, для мно-
гомерных баз данных пока еще нет никакого стандартного языка запросов, хотя ведутся
исследования с целью разработки исчисления, на котором такой стандарт мог бы базиро-
ваться [21.27]. Но ничего подобного теории нормализации, которая могла бы служить
научной базой для проектирования многомерных баз данных, пока, к сожалению, нет.
Завершая этот раздел, отметим, что в некоторых продуктах сочетаются оба подхо-
да— ROLAP и MOLAP. Такую “гибридную систему OLAP” называют HOLAP. Ведется
много споров, чтобы установить, какой из этих трех подходов лучше, поэтому стоит и
нам попытаться сказать по данному вопросу пару слов. В общем случае системы MOLAP
обеспечивают более быстрые расчеты, но поддерживают меньшие объемы данных по
сравнению с системами ROLAP, т.е. становятся менее эффективными по мере возраста-
ния объемов данных. Системы ROLAP обеспечивают большие возможности масштаби-
руемости, параллельности и управления в сравнении с аналогичными возможностями
систем MOLAP.
21.7. Разработка данных
Разработку данных можно охарактеризовать как “исследовательский анализ дан-
ных”. Цель такой разработки — отыскать интересные взаимосвязи среди данных, кото-
рые впоследствии могут использоваться для выработки стратегии деловой активности
или для выявления необычного поведения, например внезапно возросшей активности
кредитной карточки, что может означать ее кражу. В инструментах разработки данных
используются статистические методы, применяемые для больших объемов данных, что и
позволяет найти интересующие пользователя закономерности.
Замечание. Слово большие здесь нужно выделить особо. Базы для разработки дан-
ных часто чрезвычайно большие, поэтому очень важно, чтобы применяемые алгоритмы
обеспечивали масштабируемость.
Рассмотрим не очень большую таблицу продаж SALES, показанную на рис. 21.5, в ко-
торой содержатся данные относительно определенных деловых сделок по продажам16.
На основе этих данных требуется выполнить анализ набора потребительских товаров,
Отметим, что ключ в этой таблице — {TX#, PRODUCT}, данные в таблице удовлетворяют
функциональным зависимостям TX#—>CUST# и TX#—>TIMESTAMP, а значит, она не приведена к
нормальной форме Бойса-Кодда (БКНФ): версия таблицы, в которой столбец PRODUCT содержал
бы значения-отношения (а столбец TX# был бы ключом), могла бы быть в БКНФ и лучше бы под-
ходила для выполнения данных исследований (хотя, возможно, меньше подходила бы для других
видов исследования).
844
Часть V. Дополнительные аспекты
где под набором потребительских товаров понимается набор продуктов, закупленных во
время одной сделки. Благодаря анализу можно определить, например, что потребитель,
который покупает обувь, вероятно, покупает и носки как часть одной и той же сделки.
Эта зависимость между обувью и носками— пример правила связи. Оно может быть
выражено приблизительно так.
FORALL tx ( Обувь е tx —> Носки е tx )
Здесь Обувь е tx — антецедент, или условие, правила, Носки е tx—результат, или
следствие, правила и tx изменяется по всем сделкам по продаже.
TX# CUST# TIMESTAMP PRODUCT
ТХ1 С1 dl Обувь
ТХ1 С1 dl Носки
ТХ1 С1 dl Галстуки
ТХ2 С2 d2 Обувь
ТХ2 С2 d2 Носки
ТХ2 С2 d2 Галстуки
ТХ2 С2 d2 Пояса
ТХ2 С2 d2 Сорочки
ТХЗ СЗ d2 Обувь
ТХЗ СЗ d2 Галстуки
ТХ4 С2 d2 Обувь
ТХ4 С2 d3 Носки
ТХ4 С2 d3 Пояса
Рис. 21.5. Таблица продаж SALES
Введем некоторые дополнительные термины. Множество всех сделок по продаже в
данном примере называют совокупностью. Любое данное правило связи имеет уровень
поддержки и уровень достоверности, или доверительный уровень. Поддержка — это
доля совокупности, в которой правило удовлетворяется. Достоверность — это отноше-
ние объема совокупности, в которой удовлетворяется правило, к объему совокупности, в
которой удовлетворяется условие. (Отметим, что условие и следствие необязательно
должны относиться к одному продукту; они могут относиться к любому количеству раз-
личных продуктов.) Рассмотрим, например, такое правило.
FORALL tx (Носки G tx —э Галстуки е tx)
Для нашего примера данных, представленного на рис. 21.5, совокупность составля-
ет 4 сделки, поддержка равна 50%, а достоверность — 66,67%.
Более общие правила связи могут быть исследованы на соответствующих агрегациях
данных. Например, после группирования по заказчикам можно проверить допустимость
такого правила, как “Если заказчик покупает обувь, то, вероятно, он также покупает нос-
ки, хотя необязательно во время той же сделки”.
Могут быть определены и другие виды правил. Например, правило зависимости
следствия может использоваться для определения покупаемых образцов в течение неко-
торого времени (“Если заказчик купил обувь сегодня, то он, вероятно, купит носки в те-
чение пяти дней”). Правило классификации может использоваться для принятия реше-
Глава 21. Поддержка принятия решений
845
ния по удовлетворению заявки на получение товара в кредит (“Если доход заказчика
превышает $75 000 в год, то, вероятно, риск неплатежа будет невелик”) и т.д. Подобно
правилам связей правила зависимости следствий и правила классификации также имеют
уровни поддержки и достоверности.
Разработка данных представляет собой огромную самостоятельную тему [21.1], по-
этому, очевидно, что рассмотреть ее детально в этой книге невозможно. Мы ограничим-
ся кратким описанием вероятного применения методов разработки данных к расширен-
ной версии базы данных поставщиков и деталей. Прежде всего при отсутствии других
источников данных мы можем использовать индукцию для классификации поставщиков
по их специализации, например по крепежным деталям и деталям двигателя, и предваре-
ние значений, чтобы прогнозировать, какими поставщиками и какие детали наиболее ве-
роятно будут поставляться. Затем мы можем использовать демографическую кластери-
зацию, т.е. разбивку на группы, чтобы связать расходы на поставки с географическим
расположением посредством закрепления поставщиков за регионами поставок. После
этого можно использовать исследование связей, чтобы определить те детали, которые
получены вместе, в одной поставке. С помощью последовательного исследования образ-
цов можно определить, что поставки крепежных деталей, в общем, следуют за поставка-
ми деталей двигателя, а путем исследования соответствующих временных циклов — что
имеются сезонные количественные изменения в поставках определенных деталей (одни
из таких изменений происходят осенью, а другие — весной).
21.8. Резюме
В этой главе было рассмотрено использование технологии баз данных для систем
поддержки принятия решений. Основная идея заключается в том, чтобы отобрать опе-
ративные данные и привести их к виду, в котором их можно было бы использовать для
оказания помощи управляющему персоналу в понимании особенностей функционирова-
ния предприятия и выборе направления его дальнейшего развития.
Сначала были определены понятия систем поддержки принятия решений, которые
устанавливаются отдельно от систем оперативных баз данных. Характерная черта баз
данных поддержки принятия решений заключается в том, что они предназначены пре-
имущественно лишь для чтения. Как правило, такие базы данных очень большие и
имеют много индексов. В них обычно присутствует контролируемая избыточность,
особенно в форме репликации и предварительного обобщения данных. Ключи обычно
содержат временной компонент, а запросы, как правило, очень сложные. Исходя из
этих соображений, при проектировании первостепенное внимание уделяется обеспече-
нию производительности систем. Соглашаясь с важностью этой задачи, мы все же счи-
таем, что способы ее достижения не должны вступать в противоречие с правильной
практикой проектирования. Проблема заключается в том, что в практике проектирования
систем поддержки принятия решений обычно недостаточно четко различаются вопросы
логического и физического проектирования.
Затем рассматривались вопросы подготовки оперативных данных к помещению в системы
поддержки принятия решений: задачи извлечения, очистки, преобразования и консолида-
ции, загрузки и обновления данных. Также упоминалась концепция банков оперативных
данных, которые, кроме всего прочего, могут использоваться и как области накопления в
процессе подготовки данных. Еще одно применение банков оперативных данных — предос-
тавление сервиса поддержки принятия решений на основе текущих данных.
846
Часть V. Дополнительные аспекты
Далее речь шла о хранилищах данных и магазинах данных (последние могут рас-
цениваться как специализированные хранилища данных). Была рассмотрена основная
идея построения схем типа “звезда”, в которых данные организованы, как большая ос-
новная таблица фактов и несколько значительно меньших таблиц размерности. В
простых случаях схемы типа “звезда” неотличимы от обычных классических нормализо-
ванных схем. Однако на практике они во многом отходят от принципов классического
проектирования по причинам, связанным с производительностью. Проблема, опять же,
состоит в том, что схемы типа “звезда” на самом деле в большей степени имеют физиче-
скую, а не логическую природу. Также мы коснулись стратегии реализации операции со-
единения, известной как звездообразное соединение, и разновидности схемы типа
“звезда”, которая называется схемой типа “снежинка”.
В этой главе также уделялось внимание оперативной аналитической обработке дан-
ных (OLAP). Обсуждались возможности языка SQL, которые предоставляются с помо-
щью опций GROUPING SETS, ROLLUP и CUBE предложения GROUP BY, а именно — возмож-
ности получения нескольких различных видов обобщения в одном SQL-запросе. Также
отмечалось, что язык SQL, к сожалению (на наш взгляд), объединяет эти различные
обобщения в одной “таблице”, содержащей множество NULL-значений. Также шла речь
о том, что на практике OLAP-системы могут предусматривать преобразование этих
“таблиц” в многокоординатные таблицы (обыкновенные массивы) для их отображе-
ния. Затем мы обратили ваше внимание на многомерные базы данных, в которых дан-
ные концептуально хранятся не в таблицах, а в многомерных массивах или гиперкубах.
Размерности такого массива составляют независимые переменные, а в ячейках содер-
жатся значения соответствующих зависимых переменных. Независимые переменные
обычно связываются в различные иерархии, которые определяют разумные способы
группирования и объединения данных.
И наконец была рассмотрена концепция разработки данных. Основная идея состоит
в том, что, поскольку данные часто недостаточно хорошо изучены, можно использовать
возможности компьютера, чтобы во всей совокупности данных обнаружить некоторые
характерные взаимосвязи. Здесь кратко рассматривались различные виды правил, а
именно — правила связи, классификации и зависимости следствия, и обсуждались
связанные с ними понятия уровней поддержки и достоверности.
Упражнения
21.1. Назовите некоторые из основных отличий между базами данных поддержки принятия
решений и оперативными базами данных. Почему системы поддержки принятия реше-
ний и оперативные приложения обычно используют различные хранилища данных?
21.2. Кратко опишите этапы подготовки оперативных данных для их помещения в сис-
тему поддержки принятия решений.
21.3. Назовите отличия между контролируемой и неконтролируемой избыточностью.
Приведите соответствующие примеры. Почему контролируемая избыточность
важна в системах поддержки принятия решений? Что случится, если избыточность
станет неконтролируемой?
21.4. Назовите отличия между хранилищами данных и магазинами данных.
21.5. Что вы понимаете под термином схема типа “звезда”?
Глава 21. Поддержка принятия решений
847
21.6. Схемы типа “звезда” обычно не полностью нормализованы. Что служит оправда-
нием такого положения дел? Объясните методологию проектирования таких схем.
21.7. Объясните различия между системами ROLAP и MOLAP.
21.8. Сколькими способами можно подытожить данные, если они характеризуются че-
тырьмя измерениями, каждое из которых принадлежит трехуровневой иерархии
обобщения (например, город, район, область)?
21.9. Используя базу данных поставщиков, деталей и проектов (см. упр. 4.1 в главе 4),
выразите на языке SQL следующие запросы.
а) Определить количество поставок и средний объем поставок для поставщиков,
деталей и проектов, рассматривая их попарно (например, для каждой пары Р#-
J# и каждой пары J#-S#).
б) Определить максимальный и минимальный объемы поставки для каждого про-
екта, каждого сочетания “проект — деталь” и в целом.
в) Определить общий объем поставок, суммируя “по всем измерениям поставщи-
ков” и по всем “измерениям деталей”. Предупреждение. Здесь имеется ловушка.
г) Определить средний объем поставок по поставщикам, деталям, сочетаниям
“поставщик — деталь” и в целом.
Для каждого случая покажите результат выполнения соответствующего SQL-
запроса, считая, что обработке подвергаются данные, представленные на рис. 4.5
(или какие-то ваши данные). Также представьте эти результаты в виде многокоор-
динатных таблиц.
21.10. В начале раздела 21.6 была показана приблизительная версия таблицы SP, в кото-
рой было 6 строк. Предположим, что эта таблица дополнительно включает сле-
дующую строку (подразумевается (возможно!), что поставщик с номером 'S5' су-
ществует, но в данное время деталей не поставляет).
| S5 | NULL | NULL |
Рассмотрите последствия этого включения для всех SQL-запросов, приведенных в
разделе 21.6.
21.11.Есть ли различие в значениях термина многомерный, когда он используется в фра-
зах “многомерная схема” и “многомерная база данных”? Объясните свой ответ.
21.12.Прокомментируйте проблему анализа набора потребительских товаров. Опишите в
общих чертах алгоритм для определения правил связи, уровни поддержки и досто-
верности которых больше указанных предельных величин.
Совет. Если некоторые сочетания продуктов “неинтересны”, поскольку они отно-
сятся к слишком мелким сделкам продажи, то же самое верно и для всех
супермножеств этого сочетания продуктов.
Список литературы
21.1. Adriaans Р., Zantinge D. Data Mining. — Reading, Mass.: Addison-Wesley, 1996.
Хотя эта книга и представлена как обзор, на самом деле в ней довольно подробно
(и хорошо) раскрывается данная тема.
848
Часть V. Дополнительные аспекты
21.2. Alter S. Decision Support Systems: Current Practice and Continuing Challenges.—
Reading, Mass.: Addison-Wesley, 1980.
21.3. Bennett J.L. (ed.) Bilding Decision Support Systems.— Reading, Mass.:
Addison-Wesley, 1981.
21.4. Berry M.J.A., Linoff G. Data Mining Techniques for Marketing, QTY, and Customer
Support. —New York, N.Y.: McGraw-Hill, 1997.
Хорошее объяснение методов разработки данных и их значения для некоторых ас-
пектов бизнеса.
21.5. Boulden J.B. Computer-Assisted Planning Systems. — New York, N.Y.: McGraw-Hill, 1975.
Это ранняя работа, затрагивающая многие вопросы, которые позже будут объеди-
нены под общим названием “поддержка принятия решений”. Как отмечается в за-
головке, основное внимание здесь уделено управлению планированием в классиче-
ском смысле.
21.6. Bonczek R.H., Holsapple C.W., Whinston A. Fondations of Decision Support
Systems. — Orlando, Fla.: Academic Press, 1981.
Одна из первых публикаций в защиту строго методического подхода в системах под-
держки принятия решений. Особое внимание уделено роли моделирования (в общем
смысле эмпирического и математического моделирования) и науки управления.
21.7. Bontempo C.J., Saracco С.М. Database Management: Principles and’Products. — Upper
Saddle River, N.J.: Prentice-Hall, 1996.
21.8. Cabena P., Hadjinian P., Stadler R., Verhees J., Zanasi A. Discovering Data Mining:
From Concept to Implementation. — Upper Saddle River, N.J.: Prentice-Hall, 1998.
21.9. Chang C.L. DEDUCE — A Deductive Query Language for Relational Data Bases, — in
Chen C.H. (ed.) Pattern Recognition and Artifical Intelligence. — New York, N.Y.:
Academic Press, 1976.
21.10. Codd E.F., Codd S.B., Salley C.T. Providing OLAP (Online Analytical Processing) to
User-Analysts: An IT Mandate, — available from Arbor Software Corp. — 1993.
Как указывалось в настоящей главе, благодаря этой статье появился термин “OLAP”,
хотя и не само понятие. Интересно отметить, что в начале статьи категорически ут-
верждается, что “Потребности, которые существуют, пока еще НЕ нуждаются в дру-
гой технологии баз данных; скорее, они нуждаются в надежных... инструментах ана-
лиза”. Далее следуют описание и доводы в пользу новой технологии баз данных (!)
— с новым концептуальным представлением данных, новыми операторами (как для
обновления, так и для выборки), многопользовательской поддержкой (включая воз-
можности безопасности и параллельного доступа), новыми структурами памяти и но-
выми возможностями оптимизации. Словом, новая модель данных и новая СУБД.
21.11. Date C.J. We Don’t Need Composite Columns, — in Date C.J., Darwen H., McGoveran
D. Relational Database Writings 1994-1997. — Reading, Mass.: Addison-Wesley, 1998.
В названии этой статьи упоминается то, что в прошлом предпринимались (ошибочные)
попытки ввести поддержку составных столбцов, не основываясь на поддержке типов,
которые определяются пользователем. Если соответствующая поддержка пользова-
тельских типов предоставлена, то вопрос о составных столбцах отпадает.
21.12. Delvin В. Data Warehouse from Architecture to Implementation. — Reading, Mass.:
Addison-Wesley, 1997.
Глава 21. Поддержка принятия решений
849
21.13. Delvin B.A., Murphy P.T. An Architecture for a Business and Information System //
IBM Sys. — 1988. — J 27, № 1.
Первая опубликованная статья, в которой определен и использован термин
“хранилище информации”.
21.14. Edelstein Н. Data Mining: Products and Markets. — Potomac, Md.: Two Crows Corp, 1997.
21.15. Gerrity T.P., Jr. The Design of Man-Machine Decision Systems: An Application to
Portfolio Management // Sloan Management Review. — 1971. — 12, № 2.
Одна из наиболее ранних статей по системам поддержки принятия решений. В ней
описывается система поддержки управления инвестированием в администрирова-
нии фондового портфеля.
21.16. Gray J., Bosworth A., Layman A., Pirahesh Н. Data Cube: A Relational Aggregation
Operator Generalizing Group-By, Cross-Tab, and Sub-Totals // Proc. 12th IEEE Int.
Conf, on Data Engineering. — New Orleans, La., 1996.
В статье впервые предлагается добавить в предложение языка SQL GROUP BY такие
опции, как CUBE.
21.17. Inmon W.H. Data Architecture: The Information Paradigm.— Wellesley, Mass.: QED
Information Sciences, 1988.
В работе обсуждается происхождение понятия “хранилище данных” и описывает-
ся, как хранилище данных могло бы выглядеть на практике. Термин “хранилище
данных” впервые появился в этой книге.
21.18. Inmon W.H. Building The Data Warehouse. —New York, N.Y.: Wiley, 1992.
Первая книга, посвященная хранилищам данных. В ней определяется этот термин
и обсуждаются ключевые проблемы, которые возникают при разработке хранилищ
данных. В книге, в первую очередь, обосновывается концепция хранилищ данных,
а также рассматриваются вопросы операционного и физического проектирования.
21.19. Inmon W.H., Hackathorn R.D. Using the Data Warehouse. — New York, N.Y.: Wiley, 1994.
Хранилища данных обсуждаются с точки зрения пользователей и администрато-
ров. Как и другие книги по этой теме, она концентрируется на физических вопро-
сах. Понятие хранилищ операционных данных обсуждается не так подробно.
21.20. Keen P.G.W., Morton M.S.S. Decision Support Systems: An Organizational
Perspective. — Reading, Mass.: Addison-Wesley, 1978.
Это классическое изложение — одно из самых ранних, если не самое раннее, кото-
рое явно посвящено поддержке принятия решений. Публикация ориентирована на
анализ поведения и охватывает вопросы анализа, проектирования, реализации,
оценивания и разработки систем поддержки принятия решений.
21.21. Kimball R. The Data Warehouse Toolkit. —New York, N.Y.: John Wiley & Sons, 1996.
Эта книга — руководство к действию. Как и гласит подзаголовок “Практические
методы построения многомерных хранилищ данных”, в ней основное внимание
уделяется практическим, а не теоретическим вопросам. По умолчанию предполага-
ется, что не существует значительных различий между логическим и физическим
уровнями систем. Это предположение, конечно, полностью распространяется и на
современные продукты. Однако, по нашему мнению, было бы лучше попытаться
исправить положение дел, чем фактически просто его констатировать.
850
Часть V. Дополнительные аспекты
21.22. Little J.D.C Models and Managers: The Concept of a Decision Calculus // Management
Science. — 1970. — 16, № 8.
В статье представлена система (Brandaid), спроектированная для поддержки приня-
тия решений по продуктам, их сбыту, ценообразованию и рекламе. Автор определяет
четыре критерия проектирования моделей по поддержке управленческих решений:
устойчивость, удобство в управлении, простота и полнота необходимых деталей.
21.23. Morton M.S.S. Management Decision Systems: Computer-Based Support for Decision
Making. — Harvard University, Division of Research, Graduate School of Business
Administration. — 1971.
Это классическая статья, в которой было введено понятие систем поддержки
управленческих решений и поддержка принятия решений была явно отнесена к
компьютерным системам. Конкретная “система управленческих решений” была
построена для координации производственного планирования оборудования для
прачечных. Затем она была подвергнута научной проверке с коммерческими и
производственными менеджерами в качестве пользователей.
21.24. Parsaye К., Chignell М. Intelligent Database Tools and Applications.— New York,
N.Y.: Wiley, 1993.
Это первая книга, которая посвящена принципам и методам разработки данных,
хотя сами авторы обращаются к этой теме, как к “интеллектуальным базам дан-
ных”.
21.25. Pirotte A., Wodon Р. A Comprehensive Formal Query Language for a Relational Data
Base // R.A.I.R.O. Informatique/Computer Science. — 1977. — 11, № 2.
21.26. Sprague R.H., Carlson E.D. Building Effective Decision Support Systems. — Englewood
Cliffs, N.J.: Prentice-Hall, 1982.
Также классическая книга.
21.27. Thomsen E. OLAP Solutions: Building Multi-Dimensional Information Systems.—New
York, N.Y.: Wiley, 1997.
Одна из первых книг по оперативной аналитической обработке данных, и, возмож-
но, наиболее исчерпывающая. В ней обращается внимание на непонимание кон-
цепций и методов анализа, использующих многомерные системы. Предпринимает-
ся серьезная попытка ввести некоторую методическую упорядоченность в эту за-
путанную тему.
21.28. Uthurusamy R. From Data Mining to Knowledge Discovery: Current Challenges and
Future Directions, — in Fayyad U.M., Piatetsky-Shapiro G., Smyth P., Uthurusamy R.
(eds.) Advances in Knowledge Discovery and Data Mining. — Cambridge, Mass.: AAAI
Press/MIT Press, 1996.
Ответы к некоторым упражнениям
21.8. Существует восемь (23) возможных группировок для каждой иерархии, поэтому
общее количество возможностей составляет 84 = 4 0 96. В качестве дополнительно-
го упражнения можно рассмотреть, каким должен быть SQL-запрос, чтобы полу-
чить все эти итоговые значения.
21.9. Что касается SQL-запросов, то здесь мы приведем лишь предложения GROUP BY.
Глава 21. Поддержка принятия решений
851
a) GROUP BY GROUPING SETS ( (S#,P#), (P#,J#),(J#,S#) )
6) GROUP BY GROUPING SETS ( J#, (J#,P#), () )
в) Ловушка заключается в том, что запрос двусмысленный: фраза “суммируя по всем
измерениям поставщиков”, например, имеет много возможных значений. Однако
одна из вероятных интерпретаций этого запроса может быть выражена так.
GROUP BY ROLLUP (S#), ROLLUP(P#)
r) GROUP BY CUBE ( S#, P# )
Мы опускаем результирующие SQL-таблицы. Что касается многокоординатных
таблиц, то понятно, что они не очень хорошо подходят для отображения результата,
который имеет больше двух измерений (и чем больше имеется измерений, тем
труднее их получить). Например, многокоординатная таблица, соответствующая
предложению GROUP BY S#,P#, J# , может выглядеть так (часть таблицы).
Р1 Р2
Jl J2 J3 Jl J2 J3
S1 200 0 0 0 0 0
S2 0 0 0 0 0 0
S3 0 0 0 0 0 0 ...
S4 0 0 0 0 0 0
S5 0 200 0 0 0 0 ...
Короче говоря, заголовки — неуклюжи, а массивы — разрежены.
852
Часть V. Дополнительные аспекты
Глава 22
Хронологические
базы данных
22Л. Введение
Замечание. Автор оригинального текста этой главы — Хью Дарвен (Hugh Darwen).
Хронологическая база данных — это, говоря упрощенно, база данных, содержащая
исторические накопленные данные вместо (или кроме) текущих данных. Такие базы
данных начали активно исследоваться с середины 70-х годов. В некоторых из исследова-
ний была принята крайняя точка зрения, согласно которой информация в подобные базы
данных только вносится и никогда не удаляется и не обновляется (см. обсуждение храни-
лищ данных в предыдущей главе), поэтому база данных содержит только исторические
данные. Другая крайность— базы данных типа моментальный снимок1, которые со-
держат только текущие данные, удаляемые или обновляемые, когда содержание этих
данных уже не соответствует действительности. Иными словами, база данных типа мо-
ментального снимка— это просто база данных в обычном понимании, а вовсе не хроно-
логическая база данных.
В качестве примера еще раз рассмотрим базу данных поставщиков и деталей, пред-
ставленную на рис. 3.8. Безусловно, эта база данных имеет тип моментального снимка.
Например, в ней содержатся сведения о текущем статусе поставщика с номером ' S1',
который в данный момент равен 20. Однако в хронологической версии этой базы данных
был бы отражен не только текущий статус поставщика с номером 'S1', равный 20, но
также было бы указано, что его статус равен 20 с 1 июля, а, скажем, с 5 апреля по
30 июня его статус был равен 15, и т.д.
В базе данных типа моментального снимка временем выполнения этого снимка
обычно считается “данный момент времени”, т.е. время, в которое база данных фак-
тически рассматривается. Даже если время выполнения моментального снимка на
самом деле отличается от “данного момента времени”, это не имеет особого значе-
ния для сопровождения и использования данных, которые помещены в моменталь-
ный снимок. Однако, как мы вскоре убедимся, в хронологических базах данных со-
провождение и использование данных во многом отличается от обычных баз дан-
ных, чему и посвящена эта глава.
Отличительной чертой хронологических баз данных является, конечно, присутствие
данных о времени. Поэтому при исследовании особенностей хронологических баз дан-
ных значительное место занимает изучение свойств самого времени. Ниже представлены
некоторые из исследовавшихся вопросов.
1 Не имеют ничего общего с моментальными снимками, описанными в главе 9.
Глава 22. Хронологические базы данных
853
Философский вопрос. Имеет ли время начало и/или конец?
Научный вопрос. Время непрерывно или представляет собой дискретные кванты?
Психологический вопрос. Как лучше всего определить такое важное понятие, как
данный момент времени, которое часто называют моментом пересылки!
Хотя эти вопросы, возможно, и интересны сами по себе, они не являются вопро-
сами исключительно теории баз данных, поэтому в данной главе мы не будем в них
углубляться. Вместо этого там, где это необходимо, мы просто будем делать неко-
торые (надеюсь, достаточно разумные) предположения, что позволит уделить боль-
ше внимания аспектам, которые непосредственно относятся к общей задаче, постав-
ленной при написании книги. Однако необходимо отметить, что некоторые из ис-
следований свойств времени привели к интересным обобщениям, которые неопро-
вержимо доказывают, что идеи, разработанные для поддержки хронологических
данных, могли бы иметь применение и в других областях. (Несмотря на последнее
высказывание мы будем следовать обычной практике использования понятий
“хронологические ключи”, “хронологические операторы”, “хронологические отно-
шения” и т.д., хотя часто они применимы не только к хронологическим базам дан-
ных как таковым.)
Предупреждение автора! Учитывая сказанное выше, мы сосредоточим внимание
лишь на самых интересных и важных идеях, полученных в результате проведенных
исследований. Иными словами, в настоящей главе предпринята попытка извлечь и
рассмотреть “лучшие стороны” исследований, хотя это и будет отклонением от при-
нятого в литературе перечня рассматриваемых вопросов и других условностей. Пре-
дупредим, что лишь некоторые из рассматриваемых здесь технологий можно встре-
тить в какой-либо коммерческой СУБД. На наш взгляд, причины такого состояния
дел следующие.
Дисковая память лишь совсем недавно стала настолько дешевой, что храни-
лища исторических данных большого объема стали практически реализуемы-
ми. Однако, как указывалось в главе 21, “хранилища данных” сейчас стано-
вятся обыденной реальностью. Поэтому пользователи будут все чаще сталки-
ваться с проблемами, связанными с хронологическими базами данных, и нуж-
даться в их решении.
Хотя большинство, если не все, из описанных здесь возможностей реализованы в
виде прототипов, их внедрение в существующие продукты — особенно в SQL-
продукты (поскольку язык SQL все больше отклоняется от реляционной модели
вместо того, чтобы ей следовать) — может стать пугающей перспективой. Поми-
мо этого, большинство разработчиков сейчас заняты попытками реализовать под-
держку объектно-реляционных баз данных (глава 25).
Мнение сообщества исследователей относительно того, какой именно подход
является лучшим для решения данной проблемы, по-прежнему в определен-
ной мере разделено, и такое отсутствие единства также оказывает влияние на
разработчиков. Одни исследователи отдают предпочтение весьма специализи-
рованному подходу (предусматривающему определенное отклонение от реля-
ционных принципов), приспособленному конкретно для хронологических баз
данных, но в этом случае остаются нерешенными иные проблемы (см.,
например, [22.4]). Другие же отдают предпочтение более общим операторам,
854
Часть V. Дополнительные аспекты
которые при необходимости могли бы служить основой для реализации спе-
циализированного подхода, не отступая при этом от основных реляционных
принципов (см., например, [22.3]). Излишне говорить, что мы поддерживаем
именно последний подход.
Структура этой главы будет рассмотрена в следующем разделе.
22.2. Хронологические данные
Если обычные данные являются закодированным представлением фактов, то хроно-
логические данные являются закодированным представлением фактов с отметкой точно-
го времени, или временной отметкой (timestamp). В хронологических базах данных в
соответствии с крайней интерпретацией этого термина все данные являются хронологи-
ческими, а значит, каждый записанный факт сопровождается временной отметкой. Та-
ким образом, хронологическое отношение — это такое отношение, в котором содержит-
ся по крайней мере одна временная отметка, т.е. заголовок включает хотя бы один атри-
бут некоторого типа, представляющего собой временную отметку. Отсюда следует, что
хронологическая переменная-отношение является такой переменной-отношением, заго-
ловок которой представлен хронологическим отношением. В свою очередь, реляционная
хронологическая база данных — это база данных, в которой все переменные-отношения
являются хронологическими.
Замечание. Мы здесь умышленно не уточняем, как могут выглядеть данные
“некоторого типа, представляющего собой временную отметку”. Этот вопрос будет рас-
смотрен в разделах 22.3-22.5.
Итак, выше было дано достаточно точное определение понятия “хронологическая ба-
за данных” (в ее чересчур строгом понимании). Однако такое понятие здесь использо-
ваться не будет, поскольку от него мало проку! Оно отвергается потому, что даже если
бы все исходные переменные-отношения в базе данных были хронологическими, то мно-
гие производные отношения (например, результаты выполнения запроса) все же не явля-
лись бы хронологическими. Например, ответ на запрос “Найти фамилии всех служащих,
которые были приняты на работу в течение некоторого периода времени” вполне может
быть получен из некоторой хронологической базы данных, однако сам ответ не будет
представлять собой хронологическое отношение. Это была бы действительно странная
СУБД, и уж точно не реляционная, если бы она позволяла получать результаты, которые
не смогла бы сохранить в собственной базе данных.
Поэтому в настоящей главе будем считать, что хронологические базы данных — это
такие базы данных, которые могут включать хронологические данные, но содержание
которых не ограничивается лишь хронологическими данными. В настоящей главе под-
робно обсуждаются именно такие базы данных.
Далее в этом и следующем разделах содержится вступительный материал для по-
следующих разделов. В частности, в разделе 22.3 показано, почему хронологиче-
ские данные, как оказывается, требуют специальной трактовки.
В разделах 22.4 и 22.5 вводится понятие интервалы (промежутки времени) как
удобный способ добавления к данным временнь/х отметок. Затем в разделах 22.6 и
22.7 обсуждается несколько скалярных и обобщающих операторов, предназначен-
ных для обработки интервалов.
Глава 22. Хронологические базы данных
855
В разделе 22.8 вводятся некоторые новые важные реляционные операторы для об-
работки хронологических отношений.
В разделе 22.9 рассматриваются вопросы, касающиеся ограничений целостности
для хронологических данных, а в разделе 22.10 — специальные проблемы обнов-
ления таких данных.
Наконец, в разделе 22.11 предлагаются некоторые важные (и, возможно, непри-
вычные) идеи проектирования баз данных и в разделе 22.12 представлено резюме.
Замечание. Важно понимать, что, кроме одного исключения (генератора интерваль-
ного типа, представленного в разделе 22.5), все новые операторы и другие конструкции,
обсуждаемые в этой главе, в действительности являются лишь сокращениями. Другими
словами, они могут быть выражены (хотя иногда и очень громоздко) с помощью тех
функциональных возможностей, которые уже имеются в полном реляционном языке, та-
ком как Tutorial D. Это утверждение будет подкрепляться по мере необходимости при-
мерами (хотя и не во всех случаях).
Некоторые основные концепции и вопросы
Рассмотрим, как в обычном языке выражаются так называемые “высказывания с вре-
менной отметкой”. Приведем три примера.
1. С поставщиком с номером ' S1' был заключен договор (т.е. подписан контракт) от
1 июля 1999 года.
2. Договор с поставщиком с номером ' S1' действителен с 1 июля 1999 года.
3. Договор о поставках с поставщиком с номером 'S1' имеет силу на период с
1 июля 1999 года и по настоящий день.
Каждое из этих высказываний представляет собой возможную интерпретацию корте-
жа с двумя атрибутами: номером поставщика со значением 'S1' и временной отметкой
'1 июля 1999 года'. Причем каждое из этих высказываний может соответствовать кор-
тежу, который содержится в базе данных типа моментального снимка, представляющей
текущее состояние некоторого предприятия. Выделенные слова от, с и на период харак-
теризуют эти различные интерпретации.
Замечание. Везде в этой главе слова “с” и “на период” будут использоваться исклю-
чительно в смысле “с тех пор” и “в течение всего времени” (рассматриваемого периода)
соответственно, если противное не будет указано явно.
Хотя здесь приведены три возможные интерпретации, можно возразить, что во
всех этих высказываниях в действительности говорится об одном и том же, но с
использованием различных выражений. На самом деле высказывания 2 и 3 счита-
ются равносильными, а высказывания 1 и 2 (или 1 и 3) — нет. Покажем, что это
действительно так.
В высказывании 1, безусловно, утверждается, что с поставщиком с номером 'S1'
договор о поставках не был заключен до определенной даты (30 июня 1999 года),
которая непосредственно предшествует указанной дате подписания контракта. В
высказывании 2 этот факт не утверждается и из него никак не следует.
856
Часть V. Дополнительные аспекты
Предположим, что сегодня (“текущий день”) 25 сентября 2000 года. Тогда в вы-
сказывании 2, безусловно, утверждается, что заключенный с поставщиком с номе-
ром ' S1' договор был действителен каждый день, начиная с 1 июля 1999 года и по
25 сентября 2000 года включительно. Однако в высказывании 1 этот факт не ут-
верждается и не подразумевается.
Таким образом, высказывания 1 и 2 не равносильны и не следуют одно из другого.
Кортежи в базах данных типа моментального снимка часто включают элементы со
значением “указанная дата”. В этом случае в качестве подразумеваемой интерпретации
чаще всего понимаются высказывания, подобные высказыванию 2 (или 3). В рассмот-
ренном выше примере высказывание 1 в той форме, в которой оно представлено, являет-
ся не совсем точной интерпретацией заданного кортежа. Точнее, его следовало бы сфор-
мулировать так: “Договор с поставщиком с номером ' S1' был заключен не раннее
1 июля 1999 года”. Более того, если эта версия высказывания 1 действительно соответст-
вует тому, что подразумевается под данным гипотетическим кортежем с двумя атрибу-
тами, то высказывание 2 в его приведенной форме также представляет собой не совсем
точную интерпретацию. Корректнее было бы сформулировать его так: “Договор с по-
ставщиком с номером ' S1' не был заключен до 30 июня 1999 года, но 1 июля 1999 года
он действительно был заключен”.
Обратите внимание, что высказывание 1 отражает момент, в который имело место
определенное событие, в то время как высказывания 2 и 3 отражают интервал времени,
на период которого сохраняется определенное состояние. Здесь умышленно был вы-
бран пример, в котором об определенном состоянии можно судить исходя из информа-
ции, касающейся определенного события. Поскольку договор с поставщиком с номером
'S1' был заключен не раньше 1 июля 1999 года, договорные отношения с этим постав-
щиком существуют начиная с этой даты и по настоящее время. В классической техноло-
гии баз данных вполне удовлетворительно обрабатываются экземпляры времени (время,
когда произошло событие), однако совсем плохо обрабатываются интервалы времени,
т.е. периоды времени, в течение которого сохраняется определенное состояние (это бу-
дет показано в разделе 22.3).
Обратите также внимание, что хотя высказывания 2 и 3 логически равносильны, их
формы заметно отличаются. Точнее, форма высказывания 2 не может использоваться
для хранения исторических сведений, в то время как форма высказывания 3 это позволя-
ет, если только заменить в нем фразу “по настоящий день” какой-либо явной датой, на-
пример 25 сентября 2000 года. (Конечно, тогда высказывание будет соответствовать кор-
тежу с тремя атрибутами, а не с двумя.) Таким образом, можно сделать вывод, что поня-
тие “на период” является очень важным для ведения исторических записей, по крайней
мере для данных о состояниях, если не для данных о состоянии2.
Терминология. Время, когда произошло определенное событие, или интервал време-
ни, когда сохраняется определенное состояние, иногда называют допустимым временем.
Точнее говоря, допустимое время высказывания р— это множество моментов времени,
2 Здесь не лишне было бы заметить, что несмотря на повторяющееся использование таких
терминов, как "исторические записи’’, в хронологических базах данных могут также содер-
жаться данные, относящиеся к будущему времени. Например, может возникнуть необходи-
мость зафиксировать тот факт, что с поставщиком с номером JS1' будет заключен договор
на период времени от а до Ь, где обе даты — будущие даты
Глава 22. Хронологические базы данных
857
когда данному высказыванию доверяют как истинному. Это время отличается от време-
ни транзакции, которое является множеством моментов времени, когда данное выска-
зывание действительно было представлено в базе данных как истинное. Допустимое
время может быть обновлено для отображения изменения доверия к высказыванию, а
время транзакции — не может. Время транзакции полностью управляется системой, и ни
один пользователь не может его изменить (обычно это время явно или неявно записыва-
ется в журнал транзакций).
Замечание. В предыдущем абзаце упоминались интервалы и множества моментов
времени, которые неявно представляют хотя и простую, но важную идею, а именно —
что интервал с начальным временем s и конечным временем е фактически означает
множество таких моментов t, что s < t < е (где “<” означает, конечно, “раньше чем”).
Хотя это простое понятие вполне “очевидно”, оно имеет далеко идущие последствия, в
чем мы убедимся в последующих разделах.
Большая часть предыдущего обсуждения умышленно была построена так, чтобы у
читателя возникли определенные вопросы. Независимо от того, достигнута ли данная
цель, перечислим эти вопросы и попытаемся на них ответить.
1. Определяют ли такие выражения, как “множество моментов t, такое, что s <
t < е”, бесконечные множества элементов, вызывающие, как и другие бесконеч-
ные множества, некоторые концептуальные и вычислительные трудности, харак-
терные для работы с ними?
Ответ. Да, сказанное выше имеет место. Но все эти трудности можно обойти,
если предположить, что “шкала времени” содержит конечную последователь-
ность дискретных неделимых квантов времени (долей времени). В этом случае
интервал с начальным временем s и конечным временем е содержит заведомо
конечное число таких квантов.
Замечание. Во многих работах квант времени называется хрононом. Однако
при этом сам хронон определяется как интервал (см., например, словарь тер-
минов в [22.2]) и подразумевается, что он имеет начальную и конечную точки
(возможно, еще точки между ними) и, следовательно, не является неделимым.
(Что конкретно представляют собой эти точки? Чем еще они могут быть, кроме
хрононов?) Мы считаем, что здесь есть противоречие, и поэтому будем избе-
гать данного термина.
2. В высказываниях 1-3, вероятно, подразумевается, что кванты времени — это дни,
но система, безусловно, поддерживает отсчет времени с точностью до долей секун-
ды. Если с поставщиком с номером ' S1' договор был заключен 1 июля 1999 года, а
не 30 июня 1999 года, то что можно сказать о периоде от начала суток 1 июля до
момента подписания договора с поставщиком с номером ' S1' ?
Ответ. Необходимо четко различать кванты времени как таковые, являющиеся
самыми малыми единицами времени, которые могут быть представлены в систе-
ме, и единицы времени, используемые для конкретного применения, например
год, состоящий из месяцев, каждый из которых, в свою очередь, состоит из дней
или недель, и т.д. Подобные единицы мы будем называть моментами времени,
или, для краткости, просто моментами, подчеркивая тем самым, что для наших
целей они также рассматриваются как неделимые. Тогда неформально можно
858
Часть V. Дополнительные аспекты
сказать, что моменты времени являются “отрезками шкалы времени” (т.е. мно-
жеством квантов времени), которые продолжаются от границы одного кванта до
границы следующего, например от полуночи одного дня до полуночи следующе-
го дня. Поэтому можно сказать, опять-таки неформально, что моменты времени
имеют продолжительность (в нашем примере это один день). Однако формально
моменты времени, повторяем, неделимы и понятие протяженности для них ни
коим образом не применяется.
Замечание. Во многих публикациях для ссылки на моменты времени как мы их оп-
ределили, используется термин гранула. Однако, к сожалению, как и в случае тер-
мина хронон, гранулу рассматривают как интервал. Поэтому мы будем избегать
употребления и этого термина3. Тем не менее мы будем использовать неформаль-
ный термин зернистость, который определим, тоже неформально, как продолжи-
тельность соответствующего момента времени. Таким образом, можно сказать, что
в нашем примере зернистость момента времени составляет один день. Это означа-
ет, что мы в данном контексте отбрасываем наше обычное понимание дня, состоя-
щего из часов, состоящих, в свою очередь, из минут, и т.д. (такие понятия могут
быть выражены лишь посредством более мелкой зернистости).
3. Если шкала времени по существу представляет собой последовательность момен-
тов времени (с некоторой зернистостью), то можно, не вызывая какой-либо дву-
смысленности, обращаться к “непосредственно следующему времени” (или пред-
шествующему) для какого-либо момента времени. Верно ли это?
Ответ. Да, но лишь до определенных моментов времени. Этими моментами, без-
условно, являются конец и начало шкалы времени при движении по ней в прямом и
обратном направлениях соответственно. Начало шкалы времени — это момент
времени, который не имеет предшествующего момента (возможно, он соответству-
ет вычисленному астрономами моменту предполагаемого “большого взрыва” в
теории происхождения Вселенной). Конец шкалы времени — это момент времени,
за которым пока нет последующего момента.
4. Если некоторое отношение включает кортеж из трех атрибутов, представляющий
тот факт, что договор с поставщиком с номером 'S1' был подписан 1 июля
1999 года и будет действителен по 25 сентября 2000 года, то не требует ли допуще-
ние о замкнутости мира (см. главу 5), чтобы то же самое отношение включало и
аналогичный кортеж, представляющий, например, тот факт, что договор с постав-
щиком с номером ' S1' был действителен также со 2 июля 1999 года по 24 сентября
2000 года, и множество других кортежей, представляющих прочие тривиальные
следствия исходного кортежа?
3 На наш взгляд, заблуждение, при котором хрононы и гранулы рассматриваются в качестве
интервалов, возникает из-за того, что имеет место путаница между интуитивным и формаль-
ным. Интуитивное понимание каких-либо материальных процессов — это одно дело, а их фор-
мальная модель — совсем другое. В частности, можно считать график времени непрерывным и
бесконечным, однако в нашей модели (в том числе по соображениям, которые связаны с воз-
можностями проведения вычислений) он полагается дискретным и конечным.
Замечание. В дополнение к обсуждаемой теме следует сказать, что хотя концепция кванта време-
ни (или хронона) весьма полезна как основа для описания формальной модели на интуитивном уровне,
сама по себе она вовсе не является частью этой модели и не имеет для нее какого-либо значения.
Глава 22. Хронологические базы данных
859
Ответ. Интересный вопрос! Очевидно, что необходим более ограничивающий
предикат по сравнению с общей интерпретацией данного кортежа с тремя атрибу-
тами, а именно: “С поставщиком с номером ' Sx' был подписан договор, действи-
тельный каждый день с даты s по дату е, но не в день, непосредственно предшест-
вующий s, и не в день, непосредственно следующий за е”4. Эта более ограничи-
вающая интерпретация в общем виде предоставляет мотивировку и основу для
многих операторов, которые будут описаны в этой главе, в частности в разде-
лах 22.8 и 22.10.
22.3. Основная проблема хронологических
баз данных
В последующих примерах этой главы в качестве основы по-прежнему будет использо-
ваться база данных поставщиков и деталей, но, чтобы она лучше подходила для наших целей,
необходимо внести в нее несколько изменений. Прежде всего, для упрощения примеров уда-
лим переменную-отношение Р. Во-вторых, откорректируем состав атрибутов переменной-
отношения поставок SP, отбросив атрибут QTY и оставив лишь атрибуты S# и Р#. Измененную
таким образом переменную-отношение SP можно интерпретировать так: “Поставщик с номе-
, ром S# в настоящее время может поставить деталь с номером Р#”. Иначе говоря, вместо то-
го чтобы показывать действительные поставки деталей поставщиками, переменная-
отношение SP теперь показывает лишь потенциально возможные поставки, т.е. возможно-
сти поставщиков поставлять детали. На рис. 22.1 представлена исправленная версия рис. 3.8
из главы 3. Здесь отображено множество данных, содержащихся в измененной базе данных.
Обратите внимание, что эта база данных по-прежнему имеет тип моментального снимка, по-
скольку еще не включает никаких хронологических сведений.
Теперь приступим к обсуждению некоторых простых ограничений и запросов для
этой базы данных. Позднее рассмотрим, что случится с ограничениями и запросами, ес-
ли база данных будет расширена различными хронологическими функциями.
Ограничения (для текущей версии базы данных типа моментального снимка). Единст-
венные ограничения, которые будут рассмотрены, — это ограничения для ключа. Напом-
ним, что {S#} и {S#,P#} — первичные ключи переменных-отношений S и SP соответствен-
но, a {S#} — внешний ключ переменной-отношения SP, который ссылается на первичный
ключ переменной-отношения S (безусловно, внешний ключ {Р#} не учитывается).
Запросы (для текущей версии базы данных типа моментального снимка). Запросы,
которые мы будем обсуждать, очень просты, и их всего два.
Запрос 1.1. Определить номера поставщиков, которые в настоящее время могут
поставить некоторую деталь.
SP { S# }
4 Везде в этой главе неуточненный термин “предикат ” используется для обозначения внеш-
него предиката, который понятен пользователям (см. главу 8), а не внутреннего, понятного сис-
теме (последний является, конечно, предикатом переменной-отношения/ Кроме того, мы не за-
трагиваем здесь аспекты внешнего предиката, которые или “очевидны”, или не имеют отноше-
ния к теме нашего обсуждения.
860
Часть V. Дополнительные аспекты
Запрос 1.2. Определить номера поставщиков, которые в настоящее время не могут
поставлять никаких деталей.
S { S# } MINUS SP { S# }
S S# SNAME STATUS CITY SP S# P#
S1 S2 S3 S4 S5 Smith Jones Black Clark Adams 20 10 30 20 30 London Paris Paris London Athens SI SI SI SI SI SI S2 S2 S3 S4 S4 S4 Pl P2 P3 P4 P5 P6 Pl P2 P2 P2 P4 P5
Рис. 22.1. База данных поставщиков и деталей (значения для примера): текущая версия
типа моментального снимка
Отметим, что запрос 1.1 включает простую операцию проекции, а запрос 1.2 — опе-
рацию разности между двумя подобными проекциями. Позднее, при рассмотрении хро-
нологических вариантов этих двух запросов, мы убедимся, что они включают хроноло-
гические аналоги этих двух операторов (см. раздел 22.8).
Замечание. Возможно, читателя не удивит тот факт, что могут быть определены хро-
нологические аналоги и других реляционных операторов (см. упр. 22.8).
“Полуограниченные во времени” поставщики и поставки
Чтобы изменения вносились постепенно, на следующем этапе мы введем в пере-
менные-отношения S и SP только “полухронологичность” (если можно так выра-
зиться). Для этого к каждой из них добавим атрибут временной отметки SINCE
(Начиная с), а затем соответственно переименуем эти переменные-отношения так,
как показано на рис. 22.2.
Для упрощения представления информации на рис. 22.2 показаны не реальные вре-
менные отметки, а условные обозначения вида dOl, d02 и т.д., где d может для удобства
произноситься как “день”. Указанного соглашения мы будем придерживаться до конца
этой главы. (Таким образом, во всех примерах будут использоваться временные отметки,
которые являются днями.) Далее подразумевается, что день 1 непосредственно предше-
ствует дню 2, день 2 непосредственно предшествует дню 3 и т.д. Кроме того, незначащие
ведущие нули в таких выражениях, как ' день 1', отбрасываются.
Предикат для переменной-отношения S_SINCE формулируется так: “Поставщик с
номером Si ис именем SNAME имеет статус STATUS, находится в городе CITY, и договор
с ним заключен с дня SINCE”. Предикат для переменной-отношения SP_SINCE форму-
лируется так: “Поставщик с номером S# может поставлять деталь с номером P# начи-
ная с дня SINCE”.
Глава 22. Хронологические базы данных
861
S SINCE
S# SNAME STATUS CITY SINCE
S1 Smith 20 London d04
S2 Jones 10 Paris d07
S3 Black 30 Paris d03
S4 Clark 20 London d04
S5 Adams 30 Athens d02
SP SINCE
S# P# SINCE
SI Pl d04
SI P2 d05
SI P3 d09
SI P4 d05
SI P5 d04
SI P6 d06
S2 Pl d08
S2 P2 d09
S3 P2 d08
S4 P2 d06
S4 P4 d04
S4 P5 d05
Puc. 22.2. База данных поставщиков и деталей (значения для примера): "полухроноло-
гическая ” версия
Ограничения (“полухронологическая” база данных). Первичные и внешние ключи
для новой полухронологической базы данных те же, что и раньше. Однако требуется
ввести дополнительное ограничение, которое могло бы рассматриваться как расширен-
ное ограничение внешнего ключа в переменной-отношении SP_SINCE для переменной-
отношения S_SINCE. Оно необходимо для отражения того факта, что ни один поставщик
не может поставить ни одной детали прежде, чем с ним будет заключен договор. Иными
словами, если кортеж sp в переменной-отношении SP_SINCE ссылается на кортеж s в пе-
ременной-отношении S_SINCE, то значение SINCE в кортеже sp не должно быть меньше,
чем значение SINCE в кортеже s.
CONSTRAINT AUG_SP_TO_S_FK
IS_EMPTY ( ( ( S_SINCE RENAME SINCE AS SS ) JOIN
( SP_SINCE RENAME SINCE AS SPS ) )
WHERE SPS < SS ) ;
С этого примера мы и начнем рассмотрение основной проблемы хронологических баз
данных. Для “полухронологической” базы данных, аналогичной показанной на рис. 22.2,
по-видимому, потребуется установить много “расширенных ограничений внешнего клю-
ча”, подобных приведенному выше. Поэтому нам, скорее всего, потребуются некоторые
подходящие случаю способы их сокращенной записи.
Запросы (“полухронологическая” база данных). Рассмотрим “полухронологические”
версии запросов 1.1 и 1.2.
Запрос 2.1. Определить номера поставщиков, которые в настоящее время могут
поставить некоторую деталь, показав в каждом случае дату, начиная с которой они
способны выполнить эту поставку.
Если поставщик с номером ' Sx' в настоящее время может поставить несколько дета-
лей, он может поставить некоторую деталь начиная с наименьшей даты SINCE, которая
есть среди значений дат для поставщика с номером 'Sx' в переменной-отношении
SP_SINCE (например, если в качестве значения номера 'Sx' взять 'S1', наименьшей да-
той в столбце SINCE для него будет дата d04). Значит, получаем следующее.
862
Часть К. Дополнительные аспекты
SUMMARIZE SP PER SP { S#} ADD MIN { SINCE } AS SINCE
Результат будет таким, как показано ниже.
S# SINCE
S1 d04
S2 d08
S3 d08
S4 d04
Запрос 2.2. Определить номера поставщиков, которые в настоящее время не могут
поставить ни одной детали, показав в каждом случае дату, начиная с которой они
оказались в этом положении.
В нашей базе данных имеется один поставщик, который в настоящее время не
может поставить ни одной детали, — это поставщик с номером 'S5'. Однако нельзя
сделать какой-либо вывод о дате, начиная с которой поставщик с номером ' S5' не
может поставить ни одной детали, поскольку для этого у нас нет данных — база
данных пока лишь “лолухронологическая”. Предположим, например, что текущий
день — это did. Тогда может оказаться, что поставщик с номером 'S5' мог постав-
лять по крайней мере одну деталь начиная с даты, которая меньше даты d2, если с
ним ранее был подписан договор, срок действия которого истек не позднее, чем d09.
Также возможен крайний случай, когда поставщик с номером 'S5' вообще никогда
не имел возможности что-либо поставлять.
Чтобы иметь хоть какие-то шансы получить ответ на запрос 2.2, необходимо за-
вершить “хронологизацию” базы данных или по крайней мере выполнить это в от-
ношении переменной-отношения SP. Точнее, необходимо сохранить в базе данных
исторические записи, свидетельствующие о том, какие поставщики, когда и какие
именно детали могли поставлять. Именно это мы и попытаемся сделать в следую-
щем разделе.
Полностью хронологическая база данных поставщиков
и поставок
На рис. 22.3 показано содержимое полностью хронологической версии базы данных
поставщиков и поставок. Обратите внимание, что атрибуты SINCE переименованы в ат-
рибуты FROM (От) и, кроме того, в каждую переменную-отношение добавлен новый атри-
бут типа временной отметки с именем ТО (До). Совместно атрибуты FROM и ТО отражают
понятие интервала времени, в течение которого что-то истинно. Поэтому в именах пере-
менных-отношений заменим слово SINCE (Начиная с) словом FROMJTO (От и до). Как ви-
дите, теперь в новой базе данных стало больше кортежей, чем в предыдущем варианте,
поскольку в ней сохранены исторические записи. Для определенности будем подразуме-
вать, что текущая дата — это dl 0, поэтому значение даты dl 0 для атрибута ТО означает,
что соответствующий кортеж отражает текущее состояние дел.
Замечание. Возможно, читателю интересно, что это за механизм, который приводит к
тому, что все значения атрибута ТО, которые совпадают с текущей датой dl 0, автоматиче-
ски заменяются значением dll по бою часов в полночь. К сожалению, ответ этот вопрос
мы вынуждены на некоторое время отложить, но мы вернемся к нему в разделе 22.11.
Глава 22. Хронологические базы данных
863
Заметим, что хронологическая база данных, показанная на рис. 22.3, включает все
данные из предыдущего “полухронологического” аналога, представленного на
рис. 22 2, дополненные историческими сведениями, относящимися к предыдущему пе-
риоду (от d02 до d04), в течение которого был действителен договор с поставщиком с
номером 'S2'. Предикат для переменной-отношения S_FROM_TO можно сформулиро-
вать так: “Поставщик с номером S# и с именем SNAME имел статус STATUS, находился в
городе CITY и имел договор на поставку, действительный с дня FROM (и не действи-
тельный в день, предшествующий дню FROM) по день ТО (и не действительный в день,
следующий за днем ТО)”. Для переменной-отношения SP_FROM_TO предикат построен
по аналогичному принципу.
S FROM TO s# SNAME STATUS CITY FROM TO
SI Smith 20 London d04 dlO
S2 Jones 10 Paris d07 dlO
S2 Jones 10 Paris d02 d04
S3 Black 30 Paris d03 dlO
S4 Clark 20 London d04 dlO
S5 Adams 30 Athens d02 dlO
SP FROM TO S# P# FROM TO
SI Pl d04 dlO
SI P2 d05 dlO
SI P3 d09 dlO
SI P4 d05 dlO
SI P5 d04 dlO
SI P6 d06 dlO
S2 Pl d02 d04
S2 P2 d03 d03
S2 Pl d08 dlO
S2 P2 d09 dlO
S3 P2 d08 dlO
S4 P2 d06 d09
S4 P4 d04 d08
S4 P5 d05 dlO
Рис. 22.3. База данных поставщиков и деталей (значения для примера): первая полно-
стью хронологическая версия с использованием временных отметок
Ограничения (первая хронологическая база данных). Прежде всего необходимо
принять меры, чтобы в кортежах не появлялись ошибочные пары атрибутов FROM-ТО, в
которых момент ТО предшествует моменту FROM.
CONSTRAINT S_FROM_TO_OK
IS_EMPTY ( S_FROM_TO WHERE TO < FROM ) ;
CONSTRAINT SP_FROM_TO_OK
IS_EMPTY ( SP_FROM_TO WHERE TO < FROM ) ;
864
Часть К Дополнительные аспекты
Теперь обратите внимание на атрибуты, подчеркнутые на рис. 22.3 двойной линией.
Как видите, атрибут FROM включен в первичный ключ обеих переменных-отношений,
S_FROM_TO и SP_FROM_TO. Очевидно, что первичный ключ переменной-отношения
S_FROM_TO не может быть просто {S#}, поскольку в этом случае в переменную-
отношение нельзя было бы включить сведения об одном и том же поставщике, с кото-
рым договоры на поставку заключались на несколько различных периодов. Точно такие
же соображения применимы и в отношении переменной-отношения SP_FROM_TO.
Замечание. В первичный ключ вместо атрибута FROM можно было бы включить атри-
бут ТО. Фактически обе переменные-отношения, S_FROM_TO и SP_FROM ТО, имеют по два
потенциальных ключа и являются типичным примером переменных-отношений, для ко-
торых нет никаких очевидных причин выбирать один из имеющихся потенциальных
ключей в качестве “первичного” [8.13]. Мы сделали указанный выбор исключительно
для определенности.
Однако этими первичными ключами не исчерпываются все ограничения, которые
нам хотелось бы иметь. Рассмотрим, например, переменную-отношение SP_FROM_TO.
Должно быть ясно, что если в такой переменной-отношении есть кортеж для по-
ставщика с номером 'Sx' со значением f атрибута FROM и значением t атрибута ТО,
то нам хотелось бы, чтобы в этой переменной-отношении не было какого-нибудь
другого кортежа для поставщика с номером 'Sx', из значения которого следовало
бы, что этот поставщик заключил договор со дня, непосредственно предшествующе-
го дню f, или по день, непосредственно следующий за днем t. Например, рассмот-
рим поставщика с номером ' S1', для которого в переменной-отношении SP_FROM_TO
имеется один кортеж со значениями атрибутов FROM=d04 и ТО=Л0. Одного того, что
{S#,FROM} является первичным ключом для этой переменной-отношения, очевидно,
недостаточно, чтобы предотвратить появление других “перекрывающихся” корте-
жей для поставщика с номером 'S1', например кортежа со значениями атрибутов
FROM=d02 и TO=d06. Если бы такой кортеж появился, то это, кроме всего прочего,
указывало бы, что с поставщиком с номером 'S1' был заключен договор, который
являлся действительным в день, непосредственно предшествующий дню d04. Веро-
ятно, следовало бы объединить такие два кортежа в один кортеж, в котором значе-
ния атрибутов были бы соответственно равны FROM=d02 и TO=dl05.
Кроме того, лишь одного факта, что {S#,FROM} является первичным ключом для пе-
ременной-отношения SP_FROM_TO, также недостаточно, чтобы предотвратить появление
“смежных” кортежей для поставщика с номером ' S1', например таких, в которых значе-
ниями атрибутов будут FROM=d02 и H0=d03. В данном случае это означало бы, что с по-
ставщиком с номером 'S1' был заключен договор, действительный, включая день, кото-
рый непосредственно предшествует дню d04. Как и в предыдущем случае, такие кортежи
должны быть объединены в один общий кортеж.
5 Заметим, что если не объединить такие кортежи, это будет почти равносильно разреше-
нию существования дубликатов! Наличие дубликатов означает, что в базе данных "об одном и
том же говорится дважды ". Однако два кортежа для поставщика с номером 'S1' с перекры-
вающимися интервалами времени фактически "говорят об одном и том же дважды ", а имен-
но — оба они "утверждают ”, что с поставщиком с номером 'S1' был заключен договор, срок
действия которого включает дни 4, 5 и 6.
Глава 22. Хронологические базы данных
865
Ниже представлено ограничение, которое запрещает перекрытие и смежность вре-
меннь/х диапазонов.
CONSTRAINT AUG_S_FROM_TO_PK
IS_EMPTY ( ( ( S_FROM_TO RENAME FROM AS Fl, TO AS Tl ) JOIN
( S_FROM_TO RENAME FROM AS F2, TO AS T2 ) )
WHERE ( Tl > F2 AND T2 > Fl ) ) OR
( F2 = Tl+1 OR Fl = T2+1 ) ) ;
Это выражение несколько запутанное, не говоря уже о том, что здесь допущены оп-
ределенные вольности в написании (например, выражение Т1+1 используется для обо-
значения дня, непосредственно следующего за днем Т1). К этому вопросу мы еще воз-
вратимся в разделе 22.5.
Замечание. Фактически наличие данного ограничения позволяет обращаться к соче-
танию атрибутов {S#,FROM,ТО} как к хронологическому потенциальному ключу (точнее,
к хронологическому первичному ключу). Однако это не очень хороший термин, посколь-
ку “хронологический” потенциальный ключ не является на самом деле потенциальным
ключом переменной-отношения, которая его содержит. (В разделе 22.9 мы обсудим
“хронологические потенциальные ключи”, которые являются настоящими потенциаль-
ными ключами в классическом смысле этого термина.)
Далее необходимо отметить, что сочетание атрибутов {S#,FROM} в переменной-
отношении SP_FROM_TO не является внешним ключом переменной-отношения
SP_FROM_TO для переменной-отношения S_FROM_TO, несмотря на то что это сочетание
включает те же атрибуты, что и первичный ключ переменной-отношения S FROM_TO. Од-
нако нам необходимо быть уверенными, что если сведения о некотором поставщике
имеются в переменной-отношении SP_FROM_TO, то они присутствуют и в переменной-
отношении S_FROM_TO.
CONSTRAINT AUG_SP_TO_S_FK_AGAIN1
SP_FROM_TO { S# } < S_FROM_TO { S# } ;
(Здесь знак “<” означает “является подмножеством”.)
Но ограничения AUG_SP_TO_S_FK_AGAIN1 самого по себе недостаточно. Необходимо
иметь уверенность в том, что даже после выполнения всех возможных объединений
кортежей, если в переменной-отношении SP FROM ТО некоторый поставщик может по-
ставлять некоторую деталь в течение некоторого времени, в переменной-отношении
S FROMJTO обязательно есть кортеж для этого поставщика, указывающий, что на опре-
деленный период договор с ним действительно был заключен. Это можно попытаться
выразить так.
CONSTRAINT AUG_SP_TO_S_FK_AGAIN2 /* внимание - некорректно */
IS_EMPTY ( ( (”S_FROM_TO RENAME FROM AS SF, TO AS ST ) JOIN
( SP_FROM_TO RENAME FROM AS SPF, TO AS SPT ) )
WHERE SPF < SF OR SPT > ST ) ;
Однако, как сказано в комментарии, данное определение фактически неверно. Чтобы
разобраться, почему именно, рассмотрим пример. Пусть переменная-отношение
S_FROM_TO будет такой, как показано на рис. 22.3, и пусть переменная-отношение
866
Часть V. Дополнительные аспекты
SP_FROM_TO содержит кортеж для поставщика с номером 'S2' с атрибутами, скажем,
FROM=d03 и HO=d04. Очевидно, что такое сочетание является допустимым, но на самом
деле ограничение AUG_SP_TO_S_FK_AGAIN2 его запрещает.
Здесь мы не будем пытаться решить эту проблему, а отложим ее обсуждение до раз-
дела 22.9. Однако отметим, что если, как указывалось ранее, сочетание атрибутов
{S#,FROM,ТО} в переменной-отношении S_FROM_TO считается “хронологическим потен-
циальным ключом”, то сочетание атрибутов {S#,FROM,ТО} в переменной-отношении
SP_FROM_TO можно считать “хронологическим внешним ключом” (хотя он на самом деле
не является внешним ключом как таковым). Обсуждение этого вопроса также будет про-
должено в разделе 22.9.
Запросы (первая хронологическая база данных). Рассмотрим полные хронологиче-
ские версии запросов 1.1 и 1.2.
Запрос 3.1. Получить тройки значений атрибутов S#, FROM и ТО для поставщиков,
которые в некоторое время могут поставить некоторую деталь, где FROM и ТО вме-
сте означают максимальный непрерывный период, в течение которого поставщик
с номером S# действительно мог поставить некоторую деталь.
Замечание. Здесь слово “максимальный” используется как удобное сокращение,
которое в данном случае означает, что поставщик с номером S# не мог поставить
ни одной детали до дня FROM и после дня ТО.
Запрос 3.2. Получить тройки значений атрибутов S#, FROM и ТО для поставщиков,
которые в определенное время не могут поставить никаких деталей, где FROM и ТО
вместе означают максимальный непрерывный период, в течение которого по-
ставщик с номером S# действительно не мог поставлять никаких деталей.
Вероятно, вам не потребуется много времени, чтобы, как и нам, предпочесть даже не
приступать к написанию этих запросов! Если вы все-таки предпримете такую попытку,
то в конце концов тот факт, что эти запросы можно выразить, хотя и чрезвычайно труд-
но, станет вам известен. Также несомненно, что вы придете к выводу о крайней жела-
тельности соответствующих сокращений.
Можно сделать заключение, что суть проблемы хронологических данных состоит в
том, что их наличие требует создания ограничений и запросов, которые чрезмерно слож-
ны, чтобы их сформулировать, если, конечно, системой не предоставляются удачно раз-
работанные сокращения, которых, как нам известно, коммерческие СУБД в настоящее
время не имеют.
22.4. Интервалы
А теперь займемся разработкой соответствующего набора сокращений. Первый и
наиболее важный шаг— понять необходимость применения интервалов как таковых
вместо того, чтобы интерпретировать их как пары отдельных значений, как мы это дела-
ли до сих пор.
Что же конкретно представляет собой интервал времени? Согласно рис. 22.3 постав-
щик с номером 'S1' мог поставлять деталь с номером 'Р1' в течение интервала с дня 4
по день 10. Но что означает выражение “интервал с дня 4 по день 10”? Ясно, что дни 5,
6, 7, 8 и 9 в него включаются, но что можно сказать о начальной и конечной точках, о
Глава 22. Хронологические базы данных
867
днях 4 и 10? Оказывается, задавая некоторый конкретный интервал, мы иногда считаем,
что указанные начальная и конечная точки включаются в интервал, а иногда— нет. Если
интервал с дня 4 по день 10 включает день 4, то говорят, что он закрыт относительно
его начальной точки, в противном случае говорят, что интервал открыт относительно
его начальной точки. Точно так, если интервал включает день 10, то говорят, что он за-
крыт относительно его конечной точки, в противном случае говорят, что интервал от-
крыт относительно его конечной точки.
Поэтому принято обозначать интервал начальной и конечной точками (именно в этом
порядке), предваряя его открывающей квадратной скобкой или открывающей круглой
скобкой и заключая его закрывающей квадратной скобкой или закрывающей круглой
скобкой. Квадратные скобки используются, когда интервал закрыт, а круглые скобки —
когда он открыт. Таким образом, интервал, например, с 4 по 10 день, можно обозначить
четырьмя различными способами.
[d04,dl0]
[d04,dll)
(dO3,dlO]
(d03,dll)
Замечание. Вам может показаться странным, например, что используются откры-
вающая квадратная скобка и закрывающая круглая скобка. Однако есть веские причины
использования всех четырех вариантов обозначения интервалов. В действительности на
практике наиболее часто используется так называемый “закрыто-открытый” вариант
(открывающие квадратные скобки и закрывающие круглые скобки)6.
Однако “закрыто-закрытый” вариант (открывающие квадратные скобки и закрываю-
щие квадратные скобки), несомненно, наиболее интуитивно понятный, и поэтому мы бу-
дем отдавать предпочтение именно ему.
Поскольку интервалы, такие как [d04,dlO], сами по себе являются значениями,
имеет смысл объединить атрибуты FROM и ТО переменной-отношения, скажем,
SP FROM_TO (см. рис. 22.3), ,в отдельный атрибут DURING, значения которого берутся
из интервального типа (подробности приводятся в следующем разделе). Непосред-
ственное преимущество этой идеи заключается в том, что отпадает необходимость в
произвольном выборе одного из двух потенциальных ключей ([S#,FROM] или
[S#,ТО)) в качестве первичного. Еще одно преимущество состоит в том, что теперь
не нужно решать, как интерпретировать интервалы FROM-ТО, показанные на
рис. 22.3, — как закрытые или как открытые по отношению к каждому значению ат-
рибутов FROM и ТО. Фактически интервалы [d04,d20], [d04tdll), (d03,dl0] и
(d03tdll) теперь становятся четырьмя отдельными возможными представлениями
одного и то же интервала и нам нет необходимости знать, каково реальное пред-
ставление. К тому же к преимуществам можно отнести и то, что ограничения пере-
менной-отношения для предотвращения появления “ошибочных пар атрибутов
FROM-ТО, в которых точка ТО предшествует точке FROM” (как указывалось в разде-
ле 22.3) больше не нужны, поскольку ограничение “FROM < ТО” подразумевается в
6 Чтобы понять, почему “закрыто-открытый” вариант интервала может быть более
предпочтительным, рассмотрим операцию разбиения интервала /d04,dl0j перед, скажем,
днем d07. В результате получим смежные интервалы fd04,d07) и [dO 7 ,dl 0 ].
868
Часть V. Дополнительные аспекты
самом понятии интервального типа. Также является преимуществом то, что теперь
не придется иметь дело с “хронологическими ключами”, которые на самом деле та-
ковыми не являются (в классическом понимании этого термина), как указывалось в
разделе 22.9. Остальные ограничения, которые рассматривались в разделе 22.9, так-
же могут быть упрощены. На рис. 22.4 показано, как изменится наш пример базы
данных, если использовать этот новый подход.
22.5. Интервальные типы
В предыдущем разделе рассуждения об интервалах основывались, по существу, на
интуиции. Теперь необходимо изложить этот подход более формально. Отметим, что
зернистость интервального значения — “дни”. Точнее, можно сказать, что
зернистость относится к типу DATE, т.е. мы подразумеваем, что единица измерения зер-
нистости принадлежит к обычному семейству типов даты и времени, а его размер-
ность — “день” (в противоположность, скажем, “часам”, “миллисекундам” или
“месяцам”). Исходя из данного замечания можно точно определить тип интервального
значения [d04,dl0].
S_DURING S# SNAME STATUS CITY DURING
SI Smith 20 London [d04,dl0]
S2 Jones 10 Paris [dO7,dlO]
S2 Jones 10 Paris [d02,d04}
S3 Black 30 Paris [d03,dl0]
S4 Clark 20 London [d04,dl0]
S5 Adams 30 Athens [d02,dl0]
SP_DURING S# P# DURING
SI Pl [d04,dl0]
SI P2 [d05,dl0]
SI P3 [d09,dl0]
SI P4 [d05,dl0}
SI P5 [d04,dl0]
SI P6 [d06,dl0]
S2 Pl [d02,d04}
S2 P2 [d03,d03]
S2 Pl [d08,dl0]
S2 P2 [d09,dl0]
S3 P2 [d08,dl0]
S4 P2 [d06,d09]
S4 P4 [d04,d08]
S4 P5 [d05.dl0\
Рис. 22.4. База данных поставщиков и деталей (значения для примера): окончательный
вариант полной хронологической версии с использованием интервалов
Во-первых, это, конечно, некоторый интервальный тип. Только одного этого
факта достаточно, чтобы определить операторы, которые применимы к рассмат-
риваемому интервальному значению (точно так, когда говорят, например, что, ес-
Глава 22. Хронологические базы данных
869
ли значение г относится к типу отношение, этого достаточно, чтобы определить
операторы (JOIN и т.д.), которые применимы к значению г).
Во-вторых, рассматриваемое интервальное значение является интервалом от
одной даты до другой, и этого факта достаточно для того, чтобы определить
множество интервальных значений, которые составляют рассматриваемый ин-
тервальный тип.
Таким образом, тип значения [d04,d!0] — INTERVAL (DATE), где
a) INTERVAL— генератор типа, подобный RELATION в языке Tutorial D (см. главу 5)
или массиву array в обычном языке программирования; этот генератор типа по-
зволяет определить множество конкретных типов интервалов, которые будут рас-
смотрены далее;
б) DATE — точечный тип данного интервального типа.
Следует подчеркнуть, что в общем случае точечный тип РТ определяет тип и точ-
ность начальной и конечной точек, а также всех точек между двумя последними, ко-
торые имеют значения типа INTERVAL(РТ). (В случае типа DATE точность, конечно, за-
дается неявно.)
Замечание. В главе 4 уже отмечалось, что точность не является частью соответст-
вующего типа и должна задаваться ограничением целостности. Например, в объявле-
ниях DECLARE X TIMESTAMP(3) и DECLARE Y TIMESTAMP(6) атрибуты X и Y имеют один
и тот же тип, но зависят от различных ограничений (согласно этим ограничениям в ат-
рибуте X должны содержаться значения в миллисекундах, тогда как значения атрибута
Y измеряются в микросекундах). Поэтому, строго говоря, чтобы сказать, например, что
TIMESTAMP(3) и DATE— это допустимые точечные типы, необходимо объединить два
понятия, которые лучше было бы иметь отдельными понятиями. Вместо этого, пожа-
луй, было бы предпочтительнее определить два типа Т1 и Т2, оба с возможными пред-
ставлениями типа временных отметок TIMESTAMP, но с различными “ограничениями
точности”. Затем можно сказать, что допустимыми точечными типами являются типы,
Т1 и Т2 (а не, например, TIMESTAMP(3) и TIMESTAMP(6)). Однако для простоты мы сле-
дуем в этой главе общепринятой практике и условно считаем, что точность действи-
тельно является частью типа.
Какие свойства должен иметь тип, чтобы он был допустимым как точечный тип?
Прежде всего, нам известно, что интервал обозначается своими начальной и конечной
точками и содержит, по крайней мере неформально, множество точек. Если можно опре-
делить полное множество точек, задав просто начальную точку s и конечную точку е,
необходимо, чтобы можно было определить точку, которая непосредственно следует (в
некотором установленном порядке) за точкой s. Такую непосредственно следующую
точку называют наследником или преемником точки s. Условимся для простоты, что в
качестве обозначения такой точки будет использоваться выражение s+1. Тогда функция,
с помощью которой определяется точка s+1 по точке s, называется функцией следова-
ния для данного точечного типа (и точности). Функция следования должна быть опреде-
лена для каждого значения точечного типа, за исключением точки, определенной как
“последняя”. (Имеется и точка, определяемая как “первая”, которая не является следую-
щей за какой-либо точкой.)
870
Часть К Дополнительные аспекты
Если точка s+1 определена как следующая за точкой s, необходимо установить, не
следует ли точка s+1 за точкой е, в соответствии с тем же принятым порядком следова-
ния для точечного типа. Если это не так, точка s+1 действительно принадлежит интерва-
лу [s,e] и нужно переходить к следующей точке s+2. Этот процесс мы можем продол-
жать до тех пор, пока не перейдем к первой точке s+n, которая следует за точкой е. В ре-
зультате такого прохода будут перебраны все точки интервала [ s, е].
Поскольку точка s+n фактически является преемником точки е, т.е. в действитель-
ности непосредственно следует за точкой е, можно утверждать, что единственное
свойство, согласно которому тип РТ должен быть допустимым как точечный тип, рав-
носильно тому, что для него должна быть определена функция следования. Короче го-
воря, должно быть установлено общее упорядочение для значений типа РТ (поэтому
можно считать, что для всех пар значений РТ определены и доступны обычные опера-
торы сравнения “<”, “>” и т.д.).
Кстати, вы, наверное, уже заметили, что хронологические данные больше конкретно
не упоминаются. И в оставшейся части главы речь также будет идти, в основном, об ин-
тервалах вообще, а не о конкретно хронологических интервалах, хотя в разделе 22.11 бу-
дут рассмотрены и конкретные вопросы, касающиеся именно хронологических данных.
Дадим, наконец, точное определение.
Пусть РТ— точечный тип. Тогда интервал (или значение интервала) 1 типа
INTERVAL(РТ) — это скалярное значение, для которого определены два унарных
оператора (START и END) и один бинарный оператор (IN), такие, что
a) START(i) и END(i) возвращают значения типа РТ;
б) START(i) < END (i);
в) пусть р — некоторое значение типа РТ; тогда р IN i истинно, если оба сравне-
ния, START (i) < р и р < END (1), дают в результате значения истина.
Обратите внимание на обращение в этом определении к некоторой функции следова-
ния для типа РТ. Также отметим, что начальная и конечная точки составляют возможное
представление (в смысле главы 5) для значений типа INTERVAL(РТ) соответственно
(поэтому в языке Tutorial D можно было бы обращаться к точкам START и END как
THE_START и THE_END). И наконец заметим, что по определению интервалы всегда непус-
тые, т.е. в любом заданном интервале всегда имеется по крайней мере одна точка.
Следует подчеркнуть, что значение типа INTERVAL(РТ) является скалярным, т.е. оно
не имеет компонентов, которые видны пользователю. Действительно, оно имеет некото-
рое возможное представление (на самом деле даже несколько возможных представлений,
как мы убедились в предыдущем разделе), и эти возможные представления имеют види-
мые для пользователя компоненты, но само значение интервала таких видимых компо-
нентов не имеет. Иначе говоря, это означает, что интервалы инкапсулированы.
22.6. Скалярные операторы для интервалов
В этом разделе будут определены некоторые полезные операторы, применяемые к
значениям интервалов. Большинство из этих операторов более или менее понятны без
дополнительных объяснений. Рассмотрим интервальный тип INTERVAL(РТ). Пусть р бу-
Глава 22. Хронологические базы данных
871
дет значением типа РТ. Обозначения р+1, р+2 и т.д. по-прежнему будут использоваться
для указания преемника р, преемника р+1 и т.д. В реальном языке для получения сле-
дующего значения может применяться некоторый оператор NEXT. Также будут использо-
ваться обозначения р-1, р-2 и т.д. для указания значений, преемниками которых являют-
ся р, р-1 и т.д. В реальном языке для получения предыдущего значения может использо-
ваться некоторый оператор PRIOR.
Пусть pl и р2— значения типа РТ. Определим оператор МАХ(р1,р2) как оператор,
возвращающий значение р2, если р1<р2, и значение pl в противном случае. Оператор
MIN(pl,p2) возвращает значение pl, если р1<р2, и значение р2 в противном случае.
Обозначения, которые использовались до сих пор, применялись для операций интер-
вальных выборок, по крайней мере в неформальном контексте. Например, в результате
обращения к выборке интервалов [3,5] и [3,6) получим значения типа
INTERVAL (INTEGER), которые будут содержать точки 3, 4 и 5. В реальном языке может
потребоваться явный синтаксис, например INTERVAL([3,5]).
Пусть Н будет интервалом [si,el] типа INTERVAL(РТ). Как указывалось выше, опе-
ратор START(il) возвращает значение si, а оператор END(И) — значение el. Кроме то-
го, определим оператор STOP(il), который возвращает значение el+1. Также обозначим
через 12 еще один интервал [s2,e2] типа INTERVAL(РТ). Теперь дадим определение опе-
раторов сравнения интервалов.
Замечание. Эти операторы также называются операторами Аллена, по имени автора
(Allen), впервые их предложившего [22.1]. В качестве упражнения можно попытаться
начертить простые схемы, которые иллюстрируют эти операторы.
Оператор сравнения il=i2 возвращает значение истина тогда и только тогда, ко-
гда sl=s2 и е1=е2.
Оператор предшествования интервала il BEFORE 12 возвращает значение истина
тогда и только тогда, когда el<s2.
Оператор смежности интервалов 11 MEETS 12 возвращает значение истина тогда
и только тогда, когда s2=el+l или sl=e2+l.
Оператор перекрытия интервалов il OVERLAPS 12 возвращает значение истина
тогда и только тогда, когда sl<e2 и s2<el.
Оператор вхождения интервала il DURING 12 возвращает значение истина тогда
и только тогда, когда s2<sl и е2>е17.
Оператор начального интервала И STARTS 12 возвращает значение истина тогда
и только тогда, когда sl=s2 и е1<е2.
Оператор конечного интервала И FINISHES i2 возвращает значение истина то-
гда и только тогда, когда е1=е2 и sl>s2.
Замечание. Определения этих операторов иначе можно представить в терминах то-
чек (соответствующего точечного типа). Например, можно сказать, что оператор
il OVERLAPS 12 возвращает значение истина тогда и только тогда, когда существует
значение ртипа РТ, такое, что оба выражения, р IN 11 и р IN 12, истинны.
7 В виде исключения в данном случае все же заметим, что название оператора DURING (в
течение) здесь не подразумевает “в течение всего интервала времени ”.
872
Часть V. Дополнительные аспекты
Следуя [22.3], можно также определить дополнительные операторы.
Оператор слияния интервалов il MERGES 12 возвращает значение истина тогда и
только тогда, когда один из операторов, 11 MEETS i2 или 11 OVERLAPS 12, воз-
вращает значение истина.
Оператор содержания интервала 11 CONTAINS 12 возвращает значение истина то-
гда и только тогда, когда оператор 12 DURING 11 возвращает значение истина*.
Чтобы получить длину (если можно так выразиться) интервала, используют оператор
DURATION (i), который возвращает количество точек в интервале 1, например
DURATION ([d03,d0 7]) = 5.
И наконец определим некоторые бинарные операторы для интервалов, которые воз-
вращают интервалы.
Результатом выполнения оператора объединения интервалов il UNION 12 являет-
ся интервал [MIN(sI,s2),МАХ(е1,е2)], если оператор 11 MERGES 12 возвращает
значение истина', в противном случае операция объединения не определена.
Результатом выполнения оператора пересечения интервалов 11 INTERSECT 12 явля-
ется интервал [MAX(sI,s2) ,MIN(el,e2) ], если оператор 11 OVERLAPS i2возвращает
значение истина; в противном случае операция пересечения не определена.
Замечание. Здесь операторы UNION и INTERSECT представляют собой обычные опера-
торы обработки множеств и не являются их специальными реляционными аналогами. В
статье [22.3] они называются соответственно MERGE и INTERVSECT.
22.7. Операторы обобщения для интервалов
В этом разделе будут рассмотрены два чрезвычайно важных оператора: UNFOLD
(развернуть) и COALESCE (свернуть). Они обрабатывают множество интервальных значе-
ний того же типа, что и их собственный операнд, и возвращают другое такое множество.
Результат в обоих случаях можно рассматривать как определенную каноническую форму
для исходного множества (о канонической форме читайте в разделе 17.3 главы 17).
Дальнейшее обсуждение будет основываться на следующих исходных данных. Пусть
XI и Х2 представляют собой два показанных ниже множества соответственно.
{ [d01,d01], [d03,d05], [d04,d06] }
{ [d01,d01], [dO3,dO4], [d05,d05], [d05,d06] }
Нетрудно заметить, что XI и Х2 — это не одно и то же множество. Почти так же легко
заметить, что множество всех точек р, таких, которые содержатся в некотором интервале
в XI, то же самое, что и множество всех точек р, таких, которые содержатся в некотором
интервале в Х2. В это множество включены точки dOl, d03, d04, d05 и d06. Однако по со-
ображениям, которые вскоре станут понятными, нас не так интересует множество самих
точек, как соответствующее множество единичных интервалов. Назовем его ХЗ.
8 Возможно, в этом случае более подходящим названием оператора было бы INCLUDES
(включает), тогда можно было бы использовать ключевое слово CONTAINS (содержит) для опе-
ратора, обратного оператору IN, определив его как i CONTAINS р, что равносильно р IN i.
Глава 22. Хронологические базы данных
873
{ [d01,d01], [d03fd03]t [d04,d04], [dO5,dO5], [d06,d06] }
Говорят, что интервал ХЗ— это развернутая форма интервала Xi (и Х2). В общем
случае, если X является множеством интервалов и все они имеют один и тот же тип, раз-
вернутая форма множествах— это множество всех интервалов вида [р, р], где р —
точка в некотором интервале из множества X.
Отметим, что множества XI, Х2 и ХЗ имеют разную кардинальность, т.е. отличаются
количеством элементов. В нашем примере получилось так, что множество ХЗ, т.е. раз-
вернутая форма, имеет наибольшую кардинальность среди всех трех множеств примера.
Но можно легко найти такое множество Х4, которое имеет ту же развернутую форму, что
и множество XI, но кардинальность которого больше кардинальности множества ХЗ
(упражнение для читателя). Также легко можно найти более интересное, и единственное,
множество Х5, которое имеет ту же развернутую форму, но минимально возможную кар-
динальность.
{ [d01,d01], [d03,d06] }
Множество Х5 называют свернутой формой множества XI (а также Х2, ХЗ и Х4). В
общем случае, если X является множеством интервалов и все они имеют один и тот же
тип, свернутая форма множествах— это множество Y, элементами которого являются
интервалы одного и того же типа, такие, что множества X и Y имеют одну и ту же развер-
нутую форму и не существует двух отдельных элементов Н и i2 множества Y, таких, что
оператор И MERGES i2 возвращает значение истина. Отметим, что, как мы уже видели,
многие различные множества могут иметь одну и ту же свернутую форму. Кроме того,
определение свернутой формы зависит (а определение развернутой формы не зависит)
от определения функции следования для соответствующего точечного типа.
Теперь можно определить операторы UNFOLD и COALESCE. Пусть X— это множество
интервалов типа INTERVAL (РТ). Тогда оператор UNFOLD возвращает развернутую форму
множества X, а оператор COALESCE — свернутую форму множества X.
Замечание. Следует подчеркнуть, что термины развернутая форма и свернутая фор-
ма не являются стандартными. Фактически еще нет стандартных терминов для этих по-
нятий, хотя сами понятия, безусловно, обсуждаются в литературе.
Рассмотренные канонические формы играют важную роль в решениях, к которым
мы, наконец, начали приближаться, чтобы найти подходы к разрешению проблем, обсу-
ждаемых в разделе 22.3. Однако операторы UNFOLD и COALESCE— это не совсем то, что
нам нужно. Они представляют лишь этап на пути к нашей цели. Нам необходимы неко-
торые реляционные аналоги данных операторов, поэтому в следующем разделе будут да-
ны определения таких аналогов.
22.8. Реляционные операторы для обработки
интервалов
Скалярные операторы для обработки интервалов, описанные в разделе 22.6, ко-
нечно, могут использоваться и в скалярных выражениях, которые, в свою очередь,
могут применяться в соответствующих местах реляционных выражений. В языке
Tutorial D, например, к таким местам относятся в основном предложения WHERE в
874
Часть V. Дополнительные аспекты
операторах выборки и предложения ADD в операторах EXTEND и SUMMARIZE. Так, на-
пример, запрос “Определить номера поставщиков, которые могут поставить деталь с
номером 'Р2' в день 8” для базы данных, представленной на рис. 22.4, можно выра-
зить следующим образом.
( SP_DURING WHERE P# = P# ('P2') AND d08 IN DURING ) { S# }
Замечание. На практике выражение d08 было бы заменено соответствующим литера-
лом типа DAY.
В качестве другого примера рассмотрим выражение, с помощью которого
можно получить отношение, показывающее пары поставщиков, находящихся в
одном и том же городе в одно и то же время, вместе с названиями городов и соот-
ветствующими датами.
EXTEND
( ( ( ( S DURING RENAME S# AS XS#,
DURING AS XD ) { XS#, CITY, XD }
JOIN
( S_DURING RENAME S# AS YS#,
DURING AS YD ) { YS#, CITY, YD } )
WHERE XD OVERLAPS YD )
ADD ( XD INTERSECT YD ) AS DURING ) {XS#, YS#, CITY, DURING }
Пояснения. С помощью оператора JOIN выполняется поиск пар поставщиков,
которые находятся в одном и том же городе. Предложение WHERE ограничивает ре-
зультат парами, которые находились в одном и том же городе в одно и то же вре-
мя. Предложения EXTEND ... ADD используются для вычисления соответствующих
интервалов. И в конце концов с помощью операции проекции получается желае-
мый результат.
Теперь возвратимся к запросам 3.1 и 3.2 из раздела 22.3. Сначала рассмотрим за-
прос 3.1. В новой формулировке обозначим его как запрос 4.1. Для базы данных, пред-
ставленной на рис. 22.4, он будет звучать следующим образом.
Запрос 4.1. Получить пары атрибутов S#, DURING для поставщиков, которые могут
поставить некоторую деталь в некоторое время, где атрибут DURING означает пе-
риод максимальной продолжительности, в течение которого поставщик с номером
S# действительно мог поставить некоторую деталь.
Напомним, что в ранней версии этого запроса {запрос 2.1) необходимо было
использовать группирование и обобщение, а именно — обращаться к операции
SUMMARIZE. Поэтому неудивительно, что для формулировки запроса 4.1 также
нужны определенные операции группирования и обобщения. Однако в данном
случае мы будем формулировать требуемый запрос не сразу, а поэтапно. Первый
этап представлен ниже.
WITH SP-DURING { S#, DURING } AS Tl :
(Двоеточие указывает, что существует продолжение этого выражения.) На данном
этапе в исходном отношении SP_DURING просто отбрасываются номера деталей. Резуль-
тирующее отношение Т1 имеет следующий вид.
Глава 22. Хронологические базы данных
875
s# DURING
SI SI SI SI S2 S2 S2 S2 S3 S4 S4 S4 [d04,dl0] [d05,dl0] [d09,dl0] \d06,dl0] [d02,d04] \d03,d03\ [d08,dl0] [d09,dl0] [d08,dl0] [d06,d09] [d04,d08] [d05,dl0]
Отметим, что в этом отношении содержатся избыточные данные. Например, излишне
трижды говорить о том, что поставщик с номером ' S1' может что-то поставить в день 6.
Поэтому требуемое отношение, назовем его RESULT, в котором уже нет подобной избы-
точности, будет таким.
S# DURING
SI S2 S2 S3 S4 [d04,dl0] [d02,d04] [d08,dl0] [d08,dl0] [d04,dl0]
Назовем этот результат свернутой формой отношения Т1 по атрибуту DURING. Под-
черкнем, что значение атрибута DURING для данного поставщика в этой свернутой форме
необязательно должно быть представлено как явное значение атрибута DURING для данного
поставщика в отношении Т1, производной от которого является данная свернутая форма. В
нашем примере это замечание относится, в частности, к поставщику с номером ' S4'.
Может показаться, что достичь такого состояния совсем несложно, получив эту свер-
нутую форму с помощью простого выражения следующего вида.
Tl COALESCE DURING
Однако к данной цели необходимо продвигаться постепенно.
Прежде всего обратите внимание, что термин “свернутая форма” в двух предыдущих
абзацах использовался в смысле, который несколько отличается от того, который вкла-
дывался в это понятие в разделе 22.7. Оператор COALESCE, как он был определен в разде-
ле 22.7, принимает в качестве входных данных и выдает в качестве выходных данных
множество интервалов. Однако здесь рассматривается другая его версия — фактически
перегруженная (см. главу 19) версия этого оператора, когда он в качестве входных дан-
ных принимает унарное отношение и в качестве выходных данных выдает другое отно-
шение с тем же заголовком, причем оба отношения состоят из кортежей, которые содер-
жат настоящие интервалы.
Теперь подробнее рассмотрим этапы, которые позволяют перейти от отношения Т1 к
отношению RESULT.
WITH ( Tl GROUP ( DURING ) AS X ) AS T2 :
876
Часть V. Дополнительные аспекты
(Напомним, что оператор GROUP подробно рассматривался в главе 6.) Отношение Т1
представлено ниже.
S# X
S1 DURING
[d04,dl0] [d05,dl0] [d09,dl0] [d06,dl0]
S2 DURING
[d02,d04] [d03,d03] [d08,dl0] [d09,dl0]
S3 DURING
[d08,dl0]
S4 DURING
[d06,d09] [d04,d08] [d05,dl0]
Далее применим новую версию оператора COALESCE к отношениям, которые являются
значениями атрибута X (его значения имеют тип отношения).
WITH ( EXTEND Т2 COALESCE ( X ) AS Y )
{ ALL BUT X } AS T3 :
Отношение ТЗ выглядит так.
S# Y
SI DURING
[d04,dl0]
S2 DURING
[d02,d04] [d08,dl0]
S3 DURING
[d08,dl0]
S4 DURING
[d04,dl0]
Глава 22. Хронологические базы данных
877
Наконец разгруппируем это отношение (опять же, см. главу 6).
ТЗ UNGROUP Y
Это выражение служит для получения отношения, которое ранее было названо нами
RESULT. Иными словами, объединив все шаги и сделав небольшие упрощения, получим
окончательное выражение, которое в результате даст отношение RESULT.
WITH SP-DURING { S#, DURING } AS Tl,
( Tl GROUP ( DURING ) AS X ) AS T2,
( EXTEND T2 ADD COALESCE ( X ) AS Y ) { ALL BUT X } AS T3 :
T3 UNGROUP Y
Очевидно, было бы лучше, если бы можно было получить результирующее отноше-
ние RESULT из отношения Т1 с помощью единственной операции. С этой целью введем
новый оператор “реляционного свертывания” со следующим синтаксисом.
R COALESCE А
Здесь R — реляционное выражение, а А — некоторый атрибут некоторого интерваль-
ного типа, и этот атрибут принадлежит отношению, которое данное выражение обозна-
чает9. Семантика этих операторов определяется очевидными обобщениями операций
группирования, расширения, проекции и разгруппирования, с помощью которых было
получено отношение RESULT из отношения Т1.
Замечание. Стоит отметить, что свертывание отношения R по атрибуту А предусмат-
ривает его группирование по всем атрибутам, кроме атрибута А (напомним, что, как ука-
зывалось в главе 6, например выражение Tl GROUP (DURING)... может читаться как
“сгруппировать отношение Т1 по атрибуту S#”, где S# — единственный атрибут отноше-
ния Т1, не указанный в предложении GROUP).
Суммируя все сказанное выше, теперь можно предложить более приемлемую и дос-
таточно простую формулировку запроса 4.1.
SPJDURING { S#, DURING } COALESCE DURING
В целом, операция, которая обозначается этим выражением, является примером того,
что некоторыми авторами называется хронологической проекцией. А точнее, это
“хронологическая проекция” отношения SP_DURING по атрибутам S# и DURING. (Напомним,
что в первоначальной версии этого запроса (запрос 1. /) использовалась обычная проекция
отношения SP по атрибуту S#.) Заметим, что хронологическая проекция— это не совсем
проекция как таковая; скорее, это “хронологический аналог” обычной проекции.
Теперь перейдем к запросу 3.2. Исходя из содержимого базы данных, представленно-
го на рис. 22.4, этот запрос можно переформулировать следующим образом.
Запрос 4.2. Получить пары атрибутов S#, DURING для тех поставщиков, которые не
могут поставить ни одной детали в определенное время, где атрибут DURING пред-
ставляет максимально продолжительный период, в течение которого поставщик
S# фактически не мог поставить ни одной детали.
9 При желании операнд А мог бы быть расширен, чтобы можно было задать список имен
атрибутов. Аналогичное замечание относится также к оператору “реляционного развертыва-
ния” (см. ниже). Именно такая семантика приведена в упр. 22.8.
878
Часть V. Дополнительные аспекты
Напомним, что в исходной версии этого запроса (запрос 1.2) использовалась опера-
ция получения реляционной разности. Поэтому вы не ошибетесь, если предположите,
что в данном случае нам потребуется новая операция, которая будет называться “хро-
нологическая разность”. Также можно рассчитывать на то, что как “хронологическая
проекция” требует “реляционного свертывания”, так “хронологическая разность” потре-
бует “реляционного развертывания”.
Операция получения “хронологической разности”, как и обычная операция вы-
читания, включает два операнда типа отношений. Сначала рассмотрим левый опе-
ранд. Если мы развернем результат обычной проекции S_DURING {S#,DURING} по
атрибуту DURING, то получим отношение (скажем, Т1), которое будет выглядеть
следующим образом.
S# DURING
S1 [d04,d04}
S1 [d05,d05}
S1 [d06,d06]
S1 [dO7,dO7]
S1 [d08,d08]
S1 [d09,d09]
S1 [dlO.dlO]
S2 [d07,d07]
S2 [d08,d08]
S2 [d09,d09]
S2 [dlO.dlO]
S2 [d02,d02]
S2 [d03,d03]
S2 [d04,d04]
S3 [d03,d03]
При использовании данных, представленных на рис. 22.4, отношение Т1 будет содер-
жать всего 23 кортежа. (Упражнение. Проверьте достоверность этого утверждения.)
Если определить версию “унарного отношения” для оператора UNFOLD по аналогии с
версией “унарного отношения” для оператора COALESCE, то отношение Т1 можно будет
получить таким образом.
( EXTEND ( S-DURING { S#, DURING } GROUP ( DURING ) AS X )
ADD UNFOLD ( X ) AS Y { ALL BUT X } UNGROUP Y
Однако, как уже указывалось, это выражение можно упростить, если ввести оператор
“реляционного развертывания” со следующим синтаксисом.
R UNFOLD А
Теперь можно записать следующее.
WITH ( S-DURING { S#, DURING } UNFOLD DURING ) AS Tl :
Правый операнд “хронологической разности” мы представляем следующим образом.
WITH ( SP-DURING { S#, DURING } UNFOLD DURING ) AS T2 :
Глава 22. Хронологические базы данных
879
Воспользуемся обычной операцией реляционного вычитания.
WITH ( Tl MINUS Т2 ) AS ТЗ :
Отношение ТЗ выглядит так.
S# DURING
S2 [d07,d07]
S3 [d03,d03]
S3 [d04,d04\
S3 [dO5,dO5\
S3 [d06,d06\
S3 [d07,d07]
S5 \dO2,dO2]
S5 [d03,d03]
S5 [d04,d04]
S5 [d05,d05]
S5 [d06,d06]
S5 [dO7,dO7]
S5 [d08,d08]
S5 [d09,d09]
S5 [dlO,dlO]
И наконец, чтобы получить требуемый результат, свернем отношение ТЗ по атри-
буту DURING.
S# DURING
S2 [d07,d07]
S3 [d03,d07]
S5 [dO2,dlO]
Теперь сформулируем запрос 4.2 в виде одного вложенного выражения.
( ( S_DURING { S#, DURING } UNFOLD DURING )
MINUS
( SP DURING { S#, DURING } UNFOLD DURING ) )
COALESCE DURING
Как уже отмечалось, всю операцию, обозначаемую этим выражением, часто называ-
ют хронологической разностью (точнее, “хронологической разностью” между проек-
циями S_DURING и SP_DURING по атрибутам S# и DURING).
Замечание. Как и хронологическая проекция, хронологическая разность не является,
строго говоря, разностью как таковой, а представляет собой “хронологический аналог”
обычной разности.
Однако это еще не все. Выражения, подобные приведенному выше и использующие
“хронологическую разность”, настолько часто встречаются на практике, что, пожалуй,
стоит определить еще одно дополнительное сокращение10. А именно, целесообразно
представить в виде единой операции приведенную ниже последовательность действий:
Обратите внимание, что для операции временной проекции явного сокращения мы не
определяли.
880
Часть V. Дополнительные аспекты
а) развернуть оба операнда; б) получить разность; в) свернуть полученный результат.
Кроме того, подобное сокращение имеет дополнительное преимущество — появляется
возможность повышения производительности. Если используются длинные интервалы
с мелкой зернистостью, то результат развертывания отношения может быть очень
большим по сравнению с ее операндом. Если система будет реально материализовать
оба развертывания, вычислять разность и затем путем свертывания получать резуль-
тат, то такой запрос может выполняться “вечно” или же приводить к переполнению
доступного дискового пространства. Выражение хронологической разности в виде од-
ной операции может помочь оптимизатору “понять”, что именно требуется, и, воз-
можно, избежать реального выполнения каких-либо развертываний. Ниже предлагает-
ся такое дополнительное сокращение.
Rl I_MINUS R2 ON А
Здесь R1 и R2— реляционные выражения, обозначающие отношения rl и г2 одного и
того же типа, а А — атрибут некоторого интервального типа, общего для обоих отноше-
ний (префикс I , конечно же, указывает на “интервал”). Из сказанного выше должно
быть более или менее ясно, что определяемое выражение будет семантически равно-
сильно следующему выражению.
( ( Rl UNFOLD А ) MINUS ( R2 UNFOLD А ) ) COALESCE А
Дальнейшее обсуждение операторов вида “I ”, подобных оператору I_MINUS, будет
продолжено в упр. 22.2.
22.9. Ограничения, включающие интервалы
Очевидно, что пара атрибутов {S#,DURING} является потенциальным ключом для пе-
ременной-отношения S_DURING. На рис. 22.4 для данного ключа использовалось подчер-
кивание двойной линией, указывающее, что это первичный ключ. Отметим, что атрибут
{S#} сам по себе не является потенциальным ключом, поскольку после завершения дей-
ствия договора с некоторым поставщиком может быть заключен новый договор, как, на-
пример, в случае поставщика с номером 'S2' в базе данных, представленной на
рис. 22.4. Таким образом, переменную-отношение S_DURING можно определить так.
VAR S_DURING BASE RELATION
{ S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR,
DURING INTERVAL ( DATE ) }
KEY { S#, DURING } ; /* Предупреждение: этого недостаточно! */
Однако определение ключа, как оно здесь представлено, не полностью отвечает не-
обходимым требованиям, несмотря на то что оно логически корректно. А именно, со-
гласно этому определению в переменной-отношении S_DURING допустимы, например,
два таких кортежа.
S2 Jones 10 Paris [d02,d08]
S2 Jones 10 Paris [d07,dl0]
Как видите, в этих кортежах имеется определенная избыточность, поскольку данные
о наличии договора с поставщиком с номером 'S2' в дни 7 и 8 представлены дважды.
Глава 22. Хронологические базы данных
881
Данный вариант предложения KEY имеет и другой недостаток: оно не исключает воз-
можности появления в переменной-отношении S_DURING, например, таких двух кортежей.
S2 Jones 10 Paris [d02,d06]
S2 Jones 10 Paris [d07,dl0]
В этом случае уже нет избыточности данных, однако имеется излишнее многословие,
поскольку два кортежа используются для того, чтобы “сказать” то, что можно выразить в
одном кортеже.
| S2 | Jones 110 | Paris \[d02,dl0] |
Чтобы предотвратить подобные случаи избыточности и излишнего “многословия”,
для переменной-отношения, очевидно, необходимо предоставить соответствующее огра-
ничение (назовем его ограничением СГ), которое может быть сформулировано так.
Если два отдельных кортежа переменной-отношения S_DURING идентичны, за ис-
ключением лишь значений их атрибутов DURING, равных И и 12, то результат опера-
ции il MERGES i2 должен иметь значение ложь.
(Напомним, что операция проверки слияния интервалов MERGES представляет собой
логическую конъюнкцию (0R) операций перекрытия интервалов OVERLAPS и проверки
смежности MEETS. Поэтому операция MERGES может возвращать результат ложь только в
том случае, если он будет получен и для обеих операций OVERLAPS и MEETS. Ограничение
перекрытия интервалов с помощью операции OVERLAPS служит для предотвращения из-
быточности, а ограничение смежности интервалов с помощью операции MEETS использу-
ется, чтобы предотвратить излишнее “многословие”.) Должно быть ясно, что существует
очень простой способ реализации ограничения С1, а именно— посредством постоянной
поддержки переменной-отношения S_DURING в свернутом состоянии по всем значениям
времени атрибута DURING. Поэтому добавим к определению этой переменной-отношения
предложение COALESCED, которое в общем случае является необязательным.
VAR S DURING BASE RELATION
{ S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR,
DURING INTERVAL ( DATE ) }
KEY { S#, DURING } ; /* Этого по-прежнему недостаточно! */
COALESCED DURING ;
Уточнение COALESCED DURING в данном случае означает, что переменная-отношение
S DURING должна по всем значениям времени быть идентичной результату выражения
S DURING COALESCED DURING (подразумевается, что теперь свертывание переменной-
отношения S_DURING по атрибуту DURING в любых выражениях никогда не будет оказы-
вать на нее какого-либо влияния). Таким образом, в этом определении проблемы избы-
точности и “многословия” по-прежнему остались нерешенными11. *
Ч Отметим, что можно добавить аргумент с целью обеспечения соответствующего специ-
ального синтаксиса для решения проблемы избыточности, но не проблемы "многословия”.
882
Часть V. Дополнительные аспекты
Замечание. Пока подразумевается, что любая попытка обновить переменную-
отношение S_DURING так, чтобы она оказалась не полностью свернутой по атрибуту
DURING, отвергается. Обсуждение этого вопроса будет продолжено в разделе 22.10.
К сожалению, предложения KEY и COALESCED все еще не полностью отвечают необхо-
димым требованиям. Например, по-прежнему возможно появление таких двух кортежей.
S2 Jones 10 Paris [d02,d08]
S2 Jones 20 Paris [d07,dl0\
В этом случае поставщик с номером 'S2' в дни 7 и 8 имеет статус 10 и 20 (ясно,
что наличие таких кортежей недопустимо). Другими словами, здесь мы имеем дело с
противоречием.
Понятно, что для устранения таких противоречий необходимо обеспечить для пере-
менной-отношения соответствующее ограничение. Назовем его ограничением С2. Оно
может быть сформулировано следующим образом.
Если два отдельных кортежа переменной-отношения S_DURING с одним и тем же
значением атрибута S# имеют значения атрибута DURING, равные И и i2 соответст-
венно, и выражение il OVERLAPS i2 истинно, то эти кортежи должны быть иден-
тичны, за исключением, может быть, значений их атрибута DURING.
Необходимо подчеркнуть, что ограничение С2 не реализуется поддержкой перемен-
ной-отношения S_DURING в свернутом состоянии по атрибуту DURING (и, очевидно, не
реализуется за счет того, что {S#,DURING} является потенциальным ключом). Но если
предположить, что переменная-отношение S_DURING всегда поддерживается разверну-
той по атрибуту DURING, то справедливы следующие замечания.
Единственный потенциальный ключ для развернутой формы переменной-
отношения S_DURING UNFOLD DURING — это все та же комбинация атрибутов
{S# ,DURING}, поскольку в любое заданное время любой заданный поставщик, с
которым в данное время заключен договор, имеет только одно имя, один статус и
находится в одном городе.
Следовательно, никакие два отдельных кортежа не могли бы иметь одно и то же
значение атрибута S# и “перекрывающиеся” значения атрибута DURING, поскольку
в форме S_DURING UNFOLD DURING все значения атрибута DURING являются еди-
ничными интервалами, и два кортежа с одним и тем же значением атрибута S# и
“перекрывающимися” значениями атрибута DURING являлись бы дубликатами
(фактически они были бы одним и тем же кортежем).
Поэтому, если обеспечено такое ограничение, что комбинация атрибутов {S#,DURING}
является потенциальным ключом для формы S_DURING UNFOLD DURING, ограничение С2
обеспечивается “автоматически”. Определим новое предложение I_KEY, которое может ис-
пользоваться вместо обычного предложения KEY в переменной-отношении S_DURING.
VAR S_DURING BASE RELATION
{ S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR,
DURING INTERVAL ( DATE ) }
Глава 22. Хронологические базы данных
883
I_KEY { S#, DURING UNFOLDED}
COALESCED DURING ;
Предложение I KEY здесь означает именно то, что комбинация атрибутов
{S#,DURING} является потенциальным ключом для формы S_DURING UNFOLD DURING12.
Таким образом, этого специального синтаксиса вполне достаточно для устранения ука-
занного противоречия.
Необходимо заметить, что если комбинация атрибутов {St,DURING} является по-
тенциальным ключом для формы S_DURING UNFOLD DURING, то она, безусловно, явля-
ется потенциальным ключом и для переменной-отношения S_DURING. Это позволяет
отказаться от исходного предложения KEY для переменной-отношения S_DURING в
пользу предложения I_KEY. Также отметим, что ключ {S#,DURING} может считаться
хронологическим потенциальным ключом в смысле, который вкладывался в это
понятие в разделе 22.3. Кроме того, как мы уже убедились, этот хронологический по-
тенциальный ключ — действительно настоящий потенциальный ключ для содержащей
его переменной-отношения, в отличие от “хронологических потенциальных ключей”,
которые рассматривались в разделе 22.3.
Естественно предположить, что если поддерживается синтаксис предложения I_KEY
для потенциальных ключей, то мы вправе ожидать, что имеется соответствующая под-
держка и для внешних ключей. Например, определение переменной-отношения
SP_DURING может включать приведенное ниже уточнение.
FOREIGN I_KEY { S#, DURING UNFOLDED } REFERENCES S_DURING ...
Его смысл заключается в следующем: если в переменной-отношении SP_DURING име-
ются сведения о том, что поставщик с номером ' Sx' может поставлять некоторые детали
в течение интервала 1, то в переменной-отношении S_DURING также должно быть ото-
бражено, что с поставщиком с номером 'Sx' заключен договор, действительный в тече-
ние всего этого интервала i. Если данное ограничение удовлетворяется, комбинация ат-
рибутов {S#,DURING} в переменной-отношении SP_DURING может считаться хронологи-
ческим внешним ключом в смысле, оговоренном в разделе 22.3. (Однако это еще не
настоящий внешний ключ в классическом смысле.)
Следует обратить внимание на одну особенность, касающуюся переменной-
отношения S_DURING. Предположим, что она на самом деле постоянно поддерживается в
свернутом состоянии по атрибуту DURING. Предположим также, что время от времени мы
запускаем процедуру, пересчитывающую статус поставщиков, с которыми в текущее
время заключен договор. Конечно, процедура должна также записывать в переменную-
отношение S_DURING предыдущие значения статуса. Иногда в результате пересчета зна-
чения статуса будут оставаться без изменений. В таких случаях процедура будет маши-
нально пытаться вставить, запись предыдущего статуса в переменную-отношение
S_DURING, в результате чего будет нарушено требование свернутого состояния, выражае-
12 Некоторые авторы определяют семантику предложения I KEY таким образом, что оно ис-
пользуется и для решения проблемы избыточности. Мы же считаем такой подход несколько нелогич-
ным и здесь не используем (во всяком случае в этом нет необходимости, поскольку ясно, что для того,
чтобы справиться с проблемой избыточности, вполне достаточно и предложения COALESCED).
884
Часть V. Дополнительные аспекты
мого предложением COALESCED. Чтобы таких ситуаций не возникало, в процедуре долж-
ны быть предусмотрены проверка изменения статуса и выполнение соответствующей
операции обновления вместо операции вставки, которая используется в том случае, если
статус изменился (см. упр. 22.3). В качестве альтернативного подхода можно было бы не
поддерживать переменную-отношение S_DURING в свернутом состоянии по атрибуту
DURING. Такое решение, возможно, не подходит для данного конкретного случая, но мо-
жет быть подходящим для других случаев.
22.10. Операторы обновления, включающие
интервалы
В этом разделе будет рассмотрено несколько проблем, которые возникают при ис-
пользовании обычных операторов изменения INSERT, UPDATE и DELETE для хронологиче-
ской переменной-отношения. И вновь в качестве примера будет применяться перемен-
ная-отношение S_DURING. Предположим, что определение переменной-отношения вклю-
чает уточнения I_KEY и COALESCED, предложенные в предыдущем разделе, а также что
текущее значение переменной-отношения S_DURING именно такое, как на рис. 22.4. Те-
перь рассмотрим следующие сценарии.
Вставка. Предположим, что с поставщиком с номером 'S2' был заключен допол-
нительный договор на период с дня 5 по день 6 (в течение этого времени постав-
щик, как и прежде, имел имя 'Jones', статус, равный 10, и находился в городе
'Paris'). Однако мы не можем просто вставить кортеж, не нарушив ограничение
COALESCED, причем дважды. На самом деле для поставщика с номером 'S2' необ-
ходимо удалить один из существующих кортежей и обновить другой, чтобы уста-
новить значение атрибута DURING равным [<502,dlO].
Обновление. Предположим, что статус поставщика с номером 'S2' был времен-
но увеличен до 20 только на день 9. Довольно сложно выполнить такое измене-
ние, хотя его формулировка подобна той, которая дается при простом обновле-
нии. По существу, необходимо разбить кортеж с интервалом [d07,dl0] для по-
ставщика с номером 'S2' на три кортежа со значениями атрибута DURING, рав-
ными [d07,d08], [d09td09] и [dl0tdl0], остальные значения оставить прежни-
ми и в кортеже со значением атрибута DURING, равным [d09td09], заменить зна-
чение атрибута STATUS на 20.
Удаление. Предположим, что договор с поставщиком с номером 'S3' был отме-
нен в день 6, а затем возобновлен с дня 9. В этом случае изменение также дале-
ко не тривиальное. Требуется разбить единственный кортеж для поставщика с
номером 'S3' на два кортежа со значениями атрибута DURING, равными
[d03,d05] и [d09,dlO].
Обратите внимание, что решения трех указанных заданий, изложенные лишь в общих
чертах, являются специфическими для текущего значения переменной-отношения
S_DURING (и необходимы только при конкретных изменениях). Рассмотрим, например,
проблему, связанную со вставкой. В общем случае кортеж может просто вставляться в
переменную-отношение “как он есть”, или же может потребоваться, чтобы он был под-
Глава 22. Хронологические базы данных
885
вергнут свертыванию с “предыдущим” кортежем, со “следующим” кортежем или с ними
обоими сразу, как это было в нашем примере. Аналогично и в случае операций обновле-
ния или удаления может потребоваться “разбиение” существующих кортежей.
Очевидно, что пользователям было бы очень сложно обходиться лишь обычными
операторами INSERT, UPDATE и DELETE. Необходимы определенные расширения этих опе-
раторов. Рассмотрим некоторые возможности таких расширений.
Операция INSERT. Практически проблема, связанная с операцией вставки, может
быть решена за счет расширения семантики предложения COALESCED в определе-
нии переменной-отношения. А именно, можно разрешить выполнение операции
INSERT обычным способом и потребовать, чтобы системой осуществлялись необ-
ходимые свертывания с кортежами, добавляемыми следующими операциями
INSERT. Другими словами, уточнение COALESCED теперь будет не только опреде-
лять ограничение, но и указывать явные компенсирующие действия (аналогично
ссылочным действиям при определении внешнего ключа).
Однако, к нашему сожалению, только расширения семантики предложения
COALESCED указанным способом будет недостаточно для решения проблем опера-
ций UPDATE и DELETE (почему?).
Операция UPDATE. Проблему, связанную с операцией обновления, можно решить
за счет расширения оператора UPDATE так, как показано в следующем примере13.
UPDATE S_DURING
WHERE S# = S# ('S2')
DURING INTERVAL ( [d09,d09] )
STATUS := 20 ;
Здесь в третьей строке (синтаксис которой, по сути, имеет вид <нмя атрибута>
интервальное выраженне>) указан атрибут интервала DURING, к которому приме-
няется уточнение COALESCED, и соответствующее значение интервала [d09,d09]. В
целом, подобная операция может интерпретировать так:
а) прежде всего определяются кортежи поставщика S2;
б) затем из найденных кортежей выбираются те, в которых значение атрибута
DURING включает интервал (естественно, должен существовать по
крайней мере один такой кортеж);
в) если не обнаружено ни одного требуемого кортежа, то обновление не выполня-
ется; в противном случае кортежи разбиваются, как это требуется, и выполня-
ются необходимые обновления.
Операция DELETE. Аналогичным образом проблему удаления можно решить за
счет расширения оператора DELETE, как, например, показано ниже.
DELETE S_DURING
WHERE S# = S# ('S3')
DURING INTERVAL ( [d06,d08] ) ;
13 Этот синтаксис подобен предлагаемому в [22.3], но не идентичен ему.
886
Часть V. Дополнительные аспекты
22.11. Проектирование базы данных
До сих пор переменные-отношения S_DURING и SP_DURING использовались для иллю-
страции типов интервалов и определения специальных операторов для обработки данных
интервалов, и нам этого было достаточно. Переменные-отношения первоначально были
“спроектированы” посредством простого добавления атрибутов интервалов к их эквива-
лентам в базе данных типа моментального снимка. В настоящем разделе мы попытаемся
выяснить, насколько хорош такой подход к проектированию. Здесь будет предложена
дополнительная декомпозиция определенных хронологических переменных-отношений
(под “дополнительной декомпозицией” здесь понимается декомпозиция, которая не пре-
дусматривается требованиями классической нормализации). Фактически в зависимости
от обстоятельств предлагается использовать два вида декомпозиции — горизонтальную
и вертикальную.
Горизонтальная декомпозиция
В нашем примере подразумевается, и вполне обоснованно, что в базе данных содер-
жатся исторические данные, включающие некоторое представление сведений о времени.
Также предполагается, что представление этих сведений о времени записывалось в виде
некоторых конкретных дат (например, день 10). Однако последнее предположение никак
нельзя признать обоснованным. В частности, при таком подходе подразумевается, что с
течением времени база данных некоторым образом обновляется. В нашем примере пред-
полагалось, что каждое вхождение значения dl 0 заменяется на dl 1 ровно в полночь дня
10. Если бы в примере использовались интервалы более мелкой зернистости, то могли
бы потребоваться и более частые обновления, скажем, каждую миллисекунду!
Одни авторы предлагают использовать специальные маркеры (будем называть их
маркерами настоящего момента, now), которые допустимы везде, где допустимо точеч-
ное значение. Согласно этому подходу, например, интервал [d04,dl0], показанный на
рис. 22.4 как значение атрибута DURING для поставщика с номером 'S1' в переменной-
отношении S_DURING, должен быть представлен как интервал [d04,ncw]. Реальное зна-
чение такого интервала, конечно, зависит от того, когда именно оно рассматривается;
скажем, вдень 14 это был бы интервал [d04,dl4].
Другие авторы считают, что введение маркера настоящего момента— опрометчи-
вое отступление от концепций, на которых базируются реляционные системы. Обратите
внимание, что маркер настоящего момента в действительности представляет собой неко-
торую переменную. Следовательно, предлагается странное — мы бы сказали, логически
неоправданное — понятие значений, содержащих переменные. Вот несколько вопросов,
возникающих при введении подобного понятия, над которыми полезно поразмышлять.
Что произойдет с интервалом [ now, dl 4 ] в полночь дня 14?
Что собой представляет значение END( [d04,now]) на день 14? Это dl4 или now?
Мы считаем, что дать разумный ответ на такого рода вопросы сложно. Поэтому, по наше-
му мнению, необходимо найти подход, который не противоречит общепринятым понятиям.
Иногда “атрибут DURING” будет использоваться для записи данных относительно бу-
дущего и относительно прошлого (или вместо него). Например, пусть требуется записать
дату истечения срока договора с поставщиком или дату его возобновления в будущем. В
Глава 22. Хронологические базы данных
887
таком случае можно было бы использовать вариант отношения S_DURING, представлен-
ный на рис. 22.4. Однако этот подход, очевидно, применим не всегда (в частности, если
атрибут DURING интерпретируется как время транзакции (см. раздел 22.2), поскольку
время транзакции не может быть будущим).
Основная проблема заключается в том, что имеется существенное различие между
историческими данными и данными относительно текущего состояния дел. Для истори-
ческих данных известно начальное и конечное время, а для текущих данных обычно из-
вестно только начальное время. Отсюда неизбежно следует вывод, что необходимы две
различные переменные-отношения: одна — для отражения текущего состояния дел, дру-
гая — для исторических данных (в конце концов, они соответствуют двум, определенно,
разным предикатам). В случае отношения поставщиков “текущая” переменная-
отношение — это S_SINCE, показанная на рис. 22.2, а “историческая” — S_DURING, пред-
ставленнгя на рис. 22.4, за исключением кортежей, в значениях атрибута DURING которых
конечное время интервала не равно dl 0 (соответствующие данные записываются в пере-
менную-отношение S_SINCE).
Этим примером иллюстрируется горизонтальная декомпозиция: переменная-
отношение с точечным значением атрибута “начиная с” для текущего состояния и пере-
менная-отношение с интервальным значением атрибута “на период” для исторических
данных. Отметим, кстати, что для пополнения данными исторической переменной-
отношения могут использоваться триггерные процедуры. Например, удаление кортежа
из переменной-отношения S_SINCE может “автоматически” запускать вставку соответст-
вующего кортежа в переменную-отношение S_DURING.
Для объединения исторических и текущих данных в одном отношении может исполь-
зоваться реляционный оператор UNION, как, например, показано ниже.
S_DURING UNION ( EXTEND S_SINCE
ADD INTERVAL [ SINCE, TODAY() ]
AS DURING ) { ALL BUT SINCE }
Недостатки горизонтальной декомпозиции проявляются, если значения атрибута
DURING интерпретируются как допу ст имое время, а не как время транзакции. В этом слу-
чае исторические данные обновляемы! Здесь могли бы использоваться операторы обнов-
ления, описанные в разделе 22.10, но может случиться так, что исправления должны вно-
ситься в обе переменные-отношения. Предположим, например, что обнаружена ошибка в
последнем изменении статуса некоторого поставщика. Тогда может потребоваться не
только удалить кортеж из переменной-отношения S_DURING, но и обновить соответст-
вующий кортеж в переменной-отношении S SINCE. Или другой пример, когда последнее
изменение статуса было корректным, но был указан ошибочный день; и в этом случае
необходимо внести обновления в обе переменные-отношения.
Если переменная-отношение SP_DURING подобным образом может быть подвергнута
декомпозиции на переменные-отношения SPJ5INCE и SP_DURING, то дополнительно необ-
ходимо пересмотреть ограничение внешнего ключа. Для переменной-отношения
SP_DURING, как мы уже убедились в разделе 22.9, определение может включать следую-
щее предложение.
FOREIGN I_KEY { S#, DURING UNFOLDED } REFERENCES S_DURING ...
888
Часть V. Дополнительные аспекты
Как указывалось в разделе 22.9, это уточнение служит для того, чтобы в случае, когда
согласно данным переменной-отношения SP_DURING поставщик с номером 'Sx' может
поставлять некоторую деталь в течение времени 1, в переменной-отношении S_DURING
отражалось, что с поставщиком с номером ' Sx' заключен договор, действительный и на
время i. Там же говорилось, что ключ {S#,DURING} в переменной-отношении SP_DURING
может рассматриваться как хронологический внешний ключ.
Однако для переменной-отношения SP_SINCE соответствующий внешний ключ яв-
ляется лишь “полухронологическим”. Поэтому мы по-прежнему вынуждены использо-
вать громоздкие выражения для формулирования ограничений, как было показано в
разделе 22.3.
CONSTRAINT AUG SP_TO_S_FK
IS EMPTY ( 7 ( S_SINCE RENAME SINCE AS SS ) JOIN
( SP_SINCE RENAME SINCE AS SPS ) )
WHERE SPS < SS ) ;
Таким образом, горизонтальная декомпозиция неизбежно приводит к определен-
ным проблемам — к проблеме громоздких ограничений и к необходимости одно-
временного обновления переменных-отношений с текущими и историческими дан-
ными. На время написания этой книги не существовало каких-либо конкретных
предложений относительно введения сокращений для решения указанных проблем.
Возможно, необходимы дальнейшие исследования. Отметим, что эти проблемы не
возникают, если разрешить переменной-отношению типа “на период” включать ин-
формацию о будущем, прошлом и настоящем (поскольку переменная-отношение ти-
па “с момента” тогда не нужна). Однако при таком подходе будущее считается ко-
нечным промежутком времени. Указанные проблемы также не возникают при ис-
пользовании подхода, предлагаемого в [22.4].
Вертикальная декомпозиция
Еще до того, как были проведены исследования особенностей хронологических дан-
ных (и до того, как для их обработки были разработаны операторы языка SQL), некото-
рые авторы настаивали на необходимости максимальной декомпозиции переменных-
отношений, “насколько она возможна”, вместо декомпозиции, предусматриваемой пра-
вилами классической нормализации. Некоторые из этих авторов, к сожалению, навреди-
ли себе, предлагая проекты баз данных, содержащих лишь бинарные переменные-
отношения. Одно из критических замечаний относительно этой идеи состояло в том, что
иногда необходимы и унарные переменные-отношения. Суть другого замечания заклю-
чалась в следующем: некоторые переменные-отношения степени 3 и более на самом деле
невозможно подвергнуть декомпозиции (например, переменная-отношение SPJ из базы
данных поставщиков, деталей и проектов).
С другой стороны, наша обычная (не хронологическая) переменная-отношение S,
безусловно, может быть подвергнута дополнительной декомпозиции. Если заданы ис-
тинные высказывания “Имя поставщика с номером 'S1' — 'Smith'”, “Статус постав-
щика с номером 'S1'— 20”, “Поставщик с номером 'S1' находится в городе
'London'”, то можно с уверенностью сделать вывод об истинности высказывания, ко-
торое следует из значения первого кортежа для поставщика с номером 'S1' в базе
Глава 22. Хронологические базы данных
889
данных, представленной на рис. 22.1. Значит, переменную-отношение S можно разбить
на три бинарные переменные-отношения, каждая из которых будет иметь в качестве
первичного ключа атрибут S#.
Идея декомпозиции до максимальных пределов мотивируется желанием получить
максимально простые элементы. Возможно, для декомпозиции переменной-отношения S
это не очень веская причина, однако ее значение существенно возрастает в случае пере-
менной-отношения S_DURING. Имя поставщика, его статус и город нахождения изменя-
ются во времени независимо друг от друга. Более того, они могут изменяться с разной
частотой. Например, вряд ли имя поставщика меняется со временем, тогда как место его
нахождения иногда изменяется, а его статус может меняться достаточно часто. Но по-
вторение имени и места нахождения поставщика при каждом изменении его статуса мо-
жет представлять некоторые неудобства. Кроме того, исторические сведения об измене-
нии имени, статуса и места нахождения поставщика, возможно, более интересны и про-
сты, чем история сочетания “имя — статус — город”. Поэтому предлагается выполнить
декомпозицию переменной-отношения S_DURING на три исторические переменные-
отношения, которые могут быть описаны приблизительно так.
S__NAME_DURING { S#, SNAME, DURING }
S__STATUS_DURING { S#, STATUS, DURING }
S_CITY_DURING { S#, CITY, DURING }
К каждому из определений этих трех переменных-отношений можно было бы доба-
вить уточнения I_KEY {S#, DURING UNFOLDED} и COALESCED DURING.
Замечание. Можно было бы также добавить “основную” переменнущ-отношение по-
ставщиков.
S#_DURING { S#, DURING }
Эта переменная-отношение могла бы показывать, с какими поставщиками подписыва-
лись договора и когда это было. К определению также можно было бы добавить уточнения
I_KEY {S#, DURING UNFOLDED} и COALESCED DURING. Кроме того, ключ {S#,DURING} мог бы
служить хронологическим внешним ключом в каждой из переменных-отношений
S_NAME_DURING, S_STATUS_DURING и S_CITY_DURING (а также SP_DURING), соответствующим
хронологическому потенциальному ключу в переменной-отношении SJDURING.
Здесь следует отметить еще одну особенность. Чтобы получить историю изменения
статуса поставщика для переменной-отношения S_DURING, как она изначально была оп-
ределена, необходимо использовать не совсем тривиальное выражение.
S_DURING { S#, STATUS, DURING } COALESCED DURING
В то же время, чтобы получить значительно менее интересную комбинированную ис-
торию, требуется лишь ссылка на эту переменную-отношение. Поэтому в некотором
смысле предлагаемая декомпозиция “выравнивает игровое поле” для запросов, или, ско-
рее, упрощает выражение более интересных запросов, и усложняет выражение менее ин-
тересных запросов.
Однако необходимость декомпозиции переменной-отношения S_SINCE не так уж и
непреодолима. В частности, отметим, что, поскольку для пополнения трех исторических
переменных-отношений могут использоваться триггерные процедуры (например, удале-
890
Часть V. Дополнительные аспекты
ние кортежа из переменной-отношения SJ5INCE может “автоматически” активизировать
обновление переменных-отношений S#_DURING, S_NAME_DURING, S_STATUS_DURING и
S_CITY_DURING), нет необходимости в декомпозиции переменной-отношения SJSINCE,
чтобы достичь тех же результатов.
22.12. Резюме
В начале главы был отмечен все возрастающий интерес к базам данных, содержащим
не только текущие, но и исторические сведения. Также было показано, что представле-
ние исторических данных с использованием лишь временных отметок (timestamp) при-
водит к серьезным трудностям и, в частности, очень усложняет задание некоторых огра-
ничений и формулировку определенных запросов. В качестве лучшего подхода рассмат-
ривалось использование скалярных (“инкапсулированных”) интервалов: обсуждался
генератор типа INTERVAL вместе с несколькими новыми операторами, необходимыми
для обработки интервальных данных, хотя все эти операторы, напомним, представляют
собой просто некоторые сокращения. Интервалы и связанные с ними операторы могут
быть полезны не только для хронологических данных как таковых; к сожалению, наш
пример основывался лишь на типе INTERVAL (DATE). В настоящей главе также приводи-
лись примеры хронологических отношений и рассматривались хронологические пе-
ременные-отношения с атрибутами этого специфического типа.
Интервальный тип должен определяться через основной точечный тип, а связанная с
ним точность должна указываться (при необходимости) именно для такого точечного
типа. Кроме того, для данного точечного типа и заданной точности должна быть опреде-
лена функция следования.
Рассмотренные здесь операторы включали операторы для обработки собственно ин-
тервалов, операторы для обработки множеств интервалов и операторы для обработки
хронологических отношений. К операторам для обработки интервалов относятся START и
END, а также операторы Аллена. К операторам для обработки множеств интервалов от-
носятся UNFOLD и COALESCE. К операторам для обработки хронологических отношений
относятся реляционные версии операторов UNFOLD и COALESCE. Также здесь обсужда-
лись некоторые специализированные операторы обновления и некоторые специализи-
рованные ограничения целостности для хронологических переменных-отношений
(“хронологические ключи”). Было показано, что большинство из этих новых операторов
могли бы фактически рассматриваться как хронологические аналоги соответствующих
обычных конструкций.
Далее были рассмотрены две важные канонические формы для множеств интерва-
лов одного и того же типа — развернутая форма и свернутая форма. Множество ин-
тервалов типа INTERVAL(РТ) представлено в развернутой форме, если каждый интер-
вал в множестве является единичным интервалом, т.е. интервалом, содержащим ровно
одну точку, vrq точка — это значение основного точечного типа РТ. Множество ин-
тервалов типа INTERVAL(РГ) представлено в свернутой форме, если никакие два от-
дельных интервала в этом множестве не перекрываются и не являются смежными.
Обе канонические формы обладают преимуществом освобождения от определенных
видов избыточности. Свернутая форма максимально краткая и имеет психологические
преимущества, а развернутой формой легче оперировать (избавляют от необходимости
Глава 22. Хронологические базы данных
891
иметь специальные ограничения и операторы обновления, рассмотренные в разде-
лах 22.9 и 22.10). Затем было показано, как концепции этих канонических форм могут
быть расширены до отношений с интервальными атрибутами, что приводит к новым
важным реляционным операторам UNFOLD и COALESCE. Эти операторы использовались
для определения хронологических аналогов обычных реляционных операторов проек-
ции и вычисления разности.
И наконец было уделено внимание вопросам проектирования базы данных, связан-
ным с горизонтальной и вертикальной декомпозициями некоторых хронологических
переменных-отношений.
Упражнения
22.1.
а) В языке SQL тип данных VARCHAR(3) включает все строки длиной до трех сим-
волов, входящих в набор символов по умолчанию, под которым подразумевает-
ся набор символов кода ASCII. Как вы полагаете, можно ли считать тип
INTERVAL(VARCHAR(3)) приемлемым интервальным типом?
б) Если ваш ответ на предыдущий вопрос — “Да”, то выразите закрыто-открытый интер-
вал [' р' f ' q') этого типа с помощью закрыто-закрытого обозначения интервала.
22.2. В разделе 22.8 был определен оператор получения хронологической разности
I_MINUS. Операторы хронологического объединения (I_UNION) и хронологического
пересечения (I_INTERSECT) могут быть определены аналогично. Дайте соответст-
вующие определения этим операторам.
22.3. Предположим, что переменная-отношение S_DURING имеет ограничение, требую-
щее, чтобы она была свернута по атрибуту DURING, и предположим, что необходи-
мо обновить эту переменную-отношение с целью отразить тот факт, что поставщи-
ку с номером 'S1' присвоен статус 20 на период с дня 11 по день 15. Приведите
оператор, с помощью которого можно получить желаемый результат. При этом
нельзя считать, что операторы обновления расширены так, как было предложено в
разделе 22.10. Однако можно считать, что переменная-отношение S_DURING содер-
жит данные о поставщике с номером 'S1' на день 10, а данные после этого дня для
него отсутствуют. Не делайте никаких предположений относительно того, каким
может быть существующий статус поставщика с номером ' S1' на день 10.
22.4. В этой главе было показано, как определенные операторы, которые применяются
к интервальным атрибутам вообще, в частности могут оказаться очень полезны-
ми и для хронологических интервалов. Предложите какие-либо иные возможные
применения этих операторов для обработки интервалов, которые не являются
хронологическими.
22.5. Приведите реальные примеры отношений, у которых имеется более одного интер-
вального атрибута (хронологического или иного типа).
22.6. Еще раз обратимся к переменной-отношению S_DURING. В любое заданное время,
если имеются какие-либо поставщики, с которыми на этот период был заключен
договор, имеется и некоторый статус smax, такой, что ни один из поставщиков в
этот период не имел статус выше статуса smax. С помощью описанных в этой главе
892
Часть V. Дополнительные аспекты
операторов получите свернутое отношение, в котором каждое значение статуса,
когда-либо являвшееся значением smax, будет связано с интервалом времени, когда
оно имело значение smax.
22.7. Дано отношение HW с атрибутами NAME, HEIGHT и WEIGHT, представляющими имя,
рост и вес некоторого человека. Напишите запрос, который для каждого записан-
ного значения веса покажет все диапазоны значений роста, таких, что для каждого
значения роста в этом диапазоне существует по крайней мере один человек с дан-
ным ростом и весом.
22.8. Рассмотрим отношение R с двумя различными интервальными атрибутами II и 12.
Докажите или опровергните следующие утверждения.
a) (R UNFOLD II) UNFOLD 12 = (R UNFOLD 12) UNFOLD II
6) (R COALESCE II) COALESCE 12 = (R COALESCE 12) COALESCE II
22.9. Можете ли вы привести пример переменной-отношения с интервальным атрибу-
том, которую было бы нежелательно поддерживать в свернутой форме?
22.10. Исследуйте возможности расширения понятия “хронологического внешнего клю-
ча” для включения ссылочных действий, таких как каскадное удаление.
Список литературы
Вместо того чтобы приводить здесь список работ, который может оказаться слишком
объемным, мы просто обратим ваше внимание на то, что в [22.2] содержится обширный
список литературы по теме данной главы.
22.1. Allen J.F. Maintaining Knowledge about Temporal Intervals И CACM. — November,
1983. — 16, № 11.
22.2. Etzion O., Jajodia S., Sripada S. (eds.) Temporal Databases: Reaserch and Practice. —
New York, N.Y.: Springer Verlag, 1998.
Антология, представляющая состояние исследований данной темы на 1997 год, а
также превосходная первая работа для дальнейшего изучения. Четвертая часть,
Part 4: General Reference, включает обширную библиографию и версию словаря
терминов, The Consensus Glossary of Temporal Database Concepts, по состоянию на
февраль 1998 года. Вторая часть, Part 2: Temporal Query Languages, включает ста-
тью “Valid Time and Transaction Time Proposals: Language Design Aspects”, в кото-
рой автор оригинального текста настоящей главы Хью Дарвен (Hugh Darwen) при-
водит доводы против подхода, принимающего язык TSQL2, и настаивает на том,
что в определениях языка TSQL2 [22.4] имеются существенные недостатки. Также
во вторую часть входит статья Дэвида Томэна (David Toman) “Point-Based
Temporal Extensions of SQL and Their Efficient Implementation”, в которой предлага-
ется расширение языка SQL, основанное на точках, а не интервалах. Эта идея под-
нимает некоторые интересные вопросы, касающиеся реализации. Ответы на них
могли быть применимы и для подхода, основанного на интервалах, поскольку
“единичные интервалы”, которые получаются в развернутой форме (UNFOLD),
“фактически” представляют точки (на самом деле они действительно являются
точками в языке 1XSQL; см. аннотацию к [22.3]).
Глава 22. Хронологические базы данных
893
22.3. Lorentzos N.A., Mitsopoulos Y.G. SQL Extension for Interval Data П IEEE Transactions
on Knowledge and Data Engineering. — May/June, 1997. — 9, № 3.
Многие идеи, которые обсуждались в настоящей главе, основаны на результатах
исследований, описанных в данной статье. Как и предыдущая работа, эта статья
содержит множество полезных ссылок.
Прежде чем представить собственное расширение языка SQL, авторы опреде-
лили реляционную алгебру, дополненную интервалами (Interval-Extended
Relational Algebra). Предлагаемое расширение языка SQL называется IXSQL
(иногда произносят, как “девять SQL”) и не предназначено исключительно для
хронологических интервалов. Поскольку ключевые слова INTERVAL и COALESCE
уже используются в языке SQL для других целей, авторы предлагают вместо
них ключевые слова PERIOD (даже для не хронологических интервалов) и
NORMALISE (обратите внимание на написание). Как указывалось в аннотации к
[22.2], оператор UNFOLD в языке IXSQL отличается от нашего тем, что в ре-
зультате его выполнения получаются точки, а не единичные интервалы. По-
этому авторы предлагают обратный оператор FOLD, который преобразует точки
в интервалы, а затем свертывает их. Эти операторы предлагаются не как от-
дельные операторы, а как дополнительные предложения обычной конструкции
SELECT-FROM-WHERE. Интересно, что вновь введенное предложение NORMALISE
ON не только записывается последним, но и выполняется последним (что явля-
ется отклонением от правил языка SQL; см. приложение Б). Иными словами,
вывод предложения SELECT является вводом для предложения NORMALISE ON
(по веским причинам).
22.4. Snodgrass R.T. The Temporal Query Language TASQL2. — Dortrecht, Netherlands:
Kluwer Academic Pub., 1995.
Язык TSQL2 — это множество предложенных расширений для языка SQL.
Комитет языка TSQL2 в значительной степени отверг общий подход к исполь-
зованию скалярных и реляционных операторов для интервалов в пользу того,
что больше подходит в особых случаях. Вместо простой поддержки генератора
интервального типа и связанных с ним операторов были предложены различ-
ные специального вида таблицы: таблицы снимков, таблицы допустимого
времени состояния, таблицы допустимого времени события, таблицы време-
ни транзакций, таблицы двухронологического состояния и таблицы двухроно-
логических событий.
Таблица снимков — это таблица в обычном стиле языка SQL, возможно, вклю-
чающая столбцы данных типа PERIOD (как и в языке IXSQL [22.3], это ключевое
слово используется вместо ключевого слова INTERVAL, которое уже употребля-
ется в языке SQL для других целей).
Все остальные виды таблиц имеют хронологическую поддержку. Хронологиче-
ская поддержка означает существование для каждой строки одного или двух
хронологических элементов. Хронологический элемент— это множество вре-
менных отметок, причем каждая временная отметка представляет собой или
значение типа PERIOD, или значение некоторого типа даты-времени. (Обратите
внимание, что термин “временная отметка” здесь используется не в его при-
вычном, принятом в языке SQL/92 смысле.)
894
Часть V. Дополнительные аспекты
Хронологические элементы, содержащие значения типа PERIOD, определяются как свер-
нутые14. Хронологические элементы не выступают в роли обычных столбцов; вместо это-
го доступ к ним осуществляется с помощью операторов специального назначения.
Ниже приведен краткий обзор различного вида таблиц “с хронологической
поддержкой”.
В таблицах допустимого времени состояния и таблицах времени транзакций
каждая временная отметка — это значение типа PERIOD.
В таблицах допустимого времени события каждая временная отметка— это
значение некоторого типа даты-времени.
Двухронологическая таблица представляет собой одновременно таблицу времени
транзакций и либо таблицу допустимого времени состояния, либо таблицу допус-
тимого времени события. Каждая строка в двухронологической таблице имеет два
хронологических элемента: один— для времени транзакции, другой— для до-
пустимого времени. Поэтому двухронологическая таблица может обрабатываться
как таблица времени транзакций или как таблица допустимого времени.
В языке TSQL2 строго соблюдается так называемая хронологическая прямая со-
вместимость. Ее суть заключается в том, чтобы можно было добавить
“хронологическую поддержку” к существующей базовой таблице путем преобра-
зования базовой таблицы из таблицы снимка в некоторого вида хронологическую
таблицу. С этого момента все обычные SQL-операции над такой базовой таблицей
интерпретируются как операции над текущей версией моментального снимка этой
таблицы15, но теперь они могут иметь новый побочный эффект. В частности, опе-
рации обновления и удаления для текущей версии моментального снимка сохра-
няют старые версии строк как строк с хронологическими элементами.
Выбранный в языке TSQL2 подход приобретает большое преимущество благодаря
так называемым последовательным операциям. Последовательная операция выра-
жается как операция над моментальным снимком базы данных (обычно — над те-
кущим снимком), но выполняется так, как если бы это был каждый моментальный
снимок. Результат выполнения последовательного запроса для таблиц допустимого
времени, например, является таблицей допустимого времени. Сам запрос выража-
ется так, как будто это запрос текущего снимка базы данных с добавлением от-
дельного ключевого слова, чтобы можно было указать, что это последовательный
запрос. В прикладных программах, в которых выдаются такие запросы, должно
быть создано специальное обеспечение для доступа к временной отметке в резуль-
тирующих строках.
14 Версия языка TSQL2, которая была предложена организацией ISO (но не была принята)
для включения в стандарт в 1996 году, отличается от версии, описанной в [22.4], где таблицы с
хронологической поддержкой всегда были “не вложенными” (т.е. каждый элемент представлял
собой отдельную временную отметку, а не множество отметок). Также не указывалось, свер-
нута таблица или нет.
15 На самом деле есть другое отличие между языком TSQL2, как он определен в [22.4], и вер-
сией, предложенной ISO. В [22.4] требуется ключевое слово SNAPSHOT после слова SELECT, озна-
чающее, что некоторый запрос зависит от текущего состояния каждой из таблиц, на которые
он ссылается. В версии, предлагаемой ISO, это не требуется.
Глава 22. Хронологические базы данных
895
Операции, которые не могут быть выражены как последовательные операции, ино-
гда требуют использования скрытого синтаксиса. Поскольку язык SQL не поддер-
живает таблиц, которые не имеют столбцов, язык TSQL2 имеет ограничение, со-
гласно которому таблица с хронологической поддержкой должна иметь по крайней
мере один обычный столбец, кроме дополнительных хронологических элементов.
Поэтому такие запросы, как “Показать периоды, в течение которых по крайней ме-
ре один поставщик из Парижа имел договор на поставку”, не могут быть выраже-
ны в последовательной форме.
Ответы к некоторым упражнениям
22.1.
а) Вероятно, нет (хотя мог бы и быть).
б) Символьная строка, непосредственно предшествующая символу ' q', зависит от
того, какой именно символ является последним в используемой сопоставимой
последовательности (см. [4.19], где рассматриваются сопоставимые последова-
тельности языка SQL). Если последним является символ ZZZ, то ответ будет та-
ким: [ zpz, zpZZz ].
Замечание. Напомним, что, строго говоря, элемент “(3)” в описании VARCHAR(3)
лучше считать не частью типа как такового, а ограничением целостности.
22.2. Во-первых, выражение Rl I_UNION R2 ON А равносильно следующему выражению.
( Rl UNION R2 ) COALESCE А
Обратите внимание, что нет необходимости в развертывании переменных-
отношений R1 и R2 по атрибуту А до выполнения операции свертывания (почему?). Во-
вторых, выражение Rl I_INTERSECT R2 ON А равносильно следующему выражению.
( ( EXTEND ( ( Rl RENAME A AS Al ) JOIN
( R2 RENAME A AS A2 )
ADD ( Al INTERSECT A2 AS A ) { ALL BUT Al, A2 } )
И вновь нет необходимости в развертывании переменных-отношений R1 и R2 по ат-
рибуту А. Более того, если переменные-отношения R1 и R2 фактически свернуты по
атрибуту А, нет необходимости и в заключительном этапе свертывания (почему?).
Хронологические версии других реляционных операторов (например, I_JOIN) мо-
гут быть определены аналогично. В частности, специальные версии операторов
UPDATE и DELETE, описанные в разделе 22.10, подразумевают неявное использова-
ние хронологической версии операции выборки.
Замечание. Возможно, следовало бы объяснить, почему в этой главе больше вни-
мания уделялось именно сокращению I_MINUS. Дело в том, что сокращение
I_MINUS включает развертывание, в то время как другие хронологические реляци-
онные операторы (как мы уже убедились) обычно его не включают16, и желатель-
но, где это возможно, избегать таких развертываний.
Исключение — операция SUMMARIZE (см. ответ купр. 22.6).
896
Часть V. Дополнительные аспекты
22.3. Вот возможное решение.
IF IS-EMPTY ( S-DURING WHERE S# = S# (ZS1Z)
AND STATUS = 20
AND END ( DURING ) = dlO )
THEN INSERT INTO S_DURING
( EXTEND ( S_DURING WHERE S# = S# (ZS1Z)
AND END ( DURING ) = dlO )
{ ALL BUT DURING }
AND INTERVAL ( [ dll, dl5 ] ) AS DURING ;
ELSE UPDATE S_DURING WHERE S# = S# (ZS1Z)
AND END ( DURING ) = dlO
DURING := INTERVAL ( [ START ( DURING ), dl5 ] );
22.4. Животные отличаются между собой диапазоном частоты света и звуковых волн,
которые воспринимают их глаза и уши. Существуют различные природные явле-
ния, и можно измерять в диапазонах глубину почвы или моря либо высоту над
уровнем моря. Тот факт, что чай пьют во второй половине дня, между 16.00 и
17.00,— это тоже хронологическое наблюдение, но оно существенно отличается
от примеров в этой главе (чем именно?). Не вызывает сомнения, что можно при-
думать множество подобных примеров, на которых могут основываться интерес-
ные приложения баз данных.
22.5. Животные отличаются между собой диапазоном частоты света и звуковых волн,
которые воспринимают их глаза и уши! Кроме того, как только мы соединим два
хронологических отношения R1{A,B} и R2{AtC}, где В и С— интервальные атрибу-
ты, будет получен результат (хотя и промежуточный), который имеет больше од-
ного интервального атрибута.
22.6.
WITH SP-DURING UNFOLD DURING AS SP UNFOLDED :
( SUMMARIZE SP UNFOLDED PER SP_UNFOLDED { DURING }
ADD MAX ( STATUS ) AS SMAX ) COALESCE DURING
22.7.
( ( EXTEND HW { HEIGHT, WEIGTH }
ADD INTERVAL ( [ HEIGHT, HEIGHT ] ) AS HR )
{ WEIGTH, HR } ) COALESCE HR
22.8. Утверждение а, как нетрудно заметить, допустимо. Утверждение б, как мы
сейчас убедимся, недопустимо. Пусть переменная-отношение R будет иметь
следующий вид.
11 12
[dO1,dO1] [d08,d09]
[d01,d02] [d08,d09]
[d03,d04] [d08,d08]
[d04,d04] [d08,d08]
Тогда результирующее отношение U выражений (R UNFOLD II) UNFOLD 12 и
(R UNFOLD 12) UNFOLD 11 будет иметь такой вид.
Глава 22. Хронологические базы данных
897
II 12
[dO1,dO1] [d08,d08]
[dO1,dO1] [dO9,dO9]
[d02,d02] [d08,d08]
[d02,d02] [dO9,dO9]
[d03,d03] [d08,d08]
[d04,d04] [d08,d08]
Однако результат выполнения выражения (U COALESCE II) COALESCE 12 будет
следующим.
II 12
[d01,d02] [d03,d04] [dO9,dO9] [d08,d08]
Результат выполнения выражения (U COALESCE 12) COALESCE II будет таким.
II 12
[dO1,dO2] [d03,d04] [d08,d09] [d08,d08]
Предлагаем вам проверить сказанное выше, записав результаты выполнения выра-
жений U COALESCE II и U COALESCE 12, а затем свернув полученные результаты по
атрибутам 12 и II соответственно. Также мы предлагаем следующие сокращения.
R UNFOLD 11,12 = (R UNFOLD II) UNFOLD 12
R COALESCE 11,12 = (R COALESCE II) COALESCE 12
898
Часть V. Дополнительные аспекты
Глава 23
Логические системы
управления базами данных
23Л. Введение
В середине 80-х годов в области исследования баз данных сформировалось мощное
направление, предметом изучения которого стали системы управления базами дан-
ных, основанные на логике. В научной литературе по этой тематике довольно часто
встречаются такие выражения, как логическая база данных, экспертная СУБД, дедук-
тивная СУБД, база знаний, система управления базой знаний, логика как модель данных,
выполнение рекурсивных запросов и т.д. Однако смысл этих терминов не всегда прозра-
чен, т.е. их употребление в том или ином контексте не всегда легко связать с привычной
терминологией, что усложняет понимание идей с точки зрения традиционного подхода к
исследованию баз данных. Вот почему необходимо разъяснить эти представления на ос-
нове обычных идей и принципов построения баз данных.
Назначение приведенного здесь материала— объяснить сущность логических баз
данных читателям, знакомым с обычными базами данных, но не совсем знакомым с ос-
новами логики. Причем каждая новая логическая идея по возможности будет разъяс-
няться с помощью традиционных терминов. Конечно, некоторые логические идеи уже
были представлены в этой книге, в частности в главе 7 при обсуждении реляционного
исчисления, которое непосредственно базируется на логике. Однако, как показано ниже,
под логическими базами данных подразумевается нечто большее, чем просто одно из
приложений реляционного исчисления.
Структура этой главы такова. После краткого введения следует раздел 23.2 с неболь-
шим обзором обсуждаемой темы и основных предпосылок ее возникновения. Затем в раз-
делах 23.3 и 23.4 приводится элементарное и весьма упрощенное описание исчисления вы-
сказываний (вычислений на основе логических утверждений) и исчисления предикатов.
После этого в разделе 23.5 представлен так называемый доказательно-теоретический
подход, а в разделе 23.6 описывается дедуктивная СУБД. Далее в разделе 23.7 рассматри-
ваются некоторые подходы к проблеме выполнения рекурсивных запросов, и наконец в раз-
деле 23.8 предлагаются резюме и несколько заключительных замечаний.
23.2. Обзор основных концепций
Исследования связей между базами данных и логикой начались еще в конце 70-х го-
дов, и о них можно прочесть в работах [23.5], [23.7] и [23.13]. Однако интерес к этой те-
ме значительно возрос после публикации в 1984 году работы Рейтера (Reiter) [23.15]. В
ней традиционное представление баз данных характеризуется как модельно-теорети-
ческое. Проще говоря, это означает следующее.
Глава 23. Логические системы управления базами данных
899
1. База данных в любой момент может рассматриваться как набор явно заданных (т.е.
базовых) отношений, каждое из которых включает набор явно заданных кортежей.
2. Выполнение запроса может рассматриваться как вычисление некоторой особой
формулы (т.е. выражения с логическим значением), представляющей собой комби-
нацию этих явно заданных отношений и кортежей.
Замечание. Более точное определение термина “модельно-теоретический” будет дано
в разделе 23.5.
В работе Рейтера наряду с модельно-теоретическим подходом рассматривается более
предпочтительная в некоторых отношениях альтернатива — доказательно-теоретическое
представление. Особенности этого представления заключаются в следующем.
1. База данных рассматривается как набор аксиом (“основных” аксиом, соответст-
вующих значениям домена и кортежам базовых отношений, а также определенных
“дедуктивных” аксиом, которые более подробно описаны ниже).
2. Выполнение запроса рассматривается как доказательство того, что некоторая за-
данная формула является логической последовательностью этих аксиом, т.е. тео-
ремой.
Замечание. Более точное определение термина “доказательно-теоретический” будет
дано в разделе 23.5, хотя можно сразу отметить, что доказательно-теоретическое пред-
ставление очень близко к описанию базы данных как набора истинных высказываний,
которое приводилось в разделе 1.3 главы 1 (см. также [1.2]).
Теперь полезно будет привести какой-нибудь конкретный пример. Рассмотрим сле-
дующий сформулированный в реляционном исчислении запрос к рассматриваемой ранее
базе данных поставщиков и деталей.
SPX WHERE SPX.QTY > 250
(Здесь SPX — это, конечно, переменная кортежа, принимающая значения из отноше-
ния поставок.) В традиционной, т.е. модельно-теоретической, интерпретации необходи-
мо последовательно проверить все кортежи с данными о поставках и оценить для каждо-
го из них результат вычисления формулы QTY > 250. При выполнении этого запроса бу-
дут извлечены все кортежи с описанием поставок, для которых данное выражение будет
истинным. В противоположность этому при доказательно-теоретической интерпретации
кортежи с описанием поставок (а также некоторые дополнительные объекты) рассматри-
ваются как аксиомы некой логической теории. Затем при обработке запроса применя-
ется доказательно-теоретический метод с целью выяснения, для каких возможных значе-
ний переменной SPX формула SPX. QTY>250 является логическим следствием аксиом этой
теории. Результатом выполнения запроса будут отдельные значения переменной-
отношения SPX.
Конечно, приведенный выше пример настолько прост, что с его помощью трудно об-
наружить существенные различия между двумя этими интерпретациями. Однако дело в
том, что ход рассуждений, лежащих в основе этого доказательства (в доказательно-
теоретической интерпретации), конечно же, гораздо сложнее, чем можно было бы про-
демонстрировать с помощью данного примера. Как будет показано ниже, такой ход рас-
суждений помогает справиться с проблемами, которые невозможно решить с помощью
классических реляционных систем. Более того, доказательно-теоретический подход
обладает целым рядом дополнительных преимуществ, перечисленных ниже [23.15].
900
Часть V. Дополнительные аспекты
Единство представления. Появляется возможность задать единый язык для всей
базы данных, согласно которому доменные значения, кортежи базовых
отношений, “дедуктивные аксиомы”, запросы и ограничения целостности будут
представлены одинаковым образом.
Единство действия. Предоставляется единая основа для решения различных за-
дач, включая оптимизацию запросов (особенно — семантическую оптимизацию),
обеспечение ограничений целостности, проектирование базы данных (теория за-
висимостей), доказательство корректности программ и др.
Семантическое моделирование. Появляется твердая основа для построения
множества “семантических” расширений основной модели.
Расширенное применение. Наконец, обеспечивается основа для решения таких
проблем, с которыми не могут справиться системы на основе классических подхо-
дов, например для работы с дизъюнктивной информацией наподобие “Поставщик
с номером 'S5' поставляет либо деталь с номером 'Р1', либо деталь с номером
' Р2', но какую именно, точно неизвестно”.
Дедуктивные аксиомы
В этом подразделе объясняется уже упоминавшееся понятие дедуктивной аксиомы,
которое также называется правилом вывода (или правилом заключения). По своей
сути дедуктивная аксиома— это правило, следуя которому на основе определенных
фактов можно вывести новые факты. Например, на основе фактов “Anne is the mother of
Betty” (“Анна — мать Бетти”) и “Betty is the mother of Celia” (“Бетти — мать Селии”) со-
гласно очевидной дедуктивной аксиоме можно вывести, что “Anne is the grandmother of
Celia” (“Анна— бабушка Селии”). Забегая наперед, можно представить дедуктивную
СУБД, в которой два данных факта оформлены в виде кортежей отношения MOTHER_OF с
атрибутами MOTHER (мать) и DAUGHTER (дочь).
MOTHER OF
MOTHER DAUGHTER
Anne Betty Betty Celia
Эти два факта будут основными аксиомами для системы. Предположим также, что
дедуктивная аксиома формально определена в СУБД с использованием следующего ги-
потетического упрощенного синтаксиса.
IF MOTHER_OF ( х, у )
AND MOTHER_OF ( у, z )
THEN GRANDMOTHER_OF ( х, z ) ;
Теперь это правило, выраженное в форме дедуктивной аксиомы, можно применить
к данным, выраженным в форме основных аксиом (конкретные способы такого при-
менения будут обсуждаться в разделе 23.4). Это позволит получить результат
GRANDMOTHER_OF(Anne, Celia). Таким образом, пользователи СУБД смогут создавать
запросы наподобие “Кто является бабушкой Селии?” и “Кто является внучкой Анны?”
(точнее будет спросить “Чьей бабушкой является Анна?”).
Глава 23. Логические системы управления базами данных
901
Сравним описанные идеи с традиционными концепциями баз данных. Согласно тра-
диционной терминологии дедуктивная аксиома может быть задана на основе приведен-
ного ниже определения представления.
VAR GRANDMOTHER_OF VIEW
( MX.MOTHER AS GRANDMOTHER, MY.DAUGHTER AS GRANDDAUGHTER)
WHERE MX.DAUGHTER = MY.MOTHER ;
Здесь умышленно используется стиль реляционного исчисления. MX и MY — перемен-
ные кортежа, которые изменяются на переменной-отношении MOTHER_OF. Запросы такого
типа могут быть оформлены на основе следующего представления.
GX.GRANDMOTHER WHERE GX.GRANDDAUGHTER = NAME ( 'Celia' )
GX.GRANDDAUGHTER WHERE GX.GRANDMOTHER = NAME ( 'Anne' )
Здесь GX — переменная кортежа, изменяющаяся на переменной-отношении
GRANDMOTHER_OF.
Таким образом, на основе другого синтаксиса и другой интерпретации был представ-
лен материал, который в основном уже знаком читателю. Однако в последующих разде-
лах на нескольких более сложных примерах будет показано, что на самом деле различия
между логическими системами и традиционными СУБД гораздо существеннее.
23.3. Исчисление высказываний
В этом и следующем разделах кратко и весьма упрощенно описываются некоторые
основные идеи логики. Так, в данном разделе описывается исчисление высказываний
(утверждений), а в следующем — исчисление предикатов (логических условий). Сразу
же следует отметить, что описание исчисления высказываний приводится лишь для по-
нимания более важной информации, изложенной ниже. Материал этих двух разделов яв-
ляется основой для остальных разделов данной главы.
Исходя из предположения, что читатель знаком с основными понятиями булевой ал-
гебры, в некоторых случаях мы будем использовать приведенные ниже термины и зако-
ны из этой области.
Дистрибутивные законы
f AND ( g OR h ) = ( f AND g ) OR ( f AND h )
f OR ( g AND h ) = ( f OR g ) AND ( f OR h )
Законы Де Моргана
NOT ( f AND g ) = NOT f OR NOT g
NOT ( f OR g ) = NOT f AND NOT g
Здесь f, g и h — произвольные булевы выражения.
Сама по себе логика может быть определена как формальный метод рассуждений.
В силу этого ее можно применять для выполнения таких формальных задач, как провер-
ка допустимости аргумента, т.е. последовательная, шаг за шагом, проверка только струк-
туры этого аргумента независимо от смысла шагов. В частности, благодаря такой фор-
мальности данный процесс может быть автоматизирован, т.е. запрограммирован и вы-
полнен компьютером.
902
Часть V. Дополнительные аспекты
Вообще говоря, исчисление высказываний и предикатов — это два специальных типа
логических рассуждений (хотя на самом деле первый из них является подмножеством
второго). Термин “исчисление”, в свою очередь, служит всего лишь общим термином,
используемым в любой системе с символическими вычислениями. В нашем конкретном
случае эти вычисления применяются для установления истинности значений некоторых
формул или выражений (т.е. истинны они или ложны).
Термы
Предположим для начала, что имеется набор объектов, называемых константами, о
которых делаются различного рода утверждения (или заключения). Согласно языку,
принятому в области баз данных, эти константы являются значениями из основных до-
менов, а утверждением может быть, например, такое условное выражение, как “3 > 2”.
Тогда термом мы будем называть утверждение, которое содержит такие константы и
обладает следующими свойствами.
1. Утверждения либо не содержат логических связок (подробности приводятся ниже),
либо заключены в скобки.
2. Утверждения однозначно оцениваются либо как истинные, либо как ложные.
Например, утверждения “Поставщик с номером 'S1' находится в городе 'London'”,
“Поставщик с номером 'S2' находится в городе 'London'” и “Поставщик с номером
'S1' поставляет деталь с номером 'Р1'” являются термами (в рассматриваемом примере
они оцениваются соответственно как истинное, ложное и истинное). И наоборот, ут-
верждения “Поставщик с номером 'S1' поставляет некоторую деталь с номером р”, где
р— переменная, и “Поставщик с номером 'S5' когда-нибудь в будущем будет постав-
лять деталь с номером 'Р1'” не являются термами, поскольку их нельзя однозначно оце-
нить как истинные или ложные.
Формулы
Формула исчисления высказываний или, в более общем смысле, исчисления преди-
катов используется в СУБД, помимо всего прочего, и для представления запросов.
«Формула>
::= <терм>
NOT <терМ>
<терМ> AND <формула>
<терм> OR <формула>
<терм> => <формула>
<терм>
::= <атомарная формула>
| ( <формула> )
Формулы вычисляются исходя из истинности значений входящих в них термов с ис-
пользованием обычных таблиц истинности для связок. Здесь следует отметить некото-
рые важные особенности.
1. Параметр <атомарная формула>— это логическое выражение, которое не содер-
жит связок и не заключено в скобки.
Глава 23. Логические системы управления базами данных
903
2. Символом “=>” обозначается связка типа логической импликации. По определению
выражение f => g логически эквивалентно выражению NOT f OR g.
Замечание. В главе 7 и других главах для этой связки использовалась конструкция
“IF ... THEN ...”
3. К связкам применяются обычные правила приоритета выполнения (NOT, за-
тем AND, затем OR, затем =>), что позволяет избежать многократного исполь-
зования скобок.
4. Высказывание — это просто элемент типа <формула>, как он определен выше.
Термин “формула” употребляется просто для согласования с материалом следую-
щего раздела.
Правила вывода
Правила вывода для исчисления высказываний имеют следующий вид.
h f => g
Здесь символом “ р’ обозначена фраза “Всегда верно, что”. Обратите внимание, что
такие символы необходимы для составления метаутверждений, т.е. утверждений об ут-
верждениях. Ниже приведено несколько примеров правил вывода.
1. Н f AND g ) => f
2. |= f => ( f OR g )
3. H ( f => g ) AND ( g => h ) ) => ( f => h )
4. ( f AND ( f => g ) ) => g
Замечание. Это чрезвычайно важное правило называется правилом отделения
(modus ponens). Неформально оно интерпретируется так: если f истинно и из f
следует д, то д также должно быть истинным. Допустим, например, что каждый из
приведенных ниже фактов является истинным.
а) У меня нет денег.
б) Если у меня нет денег, я должен мыть посуду.
Исходя из этих фактов можно заключить, что истинным является и следующий
факт.
в) Я должен мыть посуду.
Вот еще примеры правил вывода.
5. Н f => ( д => h ) ) ( ( f AND д ) h )
6. Н ( f OR д ) AND ( NOT д OR h ) ) => ( f OR h )
Замечание. Также очень важным является правило, которое называется правилом
резолюции. Более подробно оно описывается ниже, а затем мы вернемся к нему в
разделе 23.4.
904
Часть V. Дополнительные аспекты
Доказательства
Теперь нам известно все, что необходимо для создания формальных доказательств в
контексте исчисления высказываний. Задача доказательства состоит в определении, бу-
дет ли некоторая данная формула д, т.е. заключение, логическим следствием (выводом)
некоторого набора формул fl, f2,fn, т.е. предпосылок. Ниже дано символическое
представление доказательства.
fl, f2, fn I- g
Такая форма записи с использованием символа метаутверждения “ р’ интерпрети-
руется как “gr следует из fl, f2, ..., fn". Подобный способ выполнения называется
прямым формированием цепочки и заключается в последовательном применении
правил вывода к предпосылкам, затем — к формулам, выведенным из этих предпосы-
лок, затем — к формулам, выведенным из этих формул, и т.д. до тех пор, пока не бу-
дет выведено заключение. Иначе говоря, процесс “последовательного связывания” со-
стоит в переходе от предпосылок к заключению. Однако существует несколько вари-
антов этой основной схемы.
1. Принятие предпосылки. Если заключение д имеет вид р => д, то р принимается
как дополнительная предпосылка, a q выводится из заданных предпосылок и пред-
посылки р.
2. Обратное формирование цепочки. Вместо доказательства утверждения р => q
доказывается его контрапозиция (утверждение, обратное противоположному), т.е.
NOT q => NOT р.
3. Приведение к противоречию. Вместо доказательства прямого утверждения
р => q полагают, что р и NOT q являются истинными, и затем приходят к проти-
воречию.
4. Резолюция. В этом методе вывода используется правило резолюции (п. 6 преды-
дущего перечня).
Методику использования правила резолюции следует рассмотреть подробнее, по-
скольку она широко применяется на практике и, в частности, обобщается для исчисления
предикатов, в чем мы убедимся в разделе 23.4.
Прежде всего, нужно отметить, что правило резолюции фактически является пра-
вилом, которое позволяет сокращать подформулы. Например, рассмотрим следую-
щие формулы.
f OR g
NOT g OR h
В этом случае g и NOT g по правилу резолюции можно сократить до упрощенной формулы.
f OR h
В частности, на основе заданных формул f OR g и NOT g (т.е. допуская, что h являет-
ся истинным) можно вывести f.
Таким образом, можно отметить, что в общем случае данное правило применяется к
конъюнкции (AND) двух формул, каждая из которых является дизъюнкцией (OR) двух фор-
мул. Для применения правила резолюции нужно поступить следующим образом. (Чтобы
Глава 23. Логические системы управления базами данных
905
обсуждение этого вопроса было более конкретным, рассмотрим его на примере.) Допус-
тим, что необходимо определить, будет ли верным следующее предполагаемое доказа-
тельство (где А, В, С и D являются формулами).
А => ( В => С ), NOT D OR А, В |- D => С
Сначала следует принять отрицание заключения в качестве дополнительной предпо-
сылки, а затем записать каждую предпосылку в отдельной строке.
А => ( В => С )
NOT D OR А
В
NOT ( D => С )
Обратите внимание на то, что эти четыре строки неявным образом связаны между
собой с помощью операции AND.
Теперь нужно конвертировать каждую отдельную строку в конъюнктивную нормаль-
ную форму, т.е. в форму, состоящую из нескольких объединенных связками AND формул,
каждая из которых может содержать связки NOT и OR, но не связку AND (подробнее это опи-
сано в главе 17). В рассматриваемом примере вторая и третья строки уже имеют требуемый
вид. В двух других строках следует исключить все вхождения связки используя для
этого ее определение на основе связок NOT и OR. В случае необходимости можно применить
упомянутые выше дистрибутивные законы и законы Де Моргана. Кроме того, необходимо
убрать лишние скобки и пары смежных связок NOT, которые образуют двойное отрицание.
После выполнения всех этих действий строки примут следующий вид.
NOT A OR NOT В OR С
NOT D OR A
В
D AND NOT C
Каждую строку, которая явным образом содержит связку AND, следует заменить набо-
ром отдельных строк по одной для каждой формулы, связанной связкой AND (опуская при
этом все связки AND). В данном примере выполнить это действие необходимо только над
четвертой строкой. В результате все предпосылки будут выглядеть так, как показано ниже.
NOT A OR NOT В OR С
NOT В OR А
В
D
NOT С
Далее для объединения строк начнем применять правило резолюции. Для этого выбе-
рем пару “совмещаемых” строк, одна из которых содержит часть формулы, а другая —
ее отрицание. Например, выберем первые две строки, содержащие NOT А и А соответст-
венно. После их совмещения получится следующий результат.
NOT D OR NOT В OR С
В
D
NOT С
906
Часть V. Дополнительные аспекты
{Замечание. В общем случае необходимо также сохранить две исходные строки, од-
нако в данной ситуации они больше не нужны.) Теперь можно снова применить правило
резолюции для первых двух строк (совмещая NOT В и В), в результате чего будет получе-
но следующее.
NOT D OR С
D
NOT С
После еще одного совмещения первых двух строк (NOT Ви D) получится приведенный
ниже результат.
С
NOT С
Наконец после заключительного совмещения (Си NOT С) будет получено пустое множе-
ство заключений, которое обычно обозначается как “[ ]” и представляет собой противоре-
чие. Таким образом, путем приведения к противоречию получен нужный результат. |
23.4. Исчисление предикатов
Основным отличием исчисления предикатов от исчисления высказываний является
использование в формулах исчисления предикатов переменных1 и кванторов. Благодаря
этому эффективность и диапазон применения формул значительно увеличиваются. На-
пример, утверждения “Поставщик с номером 'S1' поставляет некоторую деталь с номе-
ром р” и “Некоторый поставщик с номером s поставляет некоторую деталь с номером р”
нельзя использовать в исчислении высказываний, однако это вполне допустимо в исчис-
лении предикатов. Таким образом, в исчислении предикатов можно составлять запросы
наподобие “Какие детали поставляются поставщиком с номером ' S1' ?”, “Найти постав-
щиков, поставляющих некоторые детали” и даже “Найти поставщиков, которые вовсе не
поставляют никаких деталей*’.
Предикаты
Как указывалось в главе 3, предикат — это логическая функция, которая при задан-
ных для ее параметров аргументах возвращает значение истина или ложь. Например,
выражение >{х,у) (оно чаще записывается в виде Х>у) является предикатом с двумя па-
раметрами, х и у. Этот предикат возвращает значение истина, если аргумент, соответст-
вующий параметру х, больше аргумента, соответствующего параметру у, и значение
ложь — в противном случае. Предикат, содержащий п аргументов (что равносильно
предикату, содержащему п параметров), называется л-местным предикатом. Утвержде-
ние (т.е. формула в смысле, определенном в разделе 23.3) может рассматриваться как
нуль-местный предикат, поскольку не имеет параметров и оценивается либо как истин-
ное, либо как ложное утверждение.
1 Такие переменные являются логическими переменными, а не переменными некоторого язы-
ка программирования. В данном случае их можно рассматривать как переменные кортежей в
смысле, определенном в главе 7.
Глава 23. Логические системы управления базами данных
907
Для удобства предполагается, что предикаты, соответствующие операциям “=”, “>”, “>” и
т.д., — встроенные (т.е. являются частью данной формально определенной системы) и выра-
жения, которые их включают, могут записываться обычным образом. Однако пользователи,
безусловно, могут определять предикаты самостоятельно. Как известно из предыдущих глав,
в терминах баз данных заданный пользователем предикат фактически представляет собой оп-
ределенную пользователем переменную-отношение. Например, переменная-отношение по-
ставщиков S может рассматриваться как предикат с четырьмя параметрами, а именно: S#,
SNAME, STATUS, CITY. Более того, выражения типа S (' S1', ' Smith', 20, ' London') и S('S6',
'White', 45, 'Rome') представляют собой “экземпляры” или “вызовы” такого предиката,
который вычисляется в результате со значением соответственно истина или ложь (в контек-
сте рассматриваемой здесь базы данных). Неформально говоря, такие предикаты (вместе с
любыми ограничениями целостности, которые также являются предикатами) можно рас-
сматривать в качестве определения того, что “подразумевает” база данных, как уже объясня-
лось в предыдущих частях книги, в частности в главе 8.
Правильно построенные формулы
Во избежание путаницы с термином “формула” из предыдущего раздела (термин, ко-
торый фактически относится к частному случаю) будем употреблять термин правильно
построенная формула (well-formed formula; произносится как “вэфф”), определение ко-
торого было дано в главе 7. Ниже приведен упрощенный синтаксис WFF-формулы.
<wff> ::= <терМ>
NOT ( <wff> )
( <wff> ) AND ( <wff> )
( <wff> ) OR ( <wff> )
( <wff> ) => ( <wff> )
EXISTS <нмя переменной> ( <wff> )
FORALL <имя переменной> ( <wff> )
<терМ> ::= [ NOT ] <имя предиката> [ ( <список аргументов^ ) ]
Отметим некоторые особенности этого синтаксиса.
1. Под словом терм подразумевается просто экземпляр предиката, который может
быть отрицаемым. Если рассматривать предикат как логическую функцию, то эк-
земпляр предиката — вызов такой функции. Каждый аргумент в параметре <список
аргументов> должен быть константой, именем переменной или обращением к
функции, а каждый аргумент функции, в свою очередь, — константой, именем пе-
ременной или обращением к функции. Для нуль-местного предиката параметр
<список аргументов> и окружающие его скобки опускаются.
Замечание. Использование логических функций допускается для того, чтобы по-
зволить включать в состав WFF-формулы вычисляемые выражения типа + (х,у),
которые обычно записываются в виде х+у.
2. Как и в разделе 23.3, для сокращения числа необходимых скобок здесь применяет-
ся обычный приоритет выполнения операций (NOT, затем AND, затем OR, затем =>).
3. Кванторы EXISTS и FORALL уже описывались в этой книге.
908
Часть V. Дополнительные аспекты
Замечание. Здесь подразумевается, что не существует “предикатных переменных”,
т.е. переменных, значениями которых являются предикаты, поэтому будут рассмот-
рены только предикаты первого порядка. Следовательно, имеется в виду, что преди-
каты сами по себе не могут быть под знаком квантора. (См. упр. 7.9 в главе 7.)
4. Законы Де Моргана можно обобщить на случай использования квантификации
WFF-формул следующим образом.
NOT ( FORALL х ( f ) ) = EXISTS х ( NOT ( f ) )
NOT ( EXISTS x ( f ) ) = FORALL x ( NOT ( f ) )
Эта тема также обсуждалась в главе 7.
5. Следует указать еще одну особенность, упомянутую в главе 7. Внутри некоторой
WFF-формулы каждый экземпляр переменной является либо свободным, либо
связанным. Переменная называется связанной, если сразу же за ней следует кван-
тор (указывающий квантифицируемую переменную) или если она находится в пре-
делах квантора и обозначает соответствующую квантифицируемую переменную. В
противном случае переменная называется свободной.
6. Закрытая WFF-формула не содержит ни одной свободной переменной. В про-
тивном случае она называется открытой WFF-формулой.
Интерпретации и модели
Для того чтобы понять, что такое WFF-формула, следует ввести понятие интерпре-
тации. Интерпретация WFF-формулы или (в более общем смысле) набора WFF-формул
определяется следующим образом.
Во-первых, необходимо определить пространство рассуждений, на котором бу-
дут интерпретироваться WFF-формулы. Иначе говоря, следует задать отображе-
ние между допустимыми константами формальной системы (в терминах базы дан-
ных это доменные значения) и объектами “реального мира”. Каждая отдельная
константа соответствует ровно одному объекту пространства рассуждений.
Во-вторых, нужно задать значение для каждого предиката на основе объектов в
пространстве рассуждений.
В-третьих, следует также задать значение для каждой функции на основе объектов
в пространстве рассуждений.
Таким образом, интерпретация включает комбинацию пространства рассуждений,
отображений отдельных констант на объекты этого пространства и заданных значений
для предикатов и функций по отношению к этому пространству.
Допустим, что пространством рассуждений является набор целых чисел {0,1,2,3,4,5};
такие константы, как 2, соответствуют элементам этого пространства очевидным образом,
а предикат Х>у задан с традиционным для данного символа значением. (Можно было бы
определить и такие функции, как “+”, и т.д.) Теперь зададим истинностные значения
для, например, таких WFF-формул.
2 > 1 : истинно
2 > 3 •. ложно
EXISTS х ( х > 2 ) : истинно
FORALL х ( х > 2 ) : ложно
Глава 23. Логические системы управления базами данных
909
Следует отметить, что возможны также другие интерпретации. Например, можно за-
дать пространство рассуждений в виде классификации уровней безопасности.
уничтожить перед прочтением (уровень 5
уничтожить после прочтения (уровень 4
совершенно секретно (уровень 3
секретно (уровень 2
для служебного пользования (уровень 1
несекретно (уровень 0
В этом случае предикат “>” будет означать “более секретно, чем” (т.е. более высокий
уровень безопасности).
Теперь ясно, что эти две интерпретации изоморфны, т.е. между ними можно задать вза-
имно однозначное соответствие, а значит, по большому счету эти две интерпретации оди-
наковы. Однако следует четко понимать, что могут существовать совершенно разные ин-
терпретации. Например, можно определить такое же пространство рассуждений на основе
целых чисел от 0 до 5, но задать предикат “>” со значением равно. (Это вполне возможно
осуществить, хотя на практике может возникнуть путаница.) В таком случае первое значе-
ние WFF-формулы в приведенном выше перечне будет ложным, а не истинным.
Другой важной особенностью является возможность совпадения истинностных зна-
чений WFF-формул для совершенно разных интерпретаций. В рассматриваемом примере
такая ситуация возможна, если предикат “>” определен по-разному, а значение WFF-
формулы 2>1 опущено.
Следует заметить, что все упомянутые выше в этом подразделе предикаты являются
закрытыми WFF-формулами. Дело в том, что для данной интерпретации всегда можно
задать однозначное логическое значение для закрытой WFF-формулы, но логическое
значение открытой WFF-формулы будет зависеть от значений, присвоенных свободным
переменным. Например, рассмотрим следующую открытую WFF-формулу.
х > 3
Она будет (очевидно) истинной, если значение х больше, чем 3, и ложной в против-
ном случае (при любых значениях “больше” и “3” в интерпретации).
Модель WFF-формулы или, в более общем смысле, набора (закрытых) WFF-формул яв-
ляется такой интерпретацией, для которой все функции набора WFF-формул истинны. Рас-
смотрим в свете двух приведенных выше интерпретаций четыре следующие WFF-формулы.
2 > 1
2 > 3
EXISTS х ( х > 2 )
FORALL х ( х > 2 )
Указанные интерпретации в терминах целых чисел от 0 до 5 не являются моделями
данных WFF-формул, потому что в каждом случае некоторые WFF-формулы принимают
ложные значения. И наоборот, первая интерпретация (в которой предикат “>” определен
“правильным” образом) могла бы быть моделью набора следующих WFF-формул.
2 > 1
3 > 2
EXISTS х ( х > 2 )
FORALL х ( х > 2 OR NOT ( x > 2 ) )
910
Часть V. Дополнительные аспекты
Наконец, стоит отметить, что если заданный набор WFF-формул может допускать не-
сколько интерпретаций, в которых эти WFF-формулы принимают истинные значения,
то он (в общем случае) может иметь несколько моделей. Таким образом, база данных в
общем случае может иметь несколько различных моделей, так как с модельно-
теоретической точки зрения она является просто набором WFF-формул. Подробности
приводятся в разделе 23.5.
Стандартная форма
Так же, как любая формула в исчислении высказываний может быть конвертирована
в конъюнктивную нормальную форму, WFF-формула в исчислении предикатов может
быть конвертирована в стандартную форму, которая может рассматриваться в качестве
расширенной версии конъюнктивной нормальной формы. Как показано ниже, одним из
побудительных мотивов выполнения такого конвертирования является возможность
применения правила резолюции при конструировании или проверке доказательств.
Ниже кратко изложен весь процесс конвертирования, а более подробное описание
представлено в [23.10]. Все этапы этого процесса демонстрируются на основе следую-
щей WFF-формулы.
FORALL х ( р ( х ) AND EXISTS у ( FORALL z ( q ( у, z ) ) ) )
В этой формуле р и q являются предикатами, а х, у и z — переменными.
1. Сначала следует, как это было сделано в разделе 23.3, исключить из записи симво-
лы В рассматриваемом примере данная операция не оказывает никакого
влияния на вид WFF-формулы.
2. Далее нужно использовать законы Де Моргана, а также тот факт, что две смежные
операции NOT нейтрализуют одна другую, но применять эти операции по отноше-
нию к термам, а не к общим WFF-формулам. В рассматриваемом примере эта опе-
рация не оказывает никакого влияния на вид WFF-формулы.
3. Теперь необходимо конвертировать WFF-формулу в предваренную нормальную
форму, перенося кванторы в начало формулы (и систематически переименовывая
переменные в случае необходимости).
FORALL х ( EXISTS у ( FORALL z ( р( х ) AND q( у, z ) ) ) )
4. Обратите внимание, что если содержащая кванторы WFF-формула, такая как
EXISTS v ( г ( v ) ),
эквивалентна другой WFF-формуле, например
г ( а ),
с некоторой (неизвестной) константой а, то в исходной WFF-формуле утверждает-
ся, что такая константа существует, хотя ее значение неизвестно. Точно так же
WFF-формула
FORALL u ( EXISTS v ( s ( u, v ) ) )
эквивалентна WFF-формуле
FORALL u ( s ( u, f ( u ) ) )
Глава 23. Логические системы управления базами данных
911
для некоторой неизвестной функции f, универсально квантифицированной пере-
менной и. Константа а и функция f в этих примерах называются в честь ученого-
логика Сколема (Skolem) соответственно константой Сколема (Skolem constant) и
функцией Сколема, где константа Сколема— это просто функция Сколема без
аргументов. Таким образом, на следующем этапе необходимо исключить излиш-
нюю квантификацию, заменяя соответствующие квантифицированные переменные
произвольными функциями Сколема всех универсально квантифицированных пе-
ременных, которые предшествуют данному квантору в WFF-формуле.
FORALL х ( FORALL Z ( р ( X ) AND q ( f ( X ), Z ) ) )
5. Теперь все переменные универсально квантифицированы; следовательно, можно
принять соглашение, что все они неявно универсально квантифицированы, и опус-
тить явные кванторы.
р ( х ) AND q ( f ( х ), z )
6. Далее необходимо конвертировать WFF-формулу в конъюнктивную нормальную
форму, т.е. в набор предложений, объединенных с помощью операции AND и, веро-
ятно, содержащих связки NOT и OR, но только не связку AND. В рассматриваемом
примере WFF-формула уже находится в такой форме.
7. Разместим каждое предложение в отдельной строке и опустим все связки AND.
р ( х )
q ( f ( х ), z )
Это и есть стандартная форма, эквивалентная оригинальной WFF-формуле.
Замечание. Из описанной выше процедуры следует, что общий вид WFF-формулы в
стандартной форме представляет собой набор предложений, размещенных в отдельных
строках с приведенным ниже синтаксисом.
NOT Al OR NOT A2 OR ... OR NOT Am OR Bl OR B2 OR ... OR Bn
Здесь все Аи В являются неотрицаемыми термами. Тот же синтаксис можно предста-
вить в другом виде.
Al AND А2 AND ... AND Ат => Bl OR B2 OR ... OR Bn
Если в этой записи присутствует по крайней мере один член В (п = 0 или п = 1), то
она в честь ученого-логика Альфреда Хорна (Alfred Hom) называется предложением
Хорна.
Использование правила резолюции
Теперь на основе примера из раздела 23.2 рассмотрим, как выполняются запросы в
логических базах данных. Допустим, что у нас есть предикат MOTHER_OF, который имеет
два параметра, представляющих мать и дочь соответственно, а также два следующих
терма (экземпляра предиката).
l.MOTHER_OF( 'Anne', 'Betty' )
2. MOTHER_OF( 'Betty', 'Celia' )
912
Часть V. Дополнительные аспекты
Кроме того, дана WFF-формула (“дедуктивная аксиома”), которая, по сути, является
предложением Хорна.
3. MOTHER_OF( х, у ) AND MOTHER_OF( у, z ) =>
GRANDMOTHER_OF( х, Z )
Для упрощения работы с правилом резолюции следует исключить из предложения
символ “=^” и переписать предложение таким образом.
4. NOT MOTHER_OF( х, у ) OR NOT MOTHER_OF( у, Z ) OR
GRANDMOTHER_OF( x, Z )
Далее необходимо показать, как доказывается утверждение, что Анна является ба-
бушкой Селии, т.е. как ответить на запрос “Является ли Анна бабушкой Селии?”. Для
этого нужно начать с отрицания заключения, которое требуется доказать, и принять его
как дополнительную предпосылку.
5. NOT GRANDMOTHER_OF( 'Anne', 'Celia' )
Теперь для применения правила резолюции необходимо систематически подставлять
значения для переменных таким образом, чтобы можно было найти два предложения,
содержащих WFF-формулу и ее отрицание. Подобная подстановка вполне законна, по-
скольку все переменные неявно универсально квантифицированы. Следовательно, инди-
видуальные (неотрицаемые) WFF-формулы должны быть истинны для всех и для каж-
дой допустимой комбинации значений этих переменных.
Замечание Процесс поиска набора подстановок, которые позволяют совместить два
предложения таким путем, называется унификацией.
Для того чтобы проиллюстрировать описанный выше процесс, обратимся к примеру.
Прежде всего следует обратить внимание на то, что строки в пп. 4 и 5 содержат термы
GRANDMOTHER_OF(x, z) и NOT GRANDMOTHER_OF('Anne', 'Celia') соответственно. Таким
образом, в строке п. 4 нужно подставить значение 'Anne' вместо х и значение 'Celia' —
вместо z. После совмещения получится такой результат.
6. NOT MOTHER_OF( 'Anne', у ) OR NOT MOTHER_OF( у, 'Celia' )
Строка п. 2 содержит выражение MOTHER_OF( 'Betty', 'Celia'), поэтому можно
подставить значение 'Betty' вместо у в строке п. 6 и после совмещения получить новое
выражение.
7. NOT MOTHER_OF( 'Anne', 'Betty' )
Совместив строки в пп. 7 и 1, получим пустое множество предложений [ ], т.е. проти-
воречие. Следовательно, результатом выполнения исходного запроса будет ответ “Да,
Анна является бабушкой Селии”. |
Теперь можно проанализировать, как будет выполняться запрос “Кто является внуч-
кой Анны?”. Сложность поставленной задачи заключается, прежде всего, в том, что сис-
теме ничего не известно о внучках, она обладает информацией только о бабушках. В
этом случае можно было бы добавить еще одну дедуктивную аксиому, согласно которой
z является внучкой х тогда и только тогда, когда х является бабушкой z (предполагается,
что в рассматриваемой базе данных не содержатся сведения о мужчинах). Тогда исход-
ный запрос можно перефразировать — “Чьей бабушкой является Анна?” — и использо-
вать тот же набор предпосылок, что и прежде.
Глава 23. Логические системы управления базами данных
913
l.MOTHER_OF( 'Anne', 'Betty' )
2. MOTHER_OF( 'Betty', 'Celia' )
3. NOT MOTHER_OF( x, у ) OR NOT MOTHER_OF( y, z ) OR
GRANDMOTHER_OF( x, Z )
Дополним его четвертой предпосылкой.
4. NOT GRANDMOTHER_OF( 'Anne', r ) OR RESULT( r )
Интуитивно эта предпосылка может рассматриваться как утверждение о том, что ли-
бо Анна не является ничьей бабушкой, либо, наоборот, существует некая особа г, кото-
рая отвечает требованиям, предъявляемым к результату (поскольку Анна является ба-
бушкой этой особы г). Предполагая, что такая особа существует, далее следует ее найти.
Сначала подставим значение 'Anne' вместо х и г вместо z. Совместив строки в пп. 4
и 3, получим следующий результат.
5. NOT MOTHER_OF( 'Anne', у ) OR NOT MOTHER_OF( у, z ) OR RESULT( z )
Подставив значение 'Betty' вместо у и совместив строки в пп. 5 и 1, получим
следующее.
6. NOT MOTHER_OF( 'Betty', z ) OR RESULT( z )
Наконец подставив значение 'Celia' вместо z и совместив строки в пп. 6 и 2, по-
лучим такой результат.
7. RESULT( 'Celia' )
Следовательно, Анна является бабушкой Селии. |
Замечание. Рассмотрим случай, когда задан дополнительный терм, как, например,
показано ниже.
MOTHER_OF ( 'Betty', 'Delia' )
Тогда на последнем этапе можно было бы подставить 'Delia' вместо z и получить в
результате следующее выражение.
RESULT ( 'Delia' )
Пользователю, конечно, желательно получить в результате оба имени. Таким
образом, необходимо, чтобы в системе тщательно были выполнены операции унифика-
ции и резолюции с выводом всех возможных значений. Однако технические детали ор-
ганизации такой работы системы в данной книге не рассматриваются.
23.5. Базы данных с точки зрения
доказательно-теоретического подхода
Как говорилось в разделе 23.4, предложением является выражение следующего вида.
Al AND А2 AND ... AND Ат => Bl OR B2 OR ... OR Bn
Здесь все А и В являются термами указанного ниже вида, где г— предикат, a xl, х2,
..., xt — его аргументы.
г ( xl, х2, ..., xt ),
914
Часть V. Дополнительные аспекты
В соответствии с [23.12] рассмотрим несколько важных типов этой общей конструкции.
Случай 1. ш = 0, n = 1.
В данном случае предложение может быть сведено к следующему простому виду.
=> В1
Его можно также записать в другом виде без символа импликации для некоторого
предиката г с набором аргументов xl, х2,..., xt.
г ( xl, х2, ..., xt)
Если все аргументы являются константами, то предложение представляет собой
основную аксиому, т.е. утверждение, которое однозначно является истинным. В
терминах базы данных такое утверждение соответствует кортежу некоторой пере-
менной-отношения R2. Как неоднократно отмечалось в этой книге, предикат г со-
ответствует “смысловому значению” переменной-отношения R. Например, в базе
данных поставщиков и деталей существует отношение SP, которое означает, что
заданный поставщик (S#) поставляет указанную деталь (Р#) в определенном коли-
честве (QTY). Обратите внимание, что это значение соответствует открытой WFF-
формуле, так как содержит несколько свободных переменных (S#, P# и QTY). И
наоборот, кортеж (’SI', 'Р1', 300), в котором все аргументы являются константа-
ми, представляет собой основную аксиому, или закрытую WFF-формулу, кото-
рая однозначно утверждает, что поставщик с номером 'S1' поставляет деталь с
номером 'Р1' в количестве 300.
Случай 2. ш > 0, n = 1.
В этом случае предложение принимает вид
Al AND А2 AND ... AND Ат => В
и может рассматриваться как дедуктивная аксиома. Она дает, возможно, непол-
ное определение предиката справа от знака следования в терминах, которые пред-
ставлены слева (см. в качестве примера определение предиката GRANDMOTHER_OF).
Кроме того, данное предложение может рассматриваться и как ограничение це-
лостности — ограничение переменной-отношения, если использовать термино-
логию главы 8. Предположим, что в нашем примере отношение S содержит только
два атрибута: S# и CITY. Тогда приведенное ниже предложение выражает ограни-
чение: атрибут CITY функционально зависит от атрибута S#.
S ( s, cl ) AND S ( s, с2 ) => cl = с2
Здесь следует обратить внимание на использование встроенного предиката “=”.
Из вышеизложенного можно заключить, что кортежи в отношениях (“основные аксио-
мы”), выведенные отношения (“дедуктивные аксиомы”) и ограничения целостности могут
рассматриваться как особые случаи общей конструкции предложения. Теперь рассмотрим,
как эти идеи могут привести к упомянутому ранее “доказательно-теоретическому” пред-
ставлению базы данных, упоминавшемуся в разделе 23.2.
2 Или значению в некотором домене.
Глава 23. Логические системы управления базами данных
915
Традиционное представление базы данных может считаться модельно-теорети-
ческим. Согласно этой точке зрения база данных рассматривается как набор явных име-
нованных переменных-отношений, каждая из которых содержит явный набор кортежей и
явный набор ограничений целостности. Рассмотрим, почему такое представление может
характеризоваться как модельно-теоретическое.
Используемые домены содержат переменные значения или константы, которые
используются для представления объектов “реального мира” (точнее, в некоторой
интерпретации, в смысле, который подразумевался в разделе 23.4). Таким обра-
зом, они соответствуют “пространству рассуждений”.
Переменные-отношения (точнее, их заголовки) представляют набор предикатов,
или открытых WFF-формул, которые должны быть интерпретированы в этом про-
странстве. Например, заголовок переменной-отношения SP представляет предикат
“Поставщик S# поставляет деталь P# в количестве QTY”.
Каждый кортеж данной переменной-отношения представляет собой экземпляр соот-
ветствующего предиката, т.е. однозначно истинное в пространстве рассуждений ут-
верждение (закрытую WFF-формулу, которая не содержит никаких переменных).
Ограничения целостности также являются закрытыми WFF-формулами и интер-
претируются в том же пространстве. Поскольку данные не нарушают (т.е. не
должны нарушать!) ограничений целостности, эти ограничения также всегда яв-
ляются истинными.
Кортежи и ограничения целостности вместе могут рассматриваться как набор ак-
сиом, задающих определенную логическую теорию (попросту говоря, под тер-
мином “теория” в логике подразумевается набор аксиом). Поскольку в данной
интерпретации все аксиомы истинны, такая интерпретация по определению явля-
ется моделью этой логической теории в смысле, подразумеваемом в разделе 23.4.
Следует заметить, что, как уже отмечалось в настоящем разделе, модель может
быть не уникальной, т.е. база данных может иметь несколько возможных интер-
претаций, каждая из которых допустима с логической точки зрения.
Следовательно, с модельно-теоретической точки зрения “смысловым значением” ба-
зы данных является модель в изложенном выше смысле термина “модель”. А поскольку
существует несколько возможных моделей, в принципе, существует и несколько воз-
можных смысловых значений3. Более того, обработка запросов в модельно-теоре-
тическом представлении является по существу процессом вычисления некоторой откры-
той формулы для определения, какие значения свободных переменных в этой WFF-
формуле сводят ее к значению истина в данной модели.
Для того чтобы применить правила вывода, описанные в разделах 23.3 и 23.4, необ-
ходимо использовать новую точку зрения, в соответствии с которой база данных явным
образом рассматривается как некая логическая теория, т.е. как набор аксиом. “Смыс-
3 Однако если предположить, что в базе данных не содержится явным образом никакой от-
рицаемой информации (например, утверждения наподобие “NOT S#( 'S9')”, где 'S9r не явля-
ется номером поставщика), то возможно существование “минимального” или канонического
значения, которое является пересечением всех возможных моделей [23.10]. Более того, как уже
отмечалось, в данном случае это каноническое значение будет таким же, как и значение, кото-
рое приписывается базе данных доказательно-теоретическим представлением.
916
Часть V. Дополнительные аспекты
ловым значением” этой базы данных становится набор истинных утверждений, которые
могут быть выведены из аксиом и их различных комбинаций, т.е. набора теорем, дока-
зуемых на основе этих аксиом. Так, в целом, выглядит доказательно-теоретический
подход, в котором выполнение запроса представляет собой доказательство некой теоре-
мы (во всяком случае на уровне концепции, хотя, как показано в разделе 23.7, для боль-
шей эффективности в системе, вероятнее всего, следует использовать традиционные
технологии выполнения запросов).
Замечание. Из сказанного следует, что отличие между модельно-теоретическим и
доказательно-теоретическим подходами состоит в том, что, в то время как с модельно-
теоретической точки зрения база данных может иметь несколько “смысловых значений”,
с доказательно-теоретической точки зрения она обычно обладает в точности одним
“смысловым значением”. Это верно за исключением двух случаев: когда, как уже упоми-
налось ранее, единственное значение является каноническим с модельно-теоретической
точки зрения, а также когда единственное значение с доказательно-теоретической точки
зрения прекращает быть истинным, если в базе данных содержатся какие-либо отрицае-
мые аксиомы [23.9], [23.10].
Ниже в неформальном виде перечислены аксиомы рассматриваемой в данном приме-
ре базы данных [23.15] (с доказательно-теоретической точки зрения).
1. Основные аксиомы, соответствующие значениям доменов и кортежей в базовых
переменных-отношениях, которые называются экстенсиональной базой данных
(extensional database).
2. “Аксиома дополнения” для каждой переменной-отношения, которая утверждает,
что для любого кортежа, отличного от допустимого для данной переменной-
отношения, соответствующее ей утверждение является ложным. (Фактически эти
аксиомы дополнения, взятые вместе, составляют допущение о замкнутости мира,
которое уже рассматривалось в главе 5.) Например, если в переменную-отношение
поставщиков S не включен кортеж ('S6', 'White', 45, 'Rome'), то утверждение
“Существует поставщик с номером 'S6' по имени 'White', который имеет статус
45 и проживает в городе 'Rome'” является ложным.
3. Аксиома “уникального имени”, которая утверждает, что каждая константа отлична
от других (т.е. обладает уникальным именем).
4. Аксиома “замкнутости доменов”, которая утверждает, что не существует никаких
других констант, кроме упомянутых в доменах базы данных.
5. Набор аксиом (по сути стандартных) для определения встроенного предиката ра-
венства Эти аксиомы обязательны, поскольку в аксиомах 2-4 используется
предикат равенства.
В заключение следует перечислить принципиальные различия между двумя точками
зрения — модельно-теоретической и доказательно-теоретической. Но прежде всего сле-
дует отметить, что с чисто практической точки зрения между ними нет существенной
разницы, по крайней мере в понятиях современных СУБД.
Аксиомы 2-5 из приведенного выше перечня согласно доказательно-
теоретическому подходу указывают, что некоторые допущения являются явны-
ми, хотя с точки зрения модельно-теоретического подхода они неявные [23.15].
Вообще говоря, явное задание аксиом довольно удобно и, более того, даже не-
Глава 23. Логические системы управления базами данных
917
обходимо для явного задания дополнительных аксиом, которые используются
для таких общих методов доказательства, как описанный в разделах 23.3 и 23.4
метод резолюции.
Следует отметить, что в аксиомах не упоминаются ограничения целостности. Дело в
том, что с доказательно-теоретической точки зрения при добавлении таких ограни-
чений СУБД становится дедуктивной. Подробнее об этом речь идет в разделе 23.6.
Доказательно-теоретическое представление, в отличие от модельно-
теоретического, обладает некоторой элегантностью, состоящей в едином пред-
ставлении нескольких конструкций, которые обычно рассматриваются как в ка-
кой-то мере разные: базовые данные, запросы, ограничения целостности
(несмотря на сказанное в предыдущем пункте), виртуальные данные и т.д. Это по-
зволяет создавать в большей степени единообразные интерфейсы и приложения.
С помощью доказательно-теоретического подхода можно решать проблемы, кото-
рые невозможно решить на основе реляционных систем, например обрабатывать
дизъюнктивную информацию типа “Поставщик с номером ' S6' проживает либо в
городе 'Paris', либо в городе 'Rome'”, извлекать отрицаемую информацию напо-
добие “Кто не является поставщиком?” и обрабатывать рекурсивные запросы, ко-
торые будут описаны ниже. Однако в отношении последнего случая (как минимум)
нет никаких принципиальных ограничений для соответствующего расширения клас-
сической реляционной системы с целью выполнения таких запросов. Более того, в
нескольких коммерческих продуктах их поддержка уже реализована (см. также при-
ложение Б). Подробнее эти вопросы рассматриваются в разделах 23.6 и 23.7.
Наконец, цитируя работу Рейтера (Reiter) [23.15], можно сказать, что доказатель-
но-теоретический подход “обеспечивает корректную обработку расширений реля-
ционной модели для более широкого включения семантики реального мира” (как
уже отмечалось в разделе 23.22).
23.6. Дедуктивные СУБД
Дедуктивная СУБД— это СУБД, в которой поддерживается доказательно-теоретичес-
кий подход к базам данных и которая, в частности, позволяет вывести дополнительные факты
из экстенсиональной базы данных с помощью специализированных дедуктивных аксиом,
или правил вывода, примененных к известным фактам4. Дедуктивные аксиомы вместе с ог-
раничениями целостности (они будут описаны ниже) образуют интенсиональную базу
данных (intensional database). Экстенсиональная и интенсиональная базы данных вместе со-
ставляют дедуктивную базу данных (это не совсем удачное название, поскольку на самом де-
ле выводы делает именно СУБД, а не база данных).
Как отмечалось выше, дедуктивные аксиомы образуют одну часть интенсиональной
базы данных, тогда как другая ее часть состоит из дополнительных аксиом, представ-
ляющих ограничения целостности (т.е. правила, используемые, прежде всего, для огра-
ничения обновлений, хотя в действительности такие правила могут использоваться и в
процессе дедукции для получения новых фактов).
4 В этой связи стоит заметить, что еще в 1974 году Кодд утверждал, что одной из задач
реляционной модели является, несомненно, “поглощение фактов выборки и управления файловы-
ми полями для пополнения в дальнейшем логического сервиса в коммерческом мире ” [11.2], [25.8].
918
Часть V. Дополнительные аспекты
Рассмотрим, как будет выглядеть база данных поставщиков и деталей, предс влен-
ная на рис. 3.8, в форме “дедуктивной СУБД”. Прежде всего следует определить набор
основных аксиом, которые задают допустимые значения домена.
Замечание. Далее для лучшей читабельности будут использоваться по существу те же со-
глашения относительно представления значений, которые применялись, например, на рис. 3.8,
и поэтому в качестве сокращения для записи QTY(300) будет использоваться просто 300 и т.д.
S# ( 1 'S1' ) NAME ( 'Smith' ) STATUS | : 5 ) CITY ( 'London
S# ( 1 'S2' ) NAME ( 'Jones' ) STATUS ( : Ю ) CITY ( 'Paris'
S# ( 1 'S3' ) NAME ( 'Blake' ) STATUS | ! 15 ) CITY ( 'Rome'
S# ( 1 'S4' ) NAME ( 'Clark' ) и т.д. CITY ( 'Athens
S# ( 1 'S5' ) NAME ( 'Adams' ) и т.д.
S# ( 1 'S6' ) NAME ( 'White' )
S# ( 1 'S7' ) NAME ( 'Nut' )
И Т.Д. NAME ( 'Bolt' )
NAME ( 'Screw' )
и т.д.
и т.д.
Затем следует задать основные аксиомы для кортежей базовых отношений.
S ( 'SI', 'Smith', 20, 'London' )
S ( 'S2', 'Jones', 10, 'Paris' )
И Т.д.
P ( 'Pl', 'Nut', 'Red', 12, 'London' )
и т.д.
SP ( 'SI', 'Pl', 300 )
и т.д.
Замечание. Конечно, здесь всерьез не предполагается, что экстенсиональная база данных
будет построена на основе всего лишь явного перечисления всех основных аксиом, как пока-
зано выше. Для этого, скорее всего, будет использовано традиционное определение и тради-
ционные методы ввода данных. Иначе говоря, дедуктивные СУБД применяют свои выводы
для традиционных баз данных, которые уже существуют и построены самым обычным спо-
собом. Однако следует обратить внимание на чрезвычайно важный факт: экстенсиональная
база данных не нарушает заданных ограничений целостности, поскольку база данных, нару-
шающая эти ограничения, представляет (на языке логических терминов) несовместимый на-
бор аксиом. Таким образом может быть доказана “истинность” абсолютно любого утвер-
ждения, каким бы оно ни было (другими словами, могут быть выведены противоречия). По
той же причине очень важно, чтобы набор ограничений целостности был совместимым.
Теперь перейдем к описанию интенсиональной базы данных. Для нее существует
следующий набор ограничений домена.
S ( s, sn, st, sc ) => S# ( s ) AND
NAME ( sn ) AND
STATUS ( St ) AND
CITY ( sc )
Глава 23. Логические системы управления базами данных
919
Р ( Pl Pnf pl I PWI pc ) => P# ( p ) AND
NAME ( pn ) AND
COLOR ( pl ) AND
WEIGHT ( pw ) AND
CITY ( pc )
и т.д.
Для интенсиональной базы данных существует также следующий набор ограничений
потенциальных ключей.
S ( s, snl, stlt sd ) AND S ( s, sn2, st2, sc2 )
=> snl = sn2 AND \
stl = st2 AND
scl = sc2
и т.д.
Кроме того, для интенсиональной базы данных существует следующий набор
ограничений внешних ключей.
SP ( s, р, q ) => S ( s, sn, stt sc ) AND
P ( p, pn, pt, pw, pc )
И т.д.
Замечание. Для удобства представления здесь предполагается, что переменные,
расположенные справа от символа импликации (sn, st и т.д.), связаны с квантором су-
ществования. (Все остальные, как отмечалось выше, в разделе 23.3, связаны с квантором
всеобщности.) С технической точки зрения мы нуждаемся в некоторой функции Сколе-
ма. Например, переменная sn в действительности должна быть заменена, скажем, функ-
цией SN( s), где SN является функцией Сколема.
Кстати, обратите внимание, что в данном случае многие ограничения нельзя считать
чистыми предложениями в смысле, определенном в разделе 23.5, поскольку их правая
сторона не является дизъюнкцией простых термов.
Теперь следует добавить несколько дедуктивных аксиом.
S ( s, sn, st, sc ) AND st > 15
=> GOOD_SUPPLIER ( s, st, sc )
(Сравните с определением представления GOOD_SUPPLIER, данным в разделе 9.1 главы 9.)
S ( sx, sxn, sxt, sc ) AND S ( sy, syn, syt, sc )
=> SS-COLOCATED ( sx, sy )
S ( s, sn, st, c ) AND P ( p, pn, pl, pw, c )
=> SP-COLOCATED ( s, p )
И т.д.
Для того чтобы рассматриваемый пример был интереснее, попробуем расширить базу
данных поставщиков и деталей, включив в нее переменную-отношение “состав деталей”,
которая будет содержать сведения о том, какие детали ру входят в качестве компонентов
первого уровня в состав другой детали (узла) рх. Для этого прежде всего следует задать
ограничение на идентификацию существующих деталей (рх и ру).
920
Часть V. Дополнительные аспекты
PART_STRUCTURE ( px, py ) => P ( px, xn, xl, xw, xc ) AND
P ( РУ, УП, yl, yw, yc )
Затем необходимо определить некоторые значения ее данных.
PART_STRUCTURE ( 'Pl', 'Р2' )
PART_STRUCTURE ( 'Pl', 'РЗ' )
PART_STRUCTURE ( 'Р2', 'РЗ' )
PART_STRUCTURE ( 'Р2', 'Р4' )
и т.д.
(На практике определение PART_STRUCTURE должно было бы также иметь аргумент
“количество”, который указывал бы количество деталей ру, входящих в состав детали рх,
но в данном случае он опускается из соображений простоты.)
Теперь можно добавить пару дедуктивных аксиом для объяснения, каким образом де-
таль рх содержит деталь ру в качестве компонента любого уровня.
PART_STRUCTURE ( рх, ру ) => COMPONENT_OF ( рх, ру )
PART_STRUCTURE ( рх, pz ) AND COMPONENT_OF ( pz, py )
=> COMPONENT_0F ( px, py )
Иначе говоря, деталь py является компонентом детали рх на определенном уровне,
если она является непосредственным компонентом либо детали рх, либо детали pz, кото-
рая, в свою очередь, является компонентом детали рх на определенном уровне. Обратите
внимание, что вторая аксиома рекурсивна, поскольку предикат COMPONENT_OF определя-
ется в ней на основе самого этого предиката5. В классических реляционных системах,
наоборот, не допускается использование подобных рекурсивных определений представ-
лений (а также запросов, ограничений целостности и т.п.). Эта способность поддержи-
вать рекурсивные определения — одно из самых очевидных различий между дедуктив-
ными СУБД и их классическими аналогами. Хотя, как уже упоминалось в разделе 23.5 и
как было показано в главе 6, не существует фундаментального ограничения, из-за кото-
рого классическую реляционную алгебру нельзя было бы расширить для поддержки со-
ответствующего набора рекурсивных операторов.
В разделе 23.7 возможность поддержки рекурсии обсуждается несколько подробнее.
Язык Datalog
Из сказанного можно сделать вывод, что наиболее ясно выраженной частью дедук-
тивной СУБД может быть язык, на котором будут формулироваться дедуктивные аксио-
мы (или правила). Самым известным языком такого типа является Datalog [23.9], на-
званный так по аналогии с языком Prolog. Ниже приведено его краткое описание.
Замечание. Основное внимание при создании этого языка уделялось не его вычисли-
тельным (как это обычно бывает с традиционными реляционными моделями [5.1]), а
описательным качествам. При этом основной целью было создание языка, гораздо более
5 Фактически было определено транзитивное замыкание — в любой момент отношение, со-
ответствующее предикату COMPONENT OF, является транзитивным замыканием отношения,
соответствующего предикату PART_STRUCTURE (см. главу 6).
Глава 23. Логические системы управления базами данных
921
выразительного, чем традиционные реляционные языки [23.9]. В результате в языке
Datalog, как и во всех логических СУБД, был сделан акцент на операциях выполнения
запросов, а не обновления данных, хотя можно и нужно расширить этот язык также для
поддержки операций обновления (подробнее об этом будет сказано ниже).
В простейшей форме язык Datalog поддерживает формулировку правил в виде про-
стых предложений Хорна без функций. В разделе 23.4 предложение Хорна было опреде-
лено как WFF-формула одного из двух видов.
Al AND А2 AND ... AND An
Al AND A2 AND ... AND An =$ В
В этих конструкциях все А и В являются неотрицаемыми экземплярами предикатов,
которые содержат только константы и переменные. Однако в языке Datalog вторая из
приведенных конструкций записывается в обратном порядке.
В <= Al AND А2 AND ... AND An
Для полного соответствия с другими публикациями на эту тему далее будет использовать-
ся именно такая запись. В данном предложении В является заголовком правила, или заклю-
чением, а терм А— телом правила, или предпосылкой либо целью, в которой отдельные
термы являются подчиненными целями (или подцелями). Для краткости связки AND часто
заменяют запятыми. Следовательно, программа на языке Datalog представляет собой набор
таких предложений, разделенных обычным образом, т.е. точкой с запятой (в этой книге, одна-
ко, вместо точки с запятой используется перенос на отдельную строку). При этом в такой про-
грамме порядок расположения предложений не имеет никакого значения.
Заметим, что вся дедуктивная база данных может рассматриваться как программа
Datalog в указанном выше смысле. Можно, например, все аксиомы, заданные для по-
ставщиков и деталей (основные аксиомы, ограничения целостности и дедуктивные ак-
сиомы), записать в стиле программы Datalog, разделив их точкой с запятой или размес-
тив в отдельных строках, и в результате получить программу на языке Datalog. Однако,
как уже указывалось, экстенсиональная часть базы данных обычно не определяется та-
ким способом; она определяется так, как принято в традиционных базах данных. Основ-
ная функция языка Datalog заключается в формулировании дедуктивных аксиом. Как от-
мечалось выше, эту функцию следует рассматривать в качестве расширения механизма
определений представлений, существующего в современных реляционных СУБД.
Язык Datalog может также использоваться в качестве языка запроса (точно так, как и
язык Prolog). Для примера предположим, что на языке Datalog дано следующее опреде-
ление “хороших” поставщиков GOOD_SUPPLIER.
GOOD_SUPPLIER ( s, st, sc ) <= S ( s, sn, st, sc )
AND st > 15
Ниже приведены примеры запросов на основе этого определения.
1. Найти всех хороших поставщиков.
? <= GOOD_SUPPLIER ( s, st, sc )
2. Найти хороших поставщиков в Париже.
? <= GOOD_SUPPLIER ( s, st, 'Paris' )
922
Часть V. Дополнительные аспекты
3. Является ли поставщик с номером 'S1' хорошим?
? <= GOOD_SUPPLIER ( 'SI', st, sc )
И так далее. Иначе говоря, запрос на языке Datalog состоит из специального правила
с заголовком типа “?” и телом, состоящим из одного терма, который обозначает резуль-
тат запроса. Заголовок “?” означает (по соглашению) “Показать”.
Следует отметить, что несмотря на поддержку рекурсии существует достаточное ко-
личество стандартных операций для традиционных реляционных систем, которые не
поддерживаются в языке Datalog, например скалярные операции и т.д.), опера-
ции обобщения (COUNT, SUM и др.), группирования и т.д. В этом языке также не поддер-
живается именование атрибутов (значение аргументов предиката зависит от его относи-
тельного расположения), не обеспечивается полная поддержка доменов (т.е. типов дан-
ных, определенных пользователем в смысле, изложенном в главе 5). Как уже отмечалось,
в языке не предусмотрены операции обновления, а также не поддерживается деклара-
тивная спецификация удаления и обновления внешних ключей (DELETE CASCADE и т.д.).
Для преодоления всех этих недостатков было предложено несколько расширений
языка Datalog. Предполагается, что, помимо всего прочего, эти расширения обладают
следующими дополнительными возможностями.
Отрицаемые предпосылки, например такие, как показано ниже.
SS_COLOCATED ( sx, sy ) <= S ( sx, sxn, sxt, sc ) AND
S ( sy, syn, syt, sc ) AND
NOT ( sx = sy )
Скалярные операторы (встроенные и определенные пользователем), например та-
кие, как показано ниже.
P_WT_IN_GRAMS ( р, pn, pl, pg, рс ) <=
Р ( Р/ Pni РГ Pwi Рс ) AND pg = pw * 454
В данном примере предполагается, что встроенная функция (умножение) может
быть записана в обычном инфиксном представлении. Более ортодоксальное представ-
ление терма, следующего за оператором AND, выглядело бы как =(рд, *(pw, 454)).
Операторы обобщения и группирования (в некотором смысле эта тема касается
отдельных особенностей оператора SUMMARIZE, что подробнее описано в главе 6).
Эти операторы необходимы для того, чтобы разрешить проблему так называемых
требований обобщения. Она заключается не только в поиске деталей ру, которые
являются компонентами деталей рх на любом уровне, но также в выяснении,
сколько деталей ру (на всех уровнях) требуется для изготовления детали рх (при
этом, естественно, предполагается, что переменная-отношение PART_STRUCTURE
содержит атрибут QTY).
Операторы обновления. Один из подходов в реализации этих операций, и не толь-
ко их, основан на том наблюдении, что в языке Datalog любой предикат в заголов-
ке правила должен быть неотрицаемым и каждый кортеж, генерируемый этим
правилом, может рассматриваться как “вставленный” в результирующее отноше-
ние. Возможное расширение, таким образом, должно допускать использование
отрицаемых предикатов в заголовке правила и рассматривать отрицание как за-
прос на удаление (соответствующих кортежей).
Глава 23. Логические системы управления базами данных
923
Предложения “не-хорн веского” типа в теле правила. Иначе говоря, в определе-
нии правил допускается использование WFF-формул самого общего вида.
Обзор этих расширений вместе с примерами и обсуждением приложений языка
Datalog можно найти в книге [23.10], где также обсуждается множество методов реали-
зации языка Datalog.
23.7. Обработка рекурсивных запросов
Как отмечалось в предыдущем разделе, одна из наиболее замечательных особенно-
стей дедуктивных СУБД — способность поддерживать рекурсию. Именно поэтому изу-
чению технологий реализации рекурсии в последние годы уделялось значительное вни-
мание. Действительно, с 1986 года на каждой научной конференции по базам данных
один или несколько докладов обязательно посвящаются этой теме. Ниже кратко обсуж-
дается поддержка рекурсивных запросов — функция, которая обычно не характерна для
традиционных СУБД.
В качестве примера повторим приведенное в разделе 23.6 рекурсивное определение
переменной-отношения COMPONENT_OF в терминах структуры состава деталей
PART_STRUCTURE (для краткости вместо полного названия PART_STRUCTURE используется
сокращение PS, а вместо COMPONENT_OF — COMP; кроме того, используется запись, приня-
тая в языке Datalog).
COMP ( рх, ру ) <= PS ( рх, ру )
COMP ( рх, ру ) <= PS ( рх, pz ) AND COMP ( pz, py )
А вот пример типичного рекурсивного запроса к базе данных (“Найти все компонен-
ты, из которых состоит деталь с номером 'Р1'”).
? <= COMP ( 'Р1', ру )
I
Второе правило в приведенном выше рекурсивном определении является линейно
рекурсивным, поскольку предикат из заголовка правила встречается в теле правила толь-
ко один раз. На самом деле можно переопределить это правило таким образом, чтобы
рекурсия не была линейной.
COMP ( рх, ру ) <= PS ( рх, ру )
COMP ( рх, ру ) COMP ( рх, pz ) AND COMP ( pz, py )
Однако с практической точки зрения линейная рекурсия представляет гораздо боль-
ший интерес, потому что чаще встречается на практике и для ее применения разработано
несколько известных и эффективных методов [23.16]. Поэтому далее речь пойдет ис-
ключительно о линейной рекурсии.
Замечание. Для полноты изложения следует подчеркнуть, что понятие “рекурсивное
правило” необходимо обобщить для решения более сложных случаев следующего типа.
р ( х, у ) <= Q ( х, z ) AND R ( z, у )
Q ( х, у ) <= Р ( х, z ) AND S ( z, у )
Для краткости изложения эти особенности будут опущены. Более подробную инфор-
мацию о них можно найти в [23.16].
924
Часть V. Дополнительные аспекты
Так же, как при обработке классических (нерекурсивных) запросов, в целом, пробле-
ма реализации заданного рекурсивного запроса может быть разбита на две отдельные
части, а именно: преобразование исходного запроса в эквивалентную, но более эффек-
тивную форму и собственно выполнение преобразованного таким образом запроса. В
литературе содержатся описания различных подходов к решению этих проблем. Ниже
кратко описаны некоторые простейшие из предложенных технологий. Они будут проил-
люстрированы на примере запроса “Найти все компоненты детали с номером 'Р1'” с ис-
пользованием приведенного ниже набора значений в переменной-отношении PS.
РХ PY
Р1 Р2
Р1 РЗ
Р2 РЗ
Р2 Р4
РЗ Р5
Р4 Р5
Р5 Р6
Унификация и резолюция
Одним из возможных подходов, конечно, является использование стандартных для
языка Prolog методов унификации и резолюции, описанных в разделе 23.4. В данном
примере этот подход будет реализован следующим образом. Прежде всего следует ука-
зать первичные предпосылки, которые являются дедуктивными аксиомами и в конъюнк-
тивной нормальной форме выглядят так, как показано ниже.
1. NOT PS ( рх, ру ) OR COMP ( рх, ру )
2. NOT PS ( рх, pz ) OR NOT COMP ( pz, py ) OR COMP ( px, py )
Еще одна предпосылка создана на основе искомого заключения.
3. NOT COMP ( 'Pl', ру ) OR RESULT ( py )
Основные аксиомы образуют оставшиеся предпосылки. Ниже приведен пример од-
ной из таких аксиом.
4. PS ( 'Pl', 'Р2' )
Подставив 'Р1' вместо рх и 'Р2' вместо ру в строке из п. 1 и совместив строки из
пп. 1 и 4, получим следующий результат.
5. COMP ( 'Pl', 'Р2' )
Теперь, подставив значение 'Р2' вместо ру в строке из п. 3 и совместив строки из
пп. 3 и 5, получим окончательный результат.
6. RESULT ( 'Р2' )
Таким образом, деталь с номером 'Р2' является компонентом детали с номером 'Р1'.
Аналогично можно показать, что деталь с номером 'РЗ' также является компонентом
детали с номером 'Р1'. Теперь, обладая дополнительными аксиомами СОМР( 'Pl', 'Р2')
и СОМР('Р1','РЗ'), можно рекурсивно выполнить поиск всех остальных компонентов.
Эта задача предлагается читателю в качестве упражнения.
Глава 23. Логические системы управления базами данных
925
Однако на практике применение унификации и резолюции может в значительной сте-
пени снизить производительность системы. Поэтому желательно найти и использовать
более эффективную стратегию. Несколько таких стратегий описано ниже.
Наивное оценивание
Наивное оценивание [23.25], судя по названию, является, вероятно, простейшим
подходом. Его можно продемонстрировать (на основе рассматриваемого примера запро-
са) с помощью приведенного ниже псевдокода.
COMP := PS ;
do until COMP reaches a "fixpoint" ;
/* Выполнять, пока COMP не достигнет "точки неизменности" */
COMP := COMP UNION ( COMP » PS ) ;
end ;
DISPLAY := COMP WHERE PX = P# ('Pl') ;
Каждая из переменных-отношений COMP и DISPLAY (подобно переменной-отношению
PS) имеет по два атрибута: РХ и PY. Попросту говоря, выполнение этого алгоритма с по-
лучением промежуточного результата, состоящего из объединения соединения отноше-
ния PS и предыдущего промежуточного результата, повторяется до тех пор, пока проме-
жуточный результат не достигнет точки неизменности, т.е. пока не прекратится рост
(изменение) промежуточного результата.
Замечание. Выражение COMP я PS является сокращенной формой записи выражения
“соединить СОМР и PS по атрибутам COMP.PY и PS.PX с выводом результатов по атрибутам
СОМР.РХ и PS.PY”. Для краткости здесь игнорируются операции переименования атрибу-
та, соответствующие рассматриваемому диалекту данной алгебры (подробности приво-
дятся в главе 6).
Теперь попробуем применить этот алгоритм к рассматриваемому набору данных.
Ниже показаны результаты выполнения первой итерации цикла: слева приведены значе-
ния выражения СОМР й PS, а справа — значения величины СОМР (кортежи, добавленные в
ходе этой итерации, отмечены звездочкой).
СОМР JS PS РХ PY СОМР РХ PY
Р1 РЗ Р1 Р2
Р1 Р4 Р1 РЗ
Р1 Р5 Р2 РЗ
Р2 Р5 Р2 Р4
РЗ Р6 РЗ Р5
Р4 Р6 Р4 Р5
Р5 Р6
Р1 Р4 *
Р1 Р5 *
Р2 Р5 *
РЗ Р6 *
Р4 Р6 *
Далее приведены результаты, полученные после второй итерации.
926
Часть V. Дополнительные аспекты
СОМР s PS РХ PY СОМР РХ PY
Р1 РЗ Р1 Р2
Р1 Р4 Р1 РЗ
Р1 Р5 Р2 РЗ
Р2 Р5 Р2 Р4
РЗ Рб РЗ Р5
Р4 Рб Р4 Р5
Р1 Рб Р5 Рб
Р2 Рб Р1 Р4
Р1 Р5
Р2 Р5
РЗ Рб
Р4 Рб
Р1 Рб *
Р2 Рб *
Внимательно их просмотрев, можно заметить, что на второй итерации повторяется
вычисление кортежей СОМР » PS, полученных во время первой итерации, а также вычис-
ляется несколько дополнительных кортежей (в данном случае — два кортежа:
('Pl', 'Рб') и('Р2', 'Рб')). Это делает методику наивного оценивания не очень при-
влекательной.
После третьей итерации и повторения всех необходимых вычислений извлекаемые
значения выражения COMP » PS остаются теми же, что и в предыдущей итерации. Таким
образом, точка неизменности для СОМР достигается и выполнение цикла завершается.
Выполнив выборку СОМР по всем РХ, равным ' Р1', получим окончательный результат.
COMP Грх Гру
Р1 Р2
Р1 РЗ
Р1 Р4
Р1 Р5
Р1 Рб
Неэффективность этого алгоритма проявляется еще и в том, что он выполняет огром-
ную работу по поиску компонентов каждой детали, фактически вычисляя транзитивное
замыкание отношения PS (ниже это описано более подробно), и оставляет в виде конеч-
ного результата лишь небольшую часть вычисленных кортежей. Иначе говоря, при этом
выполняется большой объем ненужной работы.
В заключение следует отметить, что наивное оценивание можно рассматривать как
применение метода прямого формирования цепочки. В самом деле, оно начинается с ис-
пользования экстенсиональной базы данных (т.е. с действительных значений данных), а за-
тем продолжается в виде повторного использования предпосылок определения (т.е. основы
правила) вплоть до получения желаемого результата. Фактически этот алгоритм позволяет
вычислить .минимальную модель для программы на языке Datalog (см. разделы 23.5 и 23.6).
Полунаивное оценивание
Первым очевидным усовершенствованием алгоритма наивного оценивания является
возможность избежать повторных вычислений результатов, полученных во время пре-
дыдущей итерации. Такой усовершенствованный алгоритм называется полунаивным
Глава 23. Логические системы управления базами данных
927
оцениванием [23.28]. Иначе говоря, на каждом шаге итерации вычисляются только но-
вые кортежи, которые добавляются к полученным ранее результатам. Эта идея вновь бу-
дет проиллюстрирована на примере запроса “Найти все компоненты детали с номером
'Р1'”. Ниже показана реализация соответствующей процедуры на псевдокоде.
NEW := PS ;
COMP := NEW ;
do until NEW is empty ;
/* Выполнять, пока отношение NEW не окажется пустым */
NEW := ( NEW й PS ) MINUS COMP ;
COMP := COMP UNION NEW ;
end ;
DISPLAY := COMP WHERE PX = P# ('Pl') ;
Теперь стоит просмотреть, как выполняется этот алгоритм на примере использован-
ных ранее данных. Перед выполнением цикла переменные-отношения NEW и СОМР иден-
тичны переменной-отношению PS.
NEW РХ PY СОМР РХ PY
Р1 Р2 Р1 Р2
Р1 РЗ Р1 РЗ
Р2 РЗ Р2 РЗ
Р2 Р4 Р2 Р4
РЗ Р5 РЗ Р5
Р4 Р5 Р4 Р5
Р5 Р6 Р5 Р6
После выполнения первой итерации эти переменные-отношения будут выглядеть
следующим образом.
NEW РХ PY
Р1 Р4
Р1 Р5
Р2 Р5
РЗ Р6
Р4 Р6
СОМР
РХ PY
Р1 Р2
Р1 РЗ
Р2 РЗ
Р2 Р4
РЗ Р5
Р4 Р5
Р5 Р6
Р1 Р4 *
Р1 Р5 *
Р2 Р5 *
РЗ Р6 *
Р4 Р6 *
Данные в переменной-отношении СОМР такие же, как при использовании алгоритма
наивного оценивания, а данные в переменной-отношении NEW содержат только те корте-
жи, которые были добавлены в СОМР на этой итерации. Обратите внимание, что данные в
переменной-отношении NEW не содержат кортеж ('Р1', 'РЗ') (сравните с данными, по-
лученными при наивном оценивании).
928
Часть V. Дополнительные аспекты
Ниже приведены результаты, которые будут получены после выполнения следую-
щей итерации.
РХ PY
Р1 Р6
Р2 Р6
РХ PY
Р1 Р2
Р1 РЗ
Р2 РЗ
Р2 Р4
РЗ Р5
Р4 Р5
Р5 Р6
Р1 Р4
Р1 Р5
Р2, Р5
РЗ Р6
Р4 Р6
Р1 Р6
Р2 Р6
На следующей итерации для переменной-отношения NEW никаких данных получено не
будет и цикл завершится.
Статическое фильтрование
Статическое фильтрование базируется на основной идее классической теории
оптимизации — налагать ограничения на самых ранних этапах вычислений. Его мож-
но рассматривать как приложение метода прямого формирования цепочки, поскольку
в нем информация запроса (заключения) фактически используется для модификации
правил (предпосылок). Иногда этот способ называется сокращением набора необходи-
мых фактов, так как в нем информация запроса используется (вновь) для исключения
ненужных кортежей из экстенсиональной базы данных непосредственно на выходе
[23.29]. Эффективность этого способа мы продемонстрируем с помощью следующей
процедуры на псевдокоде.
NEW := PS WHERE РХ = P# ( 'Pl' ) ;
COMP := NEW ;
do until NEW is empty ;
/* Выполнять, пока отношение NEW не окажется пустым */
NEW := (NEW й PS) MINUS COMP ;
COMP := COMP UNION NEW ;
end ;
DISPLAY := COMP ;
Далее приводится последовательное описание этого алгоритма. Перед началом вы-
полнения цикла переменные-отношения NEW и СОМР выглядят так, как показано ниже.
РХ PY
Р1 Р2
Р1 РЗ
СОМР
РХ PY
Р1 Р2
Р1 РЗ
Глава 23. Логические системы управления базами данных
929
После первой итерации эти переменные-отношения примут следующий вид.
NEW РХ PY СОМР РХ PY
Р1 Р4 Р1 Р2
Р1 Р5 Р1 РЗ
Р1 Р4 *
Р1 Р5 *
В конце следующей итерации будет получен окончательный результат.
NEW РХ PY СОМР РХ PY
Р1 Рб Р1 Р2
Р1 РЗ
Р1 Р4
Р1 Р5
Р1 Рб *
На следующей итерации переменная-отношение NEW окажется пустой и выполнение
цикла завершится.
На этом заканчивается краткий обзор стратегий рекурсивного выполнения запросов.
В опубликованной литературе можно найти множество более сложных подходов, однако
их описание явно выходит за рамки этой книги, в которой преследуется совсем другая
цель. Более детально изучить эти подходы и получить все необходимые для их понима-
ния основные сведения можно, обратившись к [23.16]-[23.43].
23.8. Резюме
На этом завершается краткое введение в СУБД, основанные на логике. Хотя рас-
смотренные здесь идеи еше не получили широкого распространения в научном мире,
некоторые из них уже нашли свою реализацию в коммерческих продуктах, в частности
это относится к некоторым методам оптимизации. Определенные потенциальные пре-
имущества этой сравнительно новой концепции, представляющей значительный инте-
рес, описаны в различных разделах данной главы. Однако здесь не было упомянуто
еще одно преимущество: логика может быть использована как основа для поистине
полной интеграции между базами данных и языками программирования общего назна-
чения. Другими словами, вместо не совсем элегантного подхода с применением “внед-
ряемого подъязыка данных” (который используется во многих современных СУБД,
поддерживающих язык SQL) этот подход предполагает наличие единого языка, осно-
ванного на логике. В таком случае “данные являются данными” независимо от того,
хранятся ли они в совместно используемой базе данных или локально по отношению к
некоторому приложению. (Конечно, на пути к этой цели потребуется преодолеть мно-
жество препятствий; и прежде всего весьма важно убедить специалистов в области
информационных технологий в том, что логика может служить основой для создания
языков программирования общего назначения.)
Подытожим сведения, представленные в данной главе. Она начиналась с краткого об-
зора исчисления высказываний и исчисления предикатов с введением некоторых ос-
новных понятий, перечисленных ниже.
930
Часть V. Дополнительные аспекты
Интерпретация набора WFF-формул— это комбинация пространства рассужде-
ний, отображения индивидуальных констант из этих WFF-формул на объекты в
этом пространстве и набора заданных значений для предикатов и функций, содер-
жащихся в этих WFF-формулах.
Модель для набора WFF-формул — это интерпретация, для которой все WFF-
формулы в наборе истинны. В общем случае для данного набора WFF-формул
может существовать любое количество моделей.
Доказательство— это демонстрация того, что данная WFF-формула д
(заключение) является логическим следствием некоторого заданного набора
WFF-формул fl, f2, ..., fn (предпосылок). В качестве примера рассматривался
один из методов доказательства под названием резолюция и унификация.
Затем обсуждался доказательно-теоретический подход к базам данных. При таком
подходе база данных рассматривается как комбинация экстенсиональной и
интенсиональной баз данных. Экстенсиональная база данных содержит основные ак-
сиомы, т.е. данные базы (говоря обобщенно), а интенсиональная — ограничения цело-
стности и дедуктивные аксиомы, т.е. представления (опять же, говоря обобщенно). В
этом случае “смысловое значение” базы данных определяется набором теорем, которые
должны быть выведены из аксиом, а выполнение запроса становится, по крайней мере
концептуально, процессом доказательства теоремы. Дедуктивной СУБД называется
СУБД, в которой поддерживается подобный доказательно-теоретический подход.
Одно совершенно очевидное отличие языка Datalog от традиционных реляционных
языков — возможность поддержки рекурсивных аксиом, а значит, и рекурсивных за-
просов. При этом не существует никаких принципиальных ограничений на расширение
соответствующим образом традиционной реляционной алгебры и исчисления
(см. обсуждение оператора TCLOSE в главе б)6. Также рассматривались некоторые про-
стые методы выполнения таких запросов.
В заключение отметим, что в начале главы было перечислено несколько терминов,
например логическая СУБД, дедуктивная СУБД и т.д., которые часто встречаются в со-
временной научной литературе (а также в рекламных материалах). Для прояснения
смысла этих терминов ниже приводится их краткое описание. Хотя следует заметить, что
единого мнения по этому поводу не существует и в разных публикациях можно встре-
тить совершенно разные определения.
Рекурсивная обработка запросов Этот тип обработки предусматривает анализ и
отчасти оптимизацию запросов, которые по определению являются рекурсивными
1 (см. раздел 23.7).
База знаний. Этот термин иногда используется для так называемой интенсиональной
базы данных, которая содержит правила (ограничения целостности и дедуктивные
аксиомы), тогда как экстенсиональная база данных состоит из собственно данных
базы. Однако многими авторами термин “база знаний” употребляется для обозначе-
ния комбинации экстенсиональной и интенсиональной баз данных, за исключением
-о 6 В этой связи интересно отметить, что в реляционных СУБД все же необходимо (хотя и
неявно) выполнять рекурсивную обработку, поскольку в каталоге может содержаться рекурсив-
но структурированная информация Например, определения одних представлений могут быть
выражены на основе определений других представлений.
Глава 23. Логические системы управления базами данных
931
того, что (как, например, утверждается в [23.10]) “база знаний часто содержит слож-
ные объекты, такие как классические отношения” (см. часть VI, где рассматривают-
ся “сложные объекты”). Наконец, в системах на основе естественных языков этот
термин имеет совсем другое специфическое значение, поэтому, видимо, лучше во-
обще избегать его использования.
Знания. То, что содержится в базе знаний. Исходя из такого определения для объ-
яснения термина “знания” необходимо вернуться к предыдущему абзацу.
Система управления базой знаний. Программное обеспечение, которое управляет
базой знаний. Данный термин обычно используется как синоним дедуктивной
СУБД (см. ниже).
Дедуктивная СУБД. СУБД, в которой предусмотрена поддержка доказательно-
теоретического подхода. В частности, в таких СУБД можно вывести дополнитель-
ную информацию из экстенсиональной базы данных с помощью инференциальных
(т.е. дедуктивных) правил, которые хранятся в интенсиональной базе данных. В де-
дуктивной СУБД почти всегда поддерживаются рекурсивные правила, а это значит,
что возможно выполнение рекурсивных запросов.
Дедуктивная база данных (использовать этот термин нежелательно). База данных,
управляемая дедуктивной СУБД.
Экспертная СУБД. Синоним дедуктивной СУБД.
Экспертная база данных (использовать этот термин нежелательно). База данных,
которая находится под управлением экспертной СУБД.
Инференциальная СУБД. Синоним дедуктивной СУБД.
Система, основанная на логике. Синоним дедуктивной СУБД.
Логическая база данных (использовать этот термин нежелательно). Синоним де-
дуктивной базы данных.
Логика как модель данных. Модель данных состоит из объектов, правил целостно-
сти и операторов. В дедуктивной СУБД все они представлены в одной и той же
форме — как аксиомы логического языка типа Datalog. Действительно, как объяс-
няется в разделе 23.6, база данных в такой системе может рассматриваться как ло-
гическая программа, содержащая аксиомы всех трех видов. Следовательно, можно
утверждать, что в такой системе абстрактная модель данных является логической.
Упражнения
23.1. Используя метод резолюции, определите, являются ли приведенные ниже
метаутверждения правильными доказательствами в исчислении высказываний.
а) А => В, С=>В, Р=>( A OR С), В |-В
б) ( А => В ) AND ( С => D ), ( В => Е AND D => F ),
NOT ( Е AND F ), А => С |- NOT А
в) ( A 0R В ) => D, D => NOT ( Е OR F ), NOT ( В AND С AND Е )
NOT ( G => NOT ( С AND Н ) )
23.2. Преобразуйте следующие WFF-формулы в стандартную форму.
932
Часть V. Дополнительные аспекты
a) FORALL X ( FORALL у
( P ( x, У ) => EXISTS z ( q ( x, z ) ) ) )
6) EXISTS x ( EXISTS у
( p ( x, у ) => FORALL z ( q ( x, Z ) ) ) )
в) EXISTS X ( EXISTS у
( P ( x, у ) => EXISTS z ( q ( x, z ) ) ) )
23.3. Ниже приводится достаточно стандартный пример логической базы данных.
MAN ( 'Adam' )
WOMAN ( 'Eve' )
MAN ( 'Cain' )
MAN ( 'Abel' )
MAN ( 'Enoch' )
PARENT ( 'Adam', 'Cain' )
PARENT ( 'Adam', 'Abel' )
PARENT ( 'Eve', 'Cain' )
PARENT ( 'Eve', 'Abel' )
PARENT ( 'Cain', 'Enoch' )
FATHER ( x, у ) <= PARENT ( x, у ) AND MAN ( x )
MOTHER ( x, у ) <= PARENT ( x, у ) AND WOMAN ( X )
SIBLING ( x, у ) <= PARENT ( z, x ) AND PARENT ( z, у )
BROTHER ( x, у ) <= SIBLING ( x, у ) AND MAN ( x )
SISTER ( X, у ) <= SIBLING ( x, у ) AND WOMAN ( X )
ANCESTOR ( x, у ) <= PARENT ( x, у )
ANCESTOR ( x, у ) <= PARENT ( x, z ) AND ANCESTOR ( z, у )
Используйте метод резолюции, чтобы ответить на следующие запросы.
а) Кто является матерью Каина (' Cain')?
б) Кто является братом или сестрой (Sibling) Каина?
в) Кто является братом (Brother) Каина?
г) Кто является сестрой (Sister) Каина?
д) Кто является наследником (Ancestor) Еноха ('Enoch')?
23.4. Дайте определение терминам интерпретация и модель.
23.5. Напишите набор аксиом языка Datalog только для части определений базы данных
поставщиков, деталей и проектов.
23.6. Запишите на языке Datalog решения для упр. 6.13-6.50, где это возможно.
23.7. Запишите на языке Datalog решения для упр. 8.1, где это возможно.
23.8. Завершите (ради собственного удовольствия) объяснение реализации метода уни-
фикации и резолюции, данное в разделе 23.7, для решения запроса “Найти все ком-
поненты детали с номером 'Р1'”.
Глава 23. Логические системы управления базами данных
933
Список литературы
В последние годы число публикаций в области логических СУБД быстро возраста-
ет, и приведенный ниже список представляет собой лишь малую часть всей имею-
щейся на сегодня литературы. Список включает следующие тематические группы.
Книги [23.1]-[23.9] или посвящены логике в целом (отчасти в контексте вычис-
лений, отчасти в контексте баз данных), или представляют собой сборники ста-
тей именно по логическим СУБД.
Работы [23.10]-[23.12] являются учебными пособиями, как и книги [23.46] и
[23.47].
Работы [23.14], [23.17]-[23.20], [23.30], [23.49] и [23.50] посвящены операции
транзитивного замыкания и ее реализации.
В работах [23.21 ]—[23.24] описана важная методика выполнения рекурсивных
запросов — “магические множества”, а также различные ее варианты.
Замечание. С этим вопросом также связаны публикации [17.24]—[ 17.26].
Остальные публикации демонстрируют масштабность исследований, которые ве-
дутся в этой области. В них описываются дополнительные аспекты этой темы (в
основном, без комментариев).
23.1. Stoll R.R. Sets, Logic and Axiomatic Theories. — San Francisco, Calif.: W.H. Freeman
and Company, 1961.
Представляет собой весьма неплохое введение в логику.
23.2. Manna Z., Waldinger R. The Logical Basis for Computer Programming. Volume I.
Deductive Reasoning (1985); Volume II. Deductive Techniques (1990).— Reading,
Mass.: Addison-Wesley, 1985, 1990.
233. Gray P.M.D. Logic, Algebra and Databases. — Chichester, England: Ellis Horwood Ltd., 1984.
Книга является прекрасным введением в исчисление высказываний и исчисление
предикатов с точки зрения базы данных. В ней также освещены другие темы,
имеющие непосредственное отношение к данной.
23.4. Walker A., McCord М., Sowa J.F., Wilson W.G. Knowledge Systems and Prolog (2nd
ed.). — Reading, Mass.: Addison-Wesley, 1990.
Хотя книга и посвящена логическому программированию в целом, в ней достаточ-
но материала, касающегося логических СУБД в частности.
23.5. Gallaire Н., Minker J. Logic and Data Bases. — New York, N.Y.: Plenum Publishing
Corp., 1978.
Один из первых (если не самый первый) сборников статей по данной теме.
23.6. Kershberg L. (ed.). Expert Database Systems // Proc. 1st Int. Workshop on Expert Database
Systems (Kiawah Island, S.C.). — Menlo Park, Calif.: Benjamin/Cummings, 1986.
Прекрасный сборник статей, располагающих к размышлениям. Однако не все они
непосредственно связаны с темой данной главы. Даже названия разделов вносят
некоторую путаницу в то, что же на самом деле относится “к экспертным системам
баз данных”. Перечислим эти разделы.
1. Теория баз знаний.
2. Логическое программирование и базы данных.
934
Часть V. Дополнительные аспекты
3. Архитектуры экспертных баз данных, инструменты и методы.
4. Логические рассуждения в экспертных системах баз данных.
5. Доступ к интеллектуальным базам данных и взаимодействие с ними.
Кроме того, имеется ведущая статья Джона Смита (John Smith) по экспертным сис-
темам баз данных и отчеты рабочей группы по системам управления базами зна-
ний, логическому программированию и базам данных, объектным системам баз
данных и системам знаний. Как указывает в предисловии редактор этой публика-
ции, концепция экспертной системы базы данных “подразумевает различные опре-
деления и, бесспорно, различные архитектуры”.
23.7. Minker J. (ed.). Foundations of Deductive Databases and Logic Programming. — San
Mateo, Calif.: Morgan Kaufmann, 1988.
23.8. Mylopoulos J., Brodie M.L. (eds). Readings in Artificial Intelligence and Databases. —
San Mateo, Calif.: Morgan Kaufmann, 1988.
23.9. Ullman J.D. Database and Knowledge-Base Systems. В 2-х томах. — Rockville, Md:
Computer Science Press, 1988, 1989.
Одна из десяти глав первого тома целиком посвящена логическим методам. В этой
большой по объему главе (в которой впервые был представлен язык Datalog) обсуж-
дается связь между логической и реляционной алгеброй, а также реляционное исчис-
ление в виде особого случая логического подхода— версии как для доменов, так и
для кортежей. Второй том состоит из семи глав, пять из которых посвящены различ-
ным аспектам логических СУБД.
23.10. Gardarin G., Valduriez Р. Relational Databases and Knowledge Bases.— Reading,
Mass.: Addison-Wesley, 1989.
В книге имеется глава, посвященная дедуктивным системам, в которой не-
смотря на вводный характер изложения содержатся сведения о теории таких
систем, об алгоритмах оптимизации и т.д., причем в гораздо большем объеме,
чем в данной главе.
23.11. Stonebraker М. Introduction to “Integration of Knowledge and Data Management” // M.
Stonebraker (ed.). Readings in Database Systems. — San Mateo, Calif.: Morgan
Kaufmann, 1988.
23.12. Gallaire H., Minker J., Nicolas J.-M. Logic and Databases: A Deductive Approach //
ACM Comp. Surv. — June, 1984. — 16, № 2.
23.13. Dahl V. On Database Systems Development through Logic // ACM TODS. — March,
1982. —7, № 1.
Хорошее и ясное описание идей, лежащих в основе логических СУБД, с примера-
ми, созданными автором на базе языка Prolog в 1977 году.
23.14. Agrawal R. Alpha: An Extension of Relational Algebra to Express a Class of Recursive
Queries // IEEE Transaction on Software Engineering. — July, 1988. — 14, № 7.
Здесь предлагается новый оператор alpha, с помощью которого в рамках традици-
онной реляционной алгебры поддерживается формулировка “большого класса ре-
курсивных запросов” (в действительности— надмножество линейных рекурсив-
ных запросов). Существует мнение, что оператор alpha является достаточно мощ-
ным для решения многих практических проблем, включая рекурсию, и более про-
стым в применении по сравнению с другими общими механизмами рекурсии. В
Глава 23. Логические системы управления базами данных
935
книге приводится несколько примеров его использования. В частности, показано,
как могут обрабатываться задачи транзитивного замыкания и “обобщенных требо-
ваний” (см. соответственно публикацию [23.17] и раздел 23.6).
Материал по этой теме содержится также в публикациях [23.18] и [23.19].
23.15. Reiter R. Towards a Logical Reconstruction of Relational Database Theory // On
Conceptual Modelling: Perspectives from Artificial Intelligence, Databases, and
Programming Languages (eds. M.L. Brodie, J. Mylopoulos, J.W. Schmidt). — New
York, N.Y.: Springer-Verlag, 1984.
Как уже отмечалось в разделе 23.2, хотя работа Рейтера и является первоисточни-
ком в этой области, многие исследователи до него изучали связь между логикой и
базами данных (см., например, [23.5], [23.7] и [23.13]). Однако, по всей вероятно-
сти, именно “логическая реконструкция реляционной теории” значительно повы-
сила интерес к предмету и побудила к активным исследованиям в этой области.
23.16. Bancilhon F., Ramakrishnan R. An Amateur's Introduction to Recursive Query
Processing Strategies 11 Proc. 1986 ACM SIGMOD Int. Conf, on Management of
Data. — Washington, D.C., 1986. (В переработанном виде опубликована в сборнике
М. Stonebraker (ed.). Readings in Database Systems. — San Mateo, Calif.: Morgan
Kaufmann, 1988, а также в [23.8].)
Прекрасный обзор положительных и отрицательных сторон существующих ме-
тодов решения проблемы реализации рекурсивного запроса. Положительно оце-
нивается наличие множества технологий, разработанных для решения этой про-
блемы, а отрицательно — трудности выбора технологии, наиболее подходящей
для конкретной ситуации (в частности, многие технологии представлены без
описания характеристик производительности). После описания основных идей
логических баз данных в статье предлагается множество алгоритмов — наивное
и полунаивное оценивание, итерационные запросы и подзапросы, рекурсивные
запросы и подзапросы, APEX, язык Prolog, алгоритмы Хеншена/Нэкви, Ахо-
Ульмана, Кифера-Лозинского, вычислительный алгоритм, магические множества
и их обобщение. Сравниваются различные подходы на основе домена приложе-
ния (т.е. класса проблем, для которых применяется данный алгоритм), произво-
дительности и простоты их реализации. В статье также приводятся показатели
производительности (со сравнительным анализом), полученные в результате
проверки различных алгоритмов на основе простого теста.
23.17. Ioannidis Y.E. On the Computation of the Transitive Closure of Relational Operators //
Proc. 12th Int. Conf, on Very Large Data Bases. — Kyoto, Japan, August, 1986.
Транзитивное замыкание является операцией фундаментального значения при об-
работке рекурсивного запроса [23.18]. В статье предлагается новый алгоритм реа-
лизации этой операции (основанный на подходе типа “разделяй и властвуй”). Об
этом также речь идет в работах [23.14], [23.18]—[23.20], [23.49], [23.50].
23.18. Jagadish H.V., Agrawal R., Ness L. A Study of Transitive Closure as a Recursion
Mechanism // Proc. 1987 ACM SIGMOD Int. Conf, on Management of Data.— San
Francisco, Calif., May, 1987.
Немного переработанная цитата из аннотации: “В этой статье показано, что каж-
дый линейный рекурсивный запрос может быть выражен в виде транзитивного за-
мыкания, которое начинается и завершается операциями, уже существующими в
936
Часть V. Дополнительные аспекты
реляционной алгебре”. В статье также делается предположение, что для эффектив-
ной реализации линейной рекурсии в общем случае, а значит, и для создания эф-
фективных дедуктивных СУБД для большого класса рекурсивных проблем доста-
точно обеспечить эффективную реализацию транзитивного замыкания.
23.19. Agrawal R., Jagadish Н. Direct Algorithms for Computing the Transitive Closure of
Database Relations // Proc 13th Int. Conf, on Very Large Data Bases. — Brighton, UK,
September, 1987.
Предлагается набор алгоритмов для транзитивного замыкания, которые “не пред-
ставляют задачу как вычисление рекурсии, а получают замыкание, опираясь на ис-
ходные принципы” (отсюда и определение direct — “непосредственный”). В статье
также содержится полезное резюме предыдущих работ по другим алгоритмам.
23.20. Lu Н. New Strategies for Computing the Transitive Closure of a Database Relation П
Proc 13th Int. Conf, on Very Large Data Bases. — Brighton, UK, September, 1987.
Приводится описание других алгоритмов транзитивного замыкания. Так же, как и
в [23.19], в этой статье содержится полезный обзор разработанных ранее подходов
к рассматриваемой проблеме.
23.21. Bancilhon F., Maier D., Sagiv Y., Ullman J.D. Magic Sets and Other Strange Ways to
Implement Logic Programs // Proc. 5th ACM SIGMOD-SIGFACT Symposium on
Principles of Database Systems, 1986.
Основная идея “магических множеств” заключается в динамическом введении но-
вого набора “магических” правил, которые гарантируют получение того же резуль-
тата, что и оригинальный запрос, но гораздо эффективнее за счет сокращения чис-
ла “необходимых фактов” (см. раздел 23.7). Изложение подробностей несколько
сложно для восприятия и выходит за рамки данного комментария. Читателю пред-
лагается прочесть эту статью или обратиться к работам [23.9], [23.10], [23.16],
чтобы получить более подробные сведения. Однако следует отметить, что сущест-
вуют также многочисленные варианты этой основной идеи [23.22]-[23.24]. Кроме
того, следует учесть работы [ 17.24]—[ 17.26], указанные в главе 17.
23.22. Beeri С., Ramakrishnan R. On the Power of Magic // Proc. 6th ACM SIGMOD-
SIGFACT Symposium on Principles of Database Systems, 1987.
23.23. Sacca D., Zaniolo C. Magic Counting Methods // Proc. 1987 ACM SIGMOD Int. Conf,
on Management of Data. — San Francisco, Calif., May, 1987.
23.24. Gardarin G. Magic Functions: A Technique to Optimize Extended Datalog Recursive Programs //
Proc. 13th Int. Conf, on Very Large Data Bases. — Brighton, UK, September, 1987.
23.25. Aho A., Ullman J.D. Universality of Data Retrieval Languages // Proc. 6th ACM
Symposium on Principles of Programming Languages. — San Antonio, Texas, 1979.
Для данной последовательности отношений R, f(R), f(f(R)),... (где f— некоторая фик-
сированная функция) крайней точкой неизменности называется отношение R*, выве-
денное в соответствии со следующим алгоритмом наивного оценивания (см. раздел 23.7).
R* := R ;
do until R* stops growing ;
/* выполнять, пока R* не достигнет "точки неизменности" */
R* := R* UNION f(R*) ;
end ;
Глава 23. Логические системы управления базами данных
937
В этой статье описывается дополнение реляционной алгебры понятием “крайняя
точка неизменности”.
23.26. Ullman J.D. Implementation of Logical Query Languages for Databases // ACM
TODS. — September, 1985. — 10, № 3.
Описывается важный класс технологий реализации возможных рекурсивных запросов.
Методы определены в терминах “правил сбора” на “деревьях правил/целей”, которые
являются графами, представляющими некоторую стратегию запроса в терминах пред-
ложений и предикатов. В статье определено несколько таких правил: одно из них соот-
ветствует приложению операторов реляционной алгебры, два больше соответствуют
прямому формированию цепочки, а “косвенное” правило позволяет передавать резуль-
таты от одной подцели к другой. Косвенная передача информации затем становится ос-
новой для так называемых методов магических множеств [23.21 ]—[23.24].
23.27. Tsur S., Zaniolo С. LDL: A Logic-Based Data-Language // Proc. 12th Int. Conf, on Very
Large Data Bases. — Kyoto, Japan, August, 1986.
Язык LDL включает генератор типа “множества”, отрицание (основанное на раз-
личиях множеств), операции определения данных и операции обновления. Это
язык логического типа (нет никаких зависимостей упорядочения между утвержде-
ниями), причем компилируемый, а не интерпретируемый. Материал по этой теме
можно также найти в [23.45].
23.28. Bancilhon F. Naive Evaluation of Recursive Defined Relations // M. Brodie and J.
Mylopoulos (eds): On Knowledge Base Management Systems: Integrating Database and
Al Systems. — New York, N.Y.: Springer-Verlag, 1986.
23.29. Lozinskii E.L. A Problem-Oriented Inferential Database System // ACM TODS.—
September, 1986. — 11, № 3.
Первоисточник концепции “необходимых фактов”. В статье описывается прототип
системы, в которой применяется экстенсиональная база данных для компенсации
очень быстрого расширения поискового пространства вследствие использования
инференциальных технологий.
23.30. Rosenthal A. et al. Traversal Recursion: A Practical Approach to Supporting Recursive
Applications // Proc. 1986 ACM SIGMOD Int. Conf, on Management of Data.—
Washington, D.C., June, 1986.
23.31. Gardarin G., De Maindreville C. Evaluation of Database Recursive Logic Programs as
Recurrent Function Series // Proc. 1986 ACM SIGMOD Int. Conf, on Management of
Data. — Washington, D.C., June, 1986.
23.32. Raschid L., Su S.Y.W. A Parallel Processing Strategy for Evaluating Recursive Queries
// Proc. 12th Int. Conf, on Very Large Data Bases. — Kyoto, Japan, August, 1986.
23.33. Spyratos N. The Partition Model: A Deductive Database Model // ACM TODS. —
March, 1987. — 12, № 1.
23.34. Han J., Henschen L.J. Handling Redundancy in the Processing of Recursive Queries //
Proc. 1987 ACM SIGMOD Intern. Conf, on Management of Data.— San Francisco,
Calif., May, 1987.
23.35. Zhang W., Yu C.T. A Necessary Condition for a Double Recursive Rule to be Equivalent
to a Linear Recursive Rule // Proc. 1987 ACM SIGMOD Intern. Conf, on Management
of Data. — San Francisco, Calif., May, 1987.
938
Часть V. Дополнительные аспекты
23.36. Nejdl W. Recursive Strategies for Answering Recursive Queries — The RQA/FQI Strategy
// Proc. 13th Intern. Conf, on Very Large Data Bases. — Brighton, UK, September, 1987.
23.37. Whang K.-Y., Navathe S.B. An Extended Disjunctive Normal Form Approach for
Optimizing Recursive Logic Queries in Loosely Coupled Environments // Proc. 13th
Intern. Conf, on Very Large Data Bases. — Brighton, UK, September, 1987.
23.38. Naughton J.F. Compiling Separable Recursions // Proc. 1988 ACM SIGMOD Int. Conf,
on Management of Data. — Chicago, Ill., June, 1988.
23.39. Youn C., Henschen L.J., Han J. Classification of Recursive Formulas in Deductive
Databases 11 Proc. 1988 ACM SIGMOD Int. Conf, on Management of Data. — Chicago,
Ill., June, 1988.
23.40. Ceri S., Gottlob G., Lavazza L. Translation and Optimization of Logic Queries: The Algebraic
Approach // Proc. 12th Int. Conf, on Very Large Data Bases. — Kyoto, Japan, August, 1986.
23.41. Ceri S., Tanca L. Optimization of Systems of Algebraic Equations for Evaluating
Datalog Queries // Proc. 13th Int. Conf, on Very Large Data Bases. — Brighton, UK,
September, 1987.
23.42. Van Gelder A. A Message Passing Framework for Logical Query Evaluation // Proc. 1986
ACM SIGMOD Int. Conf, on Management of Data. — Washington, D.C., June, 1986.
23.43. Wolfson O., Silberschatz A. Distributed Processing of Logic Programs // Proc. 1988
ACM SIGMOD Int. Conf, on Management of Data. — Chicago, Ill., June, 1988.
23.44. Naughton J.F. et al. Efficient Evaluation of Right-, Left-, and Multi-Linear Rules // Proc.
1989 ACM SIGMOD Int. Conf, on Management of Data. — Portland, Ore., June, 1989.
23.45. Naqvi S., Tsur S. A Logical Language for Data and Knowledge Bases. — New York.,
N.Y.: Computer Science Press, 1989.
Эта книга полностью посвящена языку LDL [23.27].
23.46. Ceri S., Gottlob G., Tanca L. Logic Programming and Databases. — New York, N.Y.:
Springer-Verlag, 1990.
23.47. Das S.K. Deductive Databases and Logic Programming. — Reading, Mass.: Addison-
Wesley, 1992.
23.48. Kifer M., Lozinskii E. On Compile-Time Query Optimization in Deductive Databases by
Means of Static Filtering // ACM TODS. — September, 1990. — 15, № 3.
23.49. Agrawal R., Dar S., and Jagadish H.V. Direct Transitive Closure Algorithms: Design and
Performance Evaluation // ACM TODS. — September, 1990. — 15, № 3.
23.50. Jagadish H.V. A Compression Method to Materialize Transitive Closure // ACM
TODS. — December, 1990. — 15, № 4.
Предлагается технология индексирования, которая позволяет сохранить транзи-
тивное замыкание данного отношения в сжатой форме таким образом, чтобы мож-
но было выполнить тестирование и узнать с помощью одной справочной таблицы с
индексом, будет ли данный кортеж находиться в замыкании.
23.51. Abiteboul S., Grumbach S. A Rule-Based Language with Functions and Sets // ACM
TODS. — March, 1991. — 16, № 1.
, Описывается “язык сложных объектов” (“complex object language” — COL), koto-
, рый является расширением языка Datalog с интеграцией идеи дедуктивных и объ-
ектно-ориентированных баз данных.
Глава 23. Логические системы управления базами данных
939
Ответы к некоторым упражнениям
23.1. а — правильное, б— правильное, в— неправильное.
23.2. В приведенных ниже выражениях а, Ь и с являются константами Сколема, a f —
функцией Сколема.
а) Р ( х, у ) => q ( х, f ( х, у ) )
б) р ( a, b ) => q ( a, z )
в) р ( a, b ) => q ( а, с )
23.6. В соответствии с обычной практикой перечисленные ниже решения обозначаются
как 23.6.л, где л — номер оригинального упражнения в главе 6.
23.6.13. ? <= J ( j, jnt jc )
23.6.14. ? <= J ( j, jn, 'London' )
23.6.15. RES ( s ) <= SPJ ( s, p, 'JI' )
? <= RES ( s )
23.6.16. ? <= SPJ ( s, p, j, q ) AND 300 < q AND q < 750
23.6.17. RES ( pl, pc ) <= P ( pt pn, pl, w, pc )
? <= RES ( pl, pc )
23.6.18. RES ( s, p, j ) <= S ( s, sn, st, c ) AND
P ( Pt Pnt Pit W, c ) AND
J ( j, jn, c )
? <= RES ( s, p, j )
23.6.19- 23.6.20. He может быть выполнено без операции отрицания.
23.6.21. RES ( р ) <= SPJ ( s, р, j, q ) AND
S ( s, sn, st, 'London' )
? <= RES ( p )
23.6.22. RES ( p ) <= SPJ ( s, p, j, q ) AND
S ( s, sn, st, 'London' ) AND
J ( j, jn, 'London' )
? <= RES ( p )
23.6.23. RES ( cl, c2 ) <= SPJ ( s, p, j, q ) AND
S ( s, sn, st, cl ) AND
J ( j, jn, c2 )
? <= RES ( cl, c2 )
23.6.24. RES ( p ) <= SPJ ( s, p, j, q ) AND
S ( s, sn, st, c ) AND
J ( j, jn, c )
? <= RES ( p )
23.6.25. He может быть выполнено без операции отрицания.
23.6.26. RES ( pl, р2 ) <= SPJ ( s, pl, jl, ql ) AND
S ( s, p2, j2, q2 )
? <= RES ( pl, p2 )
940
Часть V. Дополнительные аспекты
23.6.27- 23.6.30. Не может быть выполнено без функций группирования и функций
обобщения.
23.6.31. RES ( jn ) <= J ( j, jn, jc ) AND
SPJ ( 'SI', p, j, q )
? <= RES ( jn )
23.6.32. RES ( pl ) <= P ( p, pn, pl, w, pc ) AND
SPJ ( 'SI', p, j, q )
? <= RES ( pl )
23.6.33. RES ( p ) <= P ( p, pn, pl, W, pc ) AND
SPJ ( s, p, j, q ) AND
J ( j, jn, 'London' )
? <= RES ( p )
23.6.34. RES ( j ) <= SPJ ( S, p, j, q ) AND
S ( 'SI', p, j2, q2 )
? <= RES ( j )
23.6.35. RES ( s ) <= SPJ ( s, p, j, q ) AND
SPJ ( s2, p, j2, q2 ) AND
SPJ ( s2, p2, j3, q3 ) AND
p ( p2, pn, 'Red', w, c )
? <= RES ( s )
23.6.36. RES ( s ) <= s ( s, sn, st, c ) AND
S ( 'SI', snl, stl, cl ) AND st < stl
? <= RES ( s )
23.6.37-23.6.39. He может быть выполнено без функций группирования и функций
обобщения.
23.6.40- 23.6.44. He может быть выполнено без операции отрицания.
23.6.45. RES ( с ) <= S ( s, sn, st, с )
RES ( с ) <= Р ( р, pn, pl, w, с )
RES ( с ) <= J ( j, jn, с )
? <= RES ( с )
23.6.46. RES ( р ) <= SPJ ( s, р, j, q ) AND
S ( s, sn, st, 'London' )
RES ( p ) <= SPJ ( s, p, j, q ) AND
J ( j, jn, 'London' )
? <= RES ( p )
23.6.47- 23.6.48. He может быть выполнено без операции отрицания.
23.6.49- 23.6.50. Не может быть выполнено без операций группирования.
23.7. Покажем ограничения как обычные следствия, вместо того чтобы применять
“обратный” стиль, используемый в языке Datalog.
a) CITY ( 'London' )
CITY ( 'Paris' )
CITY ( 'Rome' )
Глава 23. Логические системы управления базами данных
941
CITY ( 'Athens' )
CITY ( 'Oslo' )
CITY ( 'Stockholm
CITY ( ; 'Madrid' )
CITY I ' 'Amsterdam
S ( s, sn, st, c ) => CITY ( c )
P ( Pl pn, pc, pw, c ) => CITY ( c )
J ( j, jn, c ) => CITY ( c )
б) He может быть выполнено без соответствующих скалярных операторов.
в) Р ( р, pn, 'Red', pw, с ) => pw < 50
г) Не может быть выполнено без операторов отрицания и обобщения.
д) S ( si, snl, stl, 'Athens' ) AND
S ( s2, sn2, st2, 'Athens' ) => si = s2
e) He может быть выполнено без операторов группирования и обобщения,
ж) Не может быть выполнено без операторов группирования и обобщения.
з) J ( ji jn, с ) => S ( s, sn, st, с )
и) J ( jt jn, с ) => SPJ ( s, p, j, j ) AND S ( s, sn, st, c )
к) P ( pl, pnl, pll, pwl, pci ) => P ( p2, pn2, 'Red', pw2, pc2 )
л) He может быть выполнено без операторов обобщения.
м) S ( s, sn, st, 'London' ) => SP ( s, 'P2', g )
н) P ( pl, pnl, pll, pwl, pci) =>
P ( p2, pn2, 'Red', pw2, pc2 ) AND pw2 < 50
о) He может быть выполнено без операторов обобщения.
п) Не может быть выполнено без операторов обобщения.
р) Не может быть выполнено (это ограничение перехода).
с) Не может быть выполнено (это ограничение перехода).
942
Часть V. Дополнительные аспекты
Часть VI
Объектные и объектно-
реляционные базы
данных
Объектная технология является важной областью в сфере разработки программного
обеспечения в целом. Поэтому возникает естественный вопрос, важна ли эта технология,
в частности, в сфере управления базами данных, и если важна, то какова ее значимость
для этой сферы. Единого мнения, однако, по этому вопросу пока нет! Одни авторитетные
источники считают, что в недалеком будущем объектные системы баз данных получат
признание во всем мире и полностью заменят реляционные системы. Другие же полага-
ют, что объектные системы подходят лишь для определенного, очень ограниченного
круга задач и никогда не займут сколько-нибудь значительную часть рынка баз данных.
Совсем недавно начали появляться системы, поддерживающие “третий путь”: они объе-
диняют объектную и реляционную технологии и пытаются везде поспеть. В двух главах
этой заключительной части книги приведенный выше вопрос рассматривается достаточ-
но глубоко: в главе 24 обсуждаются чисто объектные системы, а в главе 25 — более но-
вые объектно-реляционные системы.
943
Глава
Объектные базы данных
24.1. Введение
Большой интерес представляют результаты исследований, полученные за последнее деся-
тилетие в области объектно-ориентированных систем баз данных (или сокращенно — объ-
ектных систем). Некоторые специалисты рассматривают объектные системы как серьезного
конкурента реляционных систем (или, во всяком случае, конкурента SQL-систем), и если не в
полном объеме, то по крайней мере для определенных приложений. В этой главе подробно
рассматриваются объектные системы. Сначала мы познакомимся с основными объектными
концепциями, а затем основательно их проанализируем и предоставим некоторые выводы от-
носительно перспектив включения этих концепций в системы баз данных в будущем.
Почему же возник такой большой интерес к объектным системам? Общеизвестно, что
уже ставшие классическими SQL-системы несовершенны во многих отношениях. И не-
которые специалисты — но не автор этой книги! — считают, что и теория (т.е. реляци-
онная модель), которая служит основой для таких систем, также не отвечает современ-
ным требованиям. Как бы то ни было, некоторые из новых возможностей, которые счи-
таются необходимыми в современных СУБД, уже много лет существуют в объектно-
ориентированных языках программирования, например в C++ и Smalltalk. И, вполне ес-
тественно, возникла идея внедрить эти возможности в системы баз данных, что и было
сделано многими исследователями и несколькими производителями СУБД.
Таким образом, объектные системы берут свое начало от объектно-ориентированных
языков программирования. Основная идея, объединяющая эти две области, состоит в
том, чтобы оградить пользователя от конструкций, связанных с аппаратным обеспечени-
ем, таких как биты и байты (или даже записи и поля). Вместо этого пользователь имеет
дело с объектами и операциями над этими объектами, которые больше соответствуют
своим аналогам в реальном мире. Например, используя традиционные термины, можно
представлять отдел, как “кортеж DEPT” с набором соответствующих “кортежей ЕМР”, т.е.
сотрудников, которые имеют “значения внешних ключей”, “ссылающихся” на “значение
первичного ключа” в “кортеже DEPT”. В новой технологии пользователь будет иметь де-
ло с объектом отдела, который содержит соответствующее множество объектов со-
трудников. И вместо выполнения операции “вставки” “кортежа” в “переменную-
отношение ЕМР” с соответствующим “значением внешнего ключа”, “указывающего” на
“значение первичного ключа” некоторого “кортежа” в “переменной-отношении DEPT”,
пользователь может непосредственно “принять” сотрудника (представленного объек-
том) на работу в отдел (также представленный соответствующим объектом). Иначе гово-
ря, фундаментальная идея объектного подхода — повышение уровня абстракции.
Безусловно, повышение уровня абстракции — цель чрезвычайно привлекательная, и
объектные понятия успешно использовались для ее достижения в сфере языков про-
граммирования [24.15]. Поэтому возникает естественный вопрос, можно ли те же поня-
944
Часть VI. Объектные и объектно-реляционные базы данных
тия применить в области баз данных. Действительно, с точки зрения пользователя, рабо-
та со “сложными объектами”, например, представляющими отделы, которые “знают,
как” принять нового сотрудника, сменить менеджера или урезать бюджет, выглядит бо-
лее привлекательной (по крайней мере на первый взгляд), чем необходимость опериро-
вать понятиями “переменная-отношение”, “вставка кортежа”, “внешний ключ” и т.п.
Однако здесь необходимо сделать следующее предостережение. Несмотря на то что
между языками программирования и теорией управления базами данных, бесспорно,
имеется много общего, в некоторых весьма важных аспектах они все же различаются. В
частности, укажем на следующие различия.
Прикладная программа по определению предназначена для решения некоторых
конкретных задач.
База данных (опять же, по определению) предназначена для решения множества
различных задач, формулировка которых может быть даже неизвестна в момент
создания базы данных.
Поэтому в среде программирования, предназначенной для разработки отдельных при-
ложений, включение в сложные объекты дополнительной “интеллектуальности”, очевидно,
является разумным решением. За счет этого сокращается объем кода, который должен
быть написан программистом при использовании этих объектов. В результате повышается
продуктивность работы программиста, упрощается сопровождение готового приложения и
т.д. Для среды баз данных, напротив, дополнительная интеллектуальность в одних ситуаци-
ях может оказаться полезной, а в других — нет. Это может упростить одни задачи, но в то
же время усложнить или даже сделать невозможным решение других задач.
(Кстати, точно такой же аргумент может быть использован против дореляционных
СУБД наподобие системы IMS. Объект отдела, содержащий набор объектов сотрудни-
ков, концептуально очень похож на иерархию системы IMS, в которой “родительские
сегменты” отделов содержали подчиненные “дочерние сегменты” сотрудников. Такая
иерархия весьма удобна для выполнения запросов наподобие “Найти сотрудников, кото-
рые работают в бухгалтерии”, но не очень удобна для выполнения запросов типа “Найти
отделы, в которых принимают на работу сотрудников, окончивших бизнес-колледж”. Та-
ким образом, многие аргументы, высказанные против иерархического подхода в 70-х го-
дах, применимы и теперь в контексте объектно-ориентированного подхода.)
Несмотря на приведенные выше замечания, по-прежнему бытует мнение о том, что
объектные системы являются большим шагом вперед на пути развития технологий
управления базами данных. В частности, считается, что объектные технологии весьма
перспективны для “комплексных” приложений в следующих областях:
системы автоматизированного проектирования и автоматизированного управле-
ния производством;
системы комплексного автоматизированного управления технологическими про-
цессами;
системы автоматизированной разработки программного обеспечения;
геоинформационные системы;
наука и медицина;
системы хранения и поиска документов и т.д.
Глава 24. Объектные базы данных
945
(Отметим, что выше перечислены те области, в которых применение традиционных
SQL-продуктов сопряжено со значительными трудностями.) В последние годы на эту
тему опубликовано огромное количество технических статей, а также выпущено не-
сколько соответствующих коммерческих продуктов.
В данной главе основное внимание уделяется объектной технологии в целом.
Поэтому необходимо представить наиболее важные концепции объектного подхо-
да и, в частности, рассмотреть эти концепции с точки зрения перспективы при-
менения для управления базами данных (заметим, что большая часть имею-
щихся публикаций посвящена перспективам применения объектного подхода для
программирования). Данная глава имеет определенную структуру. В следующем
подразделе представлен специальный пример, наглядно демонстрирующий неспо-
собность современных реляционных продуктов удовлетворительно решать неко-
торые задачи, в результате чего у объектной технологии появляется шанс предос-
тавить лучший вариант решения этой задачи. Затем, в разделе 24.2, предлагается
обзор объектов, классов, сообщений и методов, а в разделе 24.3 уделяется внима-
ние некоторым особенностям этих понятий, а также подробно обсуждается их со-
держание. В разделе 24.4 представлен достаточно простой пример. В разделе 24.5
обсуждаются некоторые дополнительные вопросы. И наконец, в разделе 24.6 под-
водятся итоги обсуждения темы главы.
В заключение сделаем следующее замечание. Вопреки тому, что объектные системы
изначально предназначались для создания “сложных” приложений, таких как
САПР/АСУТП, в дальнейшем для краткости и простоты изложения будут рассматри-
ваться только очень простые примеры (отделы и сотрудники и т.п.). При этом такой уп-
рощенный подход нисколько не уменьшает значимости объектной технологии; во всяком
случае, если объектные базы данных работают хорошо, они должны легко справляться и
с “простыми” задачами.
Специальный пример
Рассмотрим простой пример, предложенный Стоунбрейкером (Stonebraker) и описан-
ный автором этой книги в [24.17]. Данный пример иллюстрирует некоторые проблемы,
присущие современным SQL-продуктам. База данных, которая может рассматриваться
как существенно упрощенная версия базы данных САПР/АСУТП, содержит сведения о
прямоугольниках, заданных в такой системе координат, оси X и Y которой параллельны
сторонам этих прямоугольников, т.е. все их стороны либо вертикальные, либо горизон-
тальные. Следовательно, каждый прямоугольник может быть уникальным образом пред-
ставлен с помощью координат (xl,yl) и (х2, у2) нижнего левого и верхнего правого уг-
лов соответственно (рис. 24.1). На языке SQL это определение можно записать с помо-
щью следующего оператора.
CREATE TABLE RECTANGLE
( XI ... , Yl ... , X2 ... , Y2 ... , ... ,
UNIQUE ( Xl, Yl, X2, Y2 ) ) ;
Теперь рассмотрим запрос “Найти все прямоугольники, которые покрывают какую-
нибудь область квадрата (0, 0, 1, 1)” (рис. 24.2).
946
Часть VI. Объектные и объектно-реляционные базы данных
Рис. 24.1. Прямоугольник с координатами Рис. 24.2. Квадрат с координатами (О, О,
(xl, х2, yl, у2) 1, 1)
“Очевидная” формулировка этого запроса на языке SQL может быть представлена
следующим образом.
SELECT ...
FROM RECTANGLES
WHERE ( Xl >= 0 AND Xl <= 1 AND Yl >= 0 AND Yl <= 1 )
— нижний левый угол внутри квадрата
OR ( Х2 >= О AND Х2 <= 1 AND Y2 >= О AND Y2 <= 1 )
— верхний правый угол внутри квадрата
OR ( XI >= О AND XI <= 1 AND Y2 >= О AND Y2 <= 1 )
— верхний левый угол внутри квадрата
OR ( Х2 >= О AND Х2 <= 1 AND Yl >= О AND Yl <= 1 )
— нижний правый угол внутри квадрата
OR ( XI <= О AND Х2 >= 1 AND Yl <= О AND Y2 >= 1 )
- - прямоугольник полностью помещается в квадрат
OR ( XI <= О AND Х2 >= 1 AND Yl >= О AND Yl <= 1 )
— нижний край пересекает квадрат
OR ( XI >= О AND XI <= 1 AND Yl <= О AND Y2 >= 1 )
- - левый край пересекает квадрат
OR ( Х2 >= О AND Х2 <= 1 AND Yl <= О AND Y2 >= 1 )
- - правый край пересекает квадрат
OR ( XI <= О AND Х2 >= 1 AND Y2 >= О AND Y2 <= 1 ) ;
- - верхний край пересекает квадрат
(Упражнение. Убедитесь в том, что эта формулировка действительно корректна.)
Однако нетрудно догадаться, что данный запрос можно сформулировать и в более
простой форме.
SELECT ...
FROM RECTANGLES
WHERE ( Xl <= 1 AND Yl <= 1
-- нижний левый угол находится ниже и левее точки (1,1)
AND Х2 >= О AND Y2 >= 0 ) ;
— верхний правый угол находится выше и правее точки (0,0)
Глава 24. Объектные базы данных
947
(В упр. 24.3 в конце главы предлагается убедиться, что эта формулировка также
корректна.)
Возникает вопрос, может ли системный оптимизатор преобразовать исходную длин-
ную форму запроса в соответствующую ему краткую форму. Иначе говоря, предполо-
жим, что пользователь выражает запрос в “очевидной” (и, очевидно, неэффективной)
длинной форме. Может ли система перед выполнением запроса сократить его формули-
ровку, сделав ее более эффективной? В [24.17] приведено доказательство того, что это
почти всегда невозможно, по крайней мере оптимизаторы современных коммерческих
продуктов такой возможностью не обладают.
В любом случае, несмотря на то что краткая формулировка “более эффективна”, ее
производительность может оказаться неприемлемо низкой в большинстве современных
реляционных продуктов, в которых используются обычные структуры памяти, например
индексы в виде В-деревьев. (В среднем, система будет проверять 50% элементов индекса
для каждой из координат Xl, Х2, Y1 и Y2.)
Таким образом, можно утверждать, что современные реляционные продукты дейст-
вительно несовершенны в некоторых отношениях. Точнее говоря, проблемы, подобные
описанной выше, иллюстрируют, что в этих продуктах некоторые “простые” запросы
пользователя неоправданно сложно формулируются и выполняются с неприемлемо низ-
кой производительностью. Именно эти соображения послужили основным побудитель-
ным мотивом для развития объектных систем.
Замечание. В главе 25 (раздел 25.1) будет приведено “эффективное” решение задачи
о прямоугольниках.
24.2. Объекты, классы, методы и сообщения
Ниже представлены некоторые основные термины и концепции объектного подхода,
а именно — сами объекты (естественно), объектные классы, методы и сообщения. Там,
где это возможно и уместно, данные понятия сравниваются с более знакомыми понятия-
ми. Фактически в весьма приблизительной форме объектную терминологию вполне
можно соотнести с терминологией традиционного программирования (рис. 24.3).
Объектный термин Традиционный термин
неизменяемый объект изменяемый объект объектный класс метод сообщение значение переменная тип данных оператор вызов оператора
Рис. 24.3. Объектная терминология (сводка)
Предупреждение. Прежде чем перейти к подробному освещению данной темы, необ-
ходимо предупредить читателя, что впредь не следует ожидать точности изложения, при-
сущей реляционной теории. Действительно, многие объектные концепции (или их опуб-
ликованные определения) выражены не очень точно, относительно формулировки их оп-
ределений единства мнений не достигнуто и разногласия возникают даже по фундамен-
948
Часть VI. Объектные и объектно-реляционные базы данных
тальным вопросам (в этом можно убедиться, прочитав работы [24.11], [24.48] и [24.52]).
Например, не существует абстрактной, формально определенной “объектной модели
данных”, нет согласия даже в отношении неформальной модели. (Поэтому в данной кни-
ге термин “объектная модель” приводится в кавычках.) Также, как это ни странно, нет
четкого разграничения между уровнями абстракции, в частности (ключевого!) разграни-
чения между самой моделью и ее реализацией. Напомним, что в главе 1 описано, в чем
заключается различие между этими концепциями.
Читателя следует также предупредить о том, что, исходя из сказанного выше, опреде-
ления и объяснения, предложенные в этой главе, не являются универсальными, а также
не обязательно полностью соответствуют принципу работы всех реальных объектных
систем. Действительно, почти все предлагаемые здесь определения и толкования могут
быть подвергнуты (и, вероятно, будут подвергнуты) критике со стороны специалистов.
Обзор объектной технологии
Вопрос: Что такое объект? Ответ: Все что угодно!
Основной догмат объектного подхода — “объектом может быть все что угодно” (или
иногда говорят “все что угодно — объект первого класса”). Одни объекты являются не-
изменяемыми; в качестве примера можно привести числа (например, 3, 42) и символь-
ные строки (например, “Mozart”, “Экономика и бизнес”). Другие объекты — изменяе-
мые; примерами могут служить объекты, представляющие отделы и служащих, которые
упоминались в начале раздела 24.1. Согласно традиционной терминологии неизменяе-
мые объекты соответствуют значениям, а изменяемые — переменным^ с произвольной
внутренней сложностью (т.е. такие объекты могут содержать любое количество типов
данных, имеющихся в обычных языках программирования, и конструкторов этих ти-
пов — чисел, строк, списков, массивов, стеков и т.д.).
Замечание. В некоторых системах термин объект употребляется только для изменяемо-
го объекта, а термин значение, или иногда литерал, — для неизменяемого объекта. Даже в
тех системах, в которых термин “объект” используется как в первом, так и во втором слу-
чаях, следует помнить о том, что неформально, за исключением особо оговоренных ситуа-
ций, под ним подразумевается изменяемый объект, если явно не указано обратное.
Каждый объект имеет тип (в объектной терминологии — класс). Отдельные объекты
иногда называются экземплярами объектов, чтобы их можно было отличить от соответ-
ствующего объектного типа или класса. Обратите внимание, что термин тип здесь ис-
пользуется в смысле, принятом в традиционном программировании (как в главе 5), в ча-
стности этот термин включает в себя и набор операторов (в объектной терминологии —
методов), которые могут применяться для объектов данного типа.
Замечание. На самом деле в некоторых объектных системах понятия типов и классов
различаются. Такие системы кратко будут рассмотрены в разделе 24.3; однако пока мы
будем использовать эти понятия как взаимозаменяемые.
Объекты инкапсулированы. Это означает, что физическое представление, т.е. внутрен-
няя структура объекта, например объекта DEPT (Отдел), остается скрытой от пользователей. В
действительности пользователю известно только то, что объект в состоянии выполнять неко-
1 Заметим, однако, что термин переменная без дополнительного уточнения в объектном
контексте часто используется для обозначения такой переменной, которая содержит иденти-
фикатор объекта (о чем пойдет речь далее в этом разделе).
Глава 24. Объектные базы данных
949
торые операции (“методы”)2. Например, к объектам DEPT могут применяться методы
HIRE_EMP (Нанять сотрудника), FIRE_EMP (Уволить сотрудника), CUT_BUDGET (Урезать бюджет)
и т.д. Также обратите внимание, что к данным объектам могут применяться ТОЛЬКО те
операции, которые упомянуты среди этих методов. Доступ к внутреннему представлению
таких объектов разрешен только коду, с помощью которого эти методы реализованы, т.е.,
употребляя жаргон, можно сказать, что эти и только эти методы могут “взломать инкапсули-
рованный объект”3, если, конечно, данный код также невидим для пользователей.
Преимущество инкапсуляции состоит в том, что она позволяет изменять внутреннее
представление объектов, исключая необходимость переделывать приложения, в которых
эти объекты используются. Конечно, это возможно при условии, что любое такое изме-
нение внутреннего представления сопровождается соответствующим изменением кода, с
помощью которого реализуются применяемые к объекту методы. Иначе говоря, инкап-
суляция подразумевает физическую независимость данных.
Теперь опишем инкапсуляцию в терминах независимости данных, что имеет смысл с
точки зрения баз данных, хотя в литературе по объектной технологии это понятие обыч-
но описывается иначе. Мы определим инкапсулированные объекты как имеющие за-
крытую память и открытый интерфейс.
Закрытая память состоит из переменных экземпляра, которые также иногда
называются членами или атрибутами. Их значения представляют внутреннее со-
стояние данного объекта. В истинно объектной системе переменные экземпляра
являются полностью защищенными и скрытыми от пользователей, однако, как
было сказано выше, они доступны для методов. Здесь следует добавить, что мно-
гие объектные системы не являются “чистыми” в этом смысле, поскольку разре-
шают пользователям доступ к некоторым переменным экземпляра. К этому во-
просу мы еще возвратимся в следующем подразделе.
. 2 В литературе много путаницы связано с понятием инкапсуляции. Точка зрения, которая
кажется наиболее разумной и которая предлагается в настоящей книге, формулируется так.
Говорят, что объект инкапсулирован, если и только если это скаляр в смысле, подразумеваемом
в главе 5 (т.е. если и только если он не имеет никаких видимых пользователем компонентов); по-
этому инкапсулированный объект и скаляр означают одно и то же. Отметим, что определен-
ные "коллекции” объектов (см. раздел 24.3), бесспорно, не являются скалярами, поэтому соглас-
но предыдущему определению они не инкапсулированы. Некоторые авторы, напротив, категори-
чески утверждают, что все объекты инкапсулированы, и такая точка зрения неизбежно приво-
дит к определенным противоречиям. Остальные же считают, что, кроме требования, чтобы
внутренняя структура была скрыта, это понятие подразумевает еще и требование, чтобы со-
ответствующие методы были физически связаны с объектом или классом данного объекта, т.е.
физически являлись его частью. Мы считаем, что в последней трактовке смешиваются понятия
модели и ее реализации. И это, конечно, еще одна причина, по которой, как указывалось в главе 5,
мы предпочли бы совсем не использовать термин "инкапсулированный”. Однако в данной главе
мы все же будем вынуждены время от времени к нему обращаться.
3 Мы бы рекомендовали следовать более строгим требованиям, приведенным в [3.3]. Допус-
тимы только выборки и операторы THE (см. главу 5), которым разрешено нарушать инкапсу-
ляцию в этом смысле. Все другие операторы должны быть реализованы в терминах данных вы-
борок и операторов THE . Иными словами, используется защита кода. Но в объектных системах
обычно предоставляются не операторы THE как таковые, а операторы "get and set” (получить
и установить), которые не являются их точными аналогами (см. раздел 24.4 и статью [24.22]).
950
Часть VI. Объектные и объектно-реляционные базы данных
Открытый интерфейс состоит из определений интерфейсов для методов данного
объекта. Эти определения соответствуют тому, что в главе 19 мы называли сигна-
турами определений. Однако, как будет показано ниже, в объектных системах
обычно требуется, чтобы такие сигнатуры были связаны лишь с одним конкрет-
ным “целевым” типом или классом. А в главе 19 ни о чем подобном не было и ре-
чи, но мы не считаем, что такое требование необходимо или обязательно
(см. [3.3]). Как уже отмечалось, код, который реализует методы объекта, как и пе-
ременные экземпляра, скрыт от пользователя.
Замечание. Точнее говоря, открытый интерфейс представляет собой часть опре-
деления класса рассматриваемого объекта, а не часть самого этого объекта. (Как
бы там ни было, открытый интерфейс является общим для всех объектов данного
класса, а не конкретным кодом в некотором отдельном объекте.) И для определе-
ния класса данный объект является его отдельным экземпляром (как элемент ка-
талога в обычной реляционной системе).
Методы вызываются с помощью сообщений, которые, по сути, являются вызовами
функций и имеют единственный синтаксически выделенный аргумент— получатель,
или цель. Например, ниже приводится сообщение, записанное с использованием гипоте-
тического синтаксиса и предназначенное для передачи указания о приеме сотрудника Е
на работу в отдел D.
D HIRE_EMP ( Е )
Аргументы D и Е будут рассмотрены в подразделе “Классы, экземпляры и коллекции”.
Получателем в этом примере является объект отдела, указанный как аргумент D. Соглас-
но синтаксису традиционных языков программирования это же сообщение следовало
сформулировать иначе4.
HIRE_EMP ( D, Е )
Для удобства в любой объектной системе обычно содержится некоторый набор
встроенных классов и методов. В частности, в ней почти всегда присутствуют числовые
(с методами “=”, “<”, “+”, и т.д.), символьные (с методами “=”, “<”, “||”, SUBSTR и т.д.)
и другие классы. Конечно, предоставляются возможности и для опытных пользователей,
которые могут создать собственные классы и методы.
Переменные экземпляра
Рассмотрим более подробно концепцию переменных экземпляра, в отношении кото-
рой у специалистов все еще нет единства мнений. Как утверждалось ранее, в истинно
объектной системе переменные экземпляра должны быть полностью скрыты от пользо-
вателя, однако большинство систем не являются действительно объектными. Поэтому на
практике необходимо различать открытые и закрытые переменные экземпляра, по-
следние из которых действительно скрыты для внешнего мира, тогда как первые — нет.
4 Выделение одного аргумента в качестве особого может упростить выполнение системой
процесса связывания во время выполнения, который был описан в главе 19. Однако такой подход
имеет и недостатки; по крайней мере, это может усложнить запись выполняемого кода для со-
ответствующего метода. При традиционном подходе (конечно, если есть из чего выбирать, т.е.
если есть несколько аргументов) целевой аргумент выбирается произвольно.
Глава 24. Объектные базы данных
951
Предположим, что имеется объектный класс отрезков линии LINESEG. Будем считать,
что каждый отрезок имеет начало (точка START) и конец (точка END). Чтобы “получить”
значения координат этих точек для заданного сегмента 1s, обычно используются выраже-
ния наподобие Is.START и Is.END. Таким образом, START и END— открытые переменные
экземпляра. Заметим, что по определению доступ к таким переменным должен осуществ-
ляться с помощью специального синтаксиса (обычно используется точка после имени объ-
екта, как в нашем примере). Если физическое представление отрезков линии заменить, на-
пример, комбинацией координат средней точки (MIDPOINT), длины отрезка (LENGTH) и его
наклона (SLOPE), в любой программе, которая содержит такие выражения, как Is.START и
Is. END, возникнет ошибка. Другими словами, будет утрачена независимость данных.
Обратите внимание, что открытые переменные экземпляра не являются логически
необходимыми. Предположим, что для получения значений переменных экземпляра от-
резка линии определены методы GET_START, GET_END, GET_MIDPOINT, GET_LENGTH и
GET_SLOPE. Тогда пользователь сможет “получить” значения координат начала, конца,
средней точки отрезка Is, его длины и наклона, вызвав методы GET_START(Is),
GET_END(Is), GET_MIDPOINT(Is), GET_LENGTH(Is) и GET_SLOPE(Is) соответственно. Од-
нако в этом случае уже не имеет значения, каково действительное физическое представ-
ление отрезка — вполне достаточно, чтобы при каждом его изменении соответствующим
образом были изменены и GET-методы. Более того, не было бы ошибкой, если бы поль-
зователю разрешалось применять выражения наподобие Is.START в качестве сокраще-
ния для выражения вызова метода GET_START(Is). Обратите внимание, что для исполь-
зования такого сокращения объект вовсе не обязательно должен содержать открытую
переменную экземпляра START. К сожалению, в реальных системах обычно не придер-
живаются такого подхода. Как правило, все открытые переменные экземпляра фактиче-
ски отражают физическое представление объекта (по крайней мере частично, хотя могут
существовать и некоторые дополнительные переменные экземпляра, которые являются
действительно закрытыми). Поэтому в соответствии со сложившейся практикой будем
считать, что, если не указано противное, объекты предоставляют определенные откры-
тые переменные экземпляра, хотя это понятие логически излишне.
В связи со сказанным выше необходимо рассмотреть еще один практический случай.
Предположим, что определенные аргументы (которые пользователь в первом приближении
может считать аргументами — “переменными экземпляра”) требуются для создания объектов
специфического класса5. Однако отсюда вовсе не следует, что подобные “переменные экзем-
пляра” могут применяться для любых целей. Пусть, например, для создания объекта отрезка
линии необходимы значения координат точек START и END. Однако отсюда не следует, что
всегда можно будет составить запрос, например, для получения сведений обо всех отрезках
линий, которые имеют одни и те же заданные координаты точки START. Возможность выпол-
нения такого запроса зависит от того, был ли определен подходящий для этого случая метод.
Наконец следует отметить, что некоторые системы поддерживают особый вид пере-
менных экземпляра, называемых защищенными. Если объекты класса С имеют защи-
щенную переменную экземпляра Р, то эта переменная доступна только для методов, оп-
ределенных для класса С, и для методов, определенных для любого подкласса (на любом
уровне) класса С. Подклассы кратко описаны в подразделе 24.3.
5 Рассматриваемые объекты должны быть, между прочим, изменяемыми (почему?).
952
Часть VI. Объектные и объектно-реляционные базы данных
Идентификатор объекта
Каждый объект обладает уникальным идентификатором объекта (object ID — OID).
Такие примитивные (“неизменяемые”) объекты, как целое число 3, являются самоиден-
тифицирующимися, т.е. они сами являются собственными идентификаторами объекта.
Изменяемые объекты, напротив, имеют в качестве идентификаторов адреса
(концептуальные). Эти адреса можно использовать повсюду в базе данных как указатели
(концептуальные) на данные объекты. Адреса объектов пользователю непосредственно
не предоставляются, но они могут быть присвоены, например, программной переменной
и переменным экземпляра в других объектах. Обсуждение этого вопроса будет продол-
жено в разделах 24.3 и 24.4.
Кстати, отметим, что иногда можно встретить утверждения о том, что, с точки зрения
пользователя, преимущество объектных систем заключается в абсолютной идентичности
двух разных объектов, т.е. они могут быть дубликатами по отношению друг к другу, но
отличаться своими идентификаторами. Однако, с точки зрения автора этой книги, по-
добное утверждение обманчиво. Ибо каким же образом пользователь действительно
сможет внешне различить оба объекта? (Более подробно этот вопрос описан в [5.3], [5.6]
и особенно — в [24.19].)
24.3. Еще раз об объектах и объектных классах
Рассмотрим более сложный пример с двумя объектными классами: DEPT (Отдел) и ЕМР
(Сотрудник). Предположим, что в системе уже были описаны определяемые пользователем
классы MONEY (Деньги) и JOB (Работа), а класс CHAR (Символьная переменная) является
встроенным. Тогда операции, необходимые для создания классов DEPT и ЕМР, могут выгля-
деть следующим образом (с использованием некоторого гипотетического синтаксиса).
CLASS DEPT
PUBLIC ( DEPT# CHAR,
DNAME CHAR,
BUDGET MONEY,
MGR REF ( EMP ),
EMPS REF ( SET ( REF | [ EMP ) ) )
METHODS ( HIRE_EMP I [ REF ( EMP ) ) ... . КОД .. • f
FIRE_EMP | [ REF ( EMP ) ) ... . КОД .. • f
CLASS ЕМР
PUBLIC ( EMP# CHAR,
ENAME CHAR,
SALARY MONEY,
POSITION REF ( JOB ) ) ...
METHODS ( . . . 1 ... f
Необходимо отметить несколько важных особенностей.
1. В этом примере описание отделов и сотрудников построено на основе иерархии
вложения, в которой объекты ЕМР концептуально содержатся внутри объектов DEPT.
Таким образом, объект класса DEPT содержит открытую переменную экземпляра MGR,
Глава 24. Объектные базы данных
953
представляющую менеджера отдела, а также переменную EMPS, представляющую со-
трудников отдела. Точнее, объекты класса DEPT содержат открытую переменную эк-
земпляра MGR, значение которой является ссылкой (REF) на объект, описывающий не-
которого сотрудника, и переменную EMPS, значение которой является совокупностью
ссылок на объекты других сотрудников. (Под ссылкой здесь подразумевается иден-
тификатор объекта, который подробнее описан ниже.) Понятие иерархии вложения
в более широкой форме будет представлено несколько ниже.
2. В данном примере в объекты класса ЕМР не была включена некоторая переменная эк-
земпляра, содержащая идентификатор объекта отдела DEPT или же значение номера
отдела DEPT# (переменная экземпляра для “внешнего ключа”). Это решение согласу-
ется с выбранным нами методом представления связи между отделами и сотрудника-
ми с помощью иерархии вложения. Однако это также означает, что не существует
возможности прямого перехода от заданного объекта класса ЕМР к соответствующему
ему объекту класса DEPT. Подробнее данный вопрос обсуждается в разделе 24.5.
3. Обратите внимание, что определение каждого класса содержит определения
(подробности кода в них опущены) методов, которые применяются к объектам это-
го класса. Целевыми классами для подобных методов являются, безусловно, клас-
сы, определение которых включает определение данного метода6.
На рис. 24.4 приведено несколько примеров экземпляров объектов для определенных
ранее классов DEPT и ЕМР. Рассмотрим объект ЕМР, показанный в верхней части рисунка
(с идентификатором (OID) еее), который содержит перечисленные ниже компоненты.
Неизменяемый объект 'Е001' (символьная строка) в открытой переменной экзем-
пляра EMP#
Неизменяемый объект 'Smith' (другая символьная строка) в открытой перемен-
ной экземпляра ENAME
Неизменяемый объект '$50 000' определенного пользователем класса MONEY в от-
крытой переменной экземпляра SALARY
Идентификатор (OID) объекта определенного пользователем класса JOB в откры-
той переменной экземпляра POSITION
Объект ЕМР также включает по крайней мере две закрытые переменные, одна из кото-
рых (0ID) содержит идентификатор еее самого объекта ЕМР, а другая (CLASS) — иденти-
фикатор, определяющий класс объекта (class-defining object— CDO) для объектов со-
трудников, что позволяет найти код методов данного объекта.
Замечание. Эти два идентификатора физически могут храниться как вместе с объек-
том, так и отдельно от него. Например, значение еее необязательно должно храниться
как часть соответствующего объекта ЕМР; необходимо только, чтобы в приложении был
задан некоторый способ обнаружения объекта ЕМР по данному значению еее (т.е. чтобы
6 Отметим, что в нашем гипотетическом синтаксисе понятия модели и реализации смешива-
ются (хотя это и нежелательно, но весьма типично). Кроме того, в [13.11] доказано, что, несо-
мненно, отделы и сотрудники — это плохие примеры для объектных классов! Однако данный вопрос
мы здесь обсуждать не будем, поскольку это слишком далеко увело бы нас от основной темы.
954
Часть VI. Объектные и объектно-реляционные базы данных
было задано некоторое отображение величины еее на физический адрес объекта ЕМР).
Однако концептуально пользователь всегда может представить себе идентификатор объ-
екта как часть этого объекта.
I Идентификаторы (OID) I CDO для класса SET
объектов класса ЕМР (REF(EMP))
Рис. 24.4. Пример экземпляров объектов классов DEPT и ЕМР
Теперь рассмотрим объект DEPT, расположенный в центре рисунка с идентификато-
ром (OID) ddd, который содержит перечисленные ниже объекты.
Неизменяемый объект ' D01' (символьная строка) в открытой переменной экземп-
ляра DEPT#
Неизменяемый объект 'Mktg' (другая символьная строка) в открытой переменной
экземпляра DNAME#
Неизменяемый объект '$1 000 000' (другая символьная строка) определенного
пользователем класса MONEY в открытой переменной экземпляра BUDGET
Идентификатор еее изменяемого объекта определенного пользователем класса
ЕМР в открытой переменной экземпляра MGR (это идентификатор объекта, пред-
ставляющего менеджера отдела)
Идентификатор sss изменяемого объекта определенного пользователем класса
SET(REF(EMP)) в открытой переменной экземпляра EMPS, которая подробнее опи-
сана ниже
Две закрытые переменные экземпляра, содержащие идентификатор (OID) ddd
объекта DEPT и идентификатор соответствующего объекта, определяющего класс
Объект с идентификатором sss состоит из набора идентификаторов индивидуальных
(изменяемых) объектов класса ЕМР, а также обычных закрытых переменных экземпляра.
Глава 24. Объектные базы данных
955
На рис. 24.4 экземпляры объектов представлены в том виде, в котором они реально
существуют, т.е. на рисунке отображается компонент структуры данных “объектной
модели”, что позволяет яснее представить саму объектную модель. Обычно в книгах или
документации такие диаграммы не используются; вместо этого данные представляются
так, как на рис. 24.5, на более высоком уровне абстракции, что, как принято считать, об-
легчает понимание объектной модели.
Рис. 24.5. Пример представления экземпляров
объектов DEPT и ЕМР в соответствии с ие-
рархией их вложения
Приведенная на рис. 24.5 схема в большей степени согласуется с интерпретацией на
основе иерархии вложения. Однако в ней остается скрытым важный факт: в объектах
часто содержатся не собственно другие объекты, а их идентификаторы. Например, со-
гласно рис. 24.5 можно предположить, что объект класса DEPT для отдела с номером
'D01' содержит два экземпляра объекта класса ЕМР для сотрудника с номером ' Е001'
(при этом, помимо всего прочего, может получиться, что сотрудник с номером 'Е001'
получает две различные зарплаты). Такая ситуация может привести к путанице, поэтому
предпочтение следует отдавать схемам, подобным приведенной на рис. 24.4.
В дополнение к этому следует заметить, что реальные объектные определения дан-
ных способствуют возникновению запутанных ситуаций, поскольку переменные экземп-
ляра в них обычно определяются не на основе “ссылок” (как в приведенных выше выра-
жениях с использованием гипотетического синтаксиса), а на основе непосредственного
отображения иерархии вложения. Например, переменные экземпляра EMPS в объектном
классе DEPT обычно определяются не как REF(SET(REF(EMP))), а в более краткой форме:
SET(ЕМР). Несмотря на некоторую громоздкость полной записи, мы все же предпочитаем
наш стиль, как более ясный и точный.
956
Часть VI. Объектные и объектно-реляционные базы данных
Следует отметить, что вся прежняя критика иерархического подхода (например, ие-
рархии вложения, воплощенной в СУБД IMS) в основном относилась именно к иерархи-
ям вложения. Подробное рассмотрение данного вопроса заняло бы слишком много
места, поэтому достаточно сказать, что основным аргументом такой критики было от-
сутствие симметрии. В частности, иерархии не совсем удобны для представления от-
ношений типа “многие ко многим”. Например, для рассматриваемого ранее отношения
поставщиков и деталей может возникнуть вопрос, содержатся ли объекты-поставщики в
объектах-деталях или наоборот. А может, верно и то, и другое? А что можно сказать об
отношениях поставщиков, деталей и проектов?
Действительно, подобных вопросов больше, чем можно было бы предположить. С
одной стороны, как мы убедились, объекты представляют собой иерархию, и к ним также
относятся привычные критические замечания относительно иерархий. А с другой сторо-
ны, как явствует из рис. 24.4, такие объекты на самом деле образуют не иерархию, а
кортежи с перечисленными ниже компонентами.
1. Неизменяемые “подобъекты”, т.е. самоидентифицируемые значения, такие как це-
лые числа и денежные суммы.
2. Идентификаторы изменяемых “подобъектов”, т.е. ссылки или указатели на другие
(возможно, совместно используемые) изменяемые объекты.
3. Множества, списки, массивы и т.д. объектов, перечисленных в пп. 1, 2 и в этом
пункте.
К этому списку следует также добавить скрытые идентификаторы объектов, иденти-
фикаторы объектов, определяющих классы, и т.д. В частности, обратите внимание на
п. 3: обычно объектные системы поддерживают несколько “коллекций” генераторов
типов (SET, LIST, ARRAY и др.), но обычно не поддерживают тип RELATION (отношение).
Такие генераторы могут сочетаться сколь угодно сложно. Например, массив списков па-
кетов массивов указателей на целые переменные может составлять при определенных
условиях отдельный изменяемый объект. В следующем подразделе мы продолжим об-
суждение этого вопроса.
Еще раз об идентификаторе объекта
Чтобы сослаться на объект или идентифицировать его, в современных реляционных
СУБД обычно используются ключи, определяемые и управляемые пользователями
(далее для краткости будем называть их пользовательскими ключами), хотя, как нам из-
вестно из главы 3, в реляционных базах данных указатели наподобие идентификаторов
объектов фактически намеренно запрещены. Также хорошо известно, что применение
пользовательских ключей сопряжено с некоторыми проблемами. Эти проблемы доста-
точно подробно рассматриваются в [13.10] и [13.16], где сделан вывод, что реляционные
СУБД, по крайней мере в качестве альтернативы, должны поддерживать и ключи, опре-
деляемые системой (“суррогатные”). Аргументы в пользу идентификаторов объектов в
объектных системах подобны аргументам в пользу суррогатных ключей в реляционных
системах. (Однако их не следует приравнивать друг к другу, поскольку суррогатные
ключи — это доступные пользователю значения, а идентификаторы объектов — это ад-
реса или указатели, которые, по крайней мере концептуально, от пользователя скрыты.
В [24.19] широко обсуждается это различие и другие связанные с ним вопросы.)
Глава 24. Объектные базы данных
957
Здесь следует отметить некоторые важные моменты.
1. Необходимо понимать, что, как будет показано в разделе 24.4, наличие идентифи-
каторов объектов не позволяет полностью исключить применение пользователь-
ских ключей. Точнее, пользовательские ключи необходимы для общения с внеш-
ним миром, хотя внутри базы данных все объекты могут ссылаться один на другой
только с помощью идентификаторов объектов.
2. Что является идентификатором производного объекта, например “соединения” неко-
торого объекта класса ЕМР и соответствующего объекта класса DEPT или “проекции”
объекта класса DEPT по атрибутам BUDGET и MGR? Это очень важный вопрос для произ-
водных объектов, рассмотрение которого мы отложим до раздела 24.5.
3. Идентификаторы объектов часто служат предметом критических замечаний, вы-
званных тем, что объектные системы выглядят, как “модифицированный стандарт
CODASYL”. Стандарт CODASYL использовался для сетевых систем управления
базами данных (например, для СУБД IDMS), которые были созданы до появления
реляционного подхода. Использование идентификаторов объектов приводит к низ-
коуровневому стилю программирования (см. раздел 24.4.), что очень напоминает
устаревший стиль программирования согласно стандарту CODASYL. Кроме того,
поскольку идентификаторы объектов являются указателями, часто можно услы-
шать, что системы типа CODASYL ближе к объектным системам, чем реляцион-
ные, и что реляционные системы основаны на значениях, в то время как объектные
системы — на идентичности.
Классы, экземпляры и коллекции
В области объектных систем четко разделяются концепции класса, экземпляра и кол-
лекции. Как уже отмечалось, объектный класс является, в основном, типом данных, при-
чем он может быть встроенным или определенным пользователем, а также быть сколь
угодно сложным7. Каждый класс способен принять сообщение NEW, которое приводит
к созданию нового (изменяемого) экземпляра объекта данного класса.
Замечание. Вызываемый этим сообщением метод иногда называют конструкто-
ром класса.
Ниже приводится пример такого сообщения, записанного с помощью некоторого ги-
потетического синтаксиса.
Е := ЕМР NEW ( 'Е001', 'Smith', MONEY ( 50000 ), POS ) ;
Здесь программная переменная POS содержит идентификатор некоторого объекта
класса JOB, а метод NEW вызывается для создания нового экземпляра класса ЕМР, инициа-
лизации его переменных экземпляра заданными значениями, возвращения идентифика-
тора нового экземпляра и присвоения его программной переменной Е.
7 Как уже подчеркивалось в разделе 24.2, в некоторых системах используются оба поня-
тия— и "тип", и "класс". В этих системах "тип” означает тип, т.е. содержание или сущ-
ность понятия, а "класс” означает применение этого понятия, т.е. определенную коллекцию,
или иногда реализацию данного типа. В других системах данные термины используются ина-
че... Мы же по-прежнему будем употреблять термин "класс” для обозначения типа в том
смысле, что и в главе 5.
958
Часть VI. Объектные и объектно-реляционные базы данных
Поскольку одни объекты могут ссылаться на любые другие объекты с помощью
идентификаторов, один объект может совместно использоваться несколькими другими
объектами. В частности, один и тот же объект может одновременно относиться к не-
скольким различным коллекциям объектов. В продолжение рассматриваемого примера
приведем еще одно выражение.
CLASS EMP_COLL
PUBLIC ( EMPS REF ( SET ( REF ( EMP ))))... ;
ALL_EMPS := EMP_COLL NEW ( ) ;
ALL_EMPS ADD ( E ) ;
Пояснения
Объект класса EMP_COLL содержит одну открытую переменную экземпляра EMPS, зна-
чением которой является указатель (идентификатор) на изменяемый объект, значение
которого представляет собой набор указателей на отдельные объекты класса ЕМР.
ALL EMPS — это программная переменная, значением которой является идентифи-
катор объекта класса ЕМР COLL. После выполнения операции присвоения она будет
содержать идентификатор объекта, значением которого, в свою очередь, будет
идентификатор пустого множества идентификаторов объектов ЕМР.
ADD — это метод объектов класса ЕМР COLL. В рассматриваемом примере данный
метод применяется для объекта класса, идентификатор которого содержится в
программной переменной ALL_EMPS, и предназначается для добавления идентифи-
катора объекта ЕМР, который содержится в программной переменной Е, к набору
идентификаторов (изначально пустому). Причем идентификатор этого набора со-
держится в объекте ЕМР COLL, идентификатор которого находится в программной
переменной ALL_EMPS.
Рассмотрев приведенную выше последовательность операций, можно заметить, что
переменная ALL EMPS связана с набором объектов ЕМР, который в текущий момент со-
держит только один объект, а именно — объект, описывающий сотрудника с номером
' Е001'. (Помимо всего прочего, обратите внимание на то, что необходимо упомянуть
значение ключа пользователя в последнем предложении!)
Конечно, в некоторый заданный момент может существовать любое количество раз-
ных и, возможно, перекрывающихся “наборов сотрудников”, например следующих.
PROGRAMMERS := EMP_COLL NEW ( ) ;
PROGRAMMERS ADD ( E ) ;
HIGHLY_PAID := EMP_COLL NEW ( ) ;
HIGHLY_PAID ADD ( E ) ;
Приведенный ниже пример SQL-выражения показывает, что в реляционных системах
все может быть организовано совсем иначе.
CREATE TABLE ЕМР
( EMP# ,
Глава 24. Объектные базы данных
959
ENAME ,
SALARY ... ,
POSITION
В этом случае тип и коллекция создаются одновременно, причем сложный тип соот-
ветствует заголовку таблицы, а исходно пустая коллекция соответствует содержанию
таблицы. Точно так же приведенное ниже SQL-выражение позволяет одновременно соз-
дать отдельную строку ЕМР и добавить ее к коллекции ЕМР.
INSERT INTO ЕМР ( ... ) VALUES (...);
Можно сделать вывод, что организация этих действий с помощью языка SQL харак-
теризуется следующими особенностями.
1. Отдельный “объект” класса ЕМР не может существовать, не являясь частью некото-
рой “коллекции”, фактически — какой-то единственной “коллекции” (подробности
приведены ниже).
2. Не существует непосредственного способа создания двух различных “коллекций”
объектов одного и того же “класса” ЕМР (подробности приведены ниже).
3. Не существует непосредственного способа совместного использования одного и
того же “объекта” в нескольких “коллекциях” “объектов” ЕМР (подробности приве-
дены ниже).
Именно такие претензии иногда можно услышать, однако они не выдерживают серь-
езной критики. Во-первых, для достижения равноценного эффекта в каждом случае мо-
жет применяться реляционный метод использования внешнего ключа. Например, можно
определить две базовые таблицы, PROGRAMMERS (программисты) и HIGHLY_PAID
(высокооплачиваемые), каждая из которых состоит из номеров соответствующих со-
трудников. Во-вторых, что еще важнее, для достижения того же эффекта может быть
применен реляционный метод с использованием представлений. Например, таблицы
PROGRAMMERS и HIGHLY_PAID можно определить как представления, созданные на основе
базовой таблицы ЕМР.
CREATE VIEW PROGRAMMERS
AS SELECT EMP#, ENAME, SALARY, POSITION
FROM EMP
WHERE POSITION = 'Programmer' ;
CREATE VIEW HIGHLY_PAID
AS SELECT EMP#, ENAME, SALARY, POSITION
FROM EMP
WHERE SALARY > <некоторое значение, например 75 000> ;
Теперь один и тот же “объект” сотрудника можно одновременно разместить в двух
или более “коллекциях”. Кроме того, участие в коллекциях, которые являются представ-
лениями, управляется системой автоматически, а не программистом вручную.
Завершая эту тему, следует упомянуть об одной интересной параллели, существую-
щей между изменяемыми объектами объектных систем и явно заданными динамиче-
скими переменными некоторых языков программирования (например, базовыми пере-
менными языка PL/I). Как и в случае изменяемых объектов данного класса, может суще-
960
Часть VI. Объектные и объектно-реляционные базы данных
ствовать любое количество отдельных явных динамических переменных данного типа,
память для которых выделяется во время выполнения явно заданными указаниями про-
граммиста. Более того, эти отдельные переменные, как и отдельные изменяемые объек-
ты, не имеют имен, а потому на них можно ссылаться только с помощью указателей.
Например, в языке PL/I можно записать такую последовательность выражений.
DCL XYZ INTEGER BASED ; /* XYZ - базовая переменная */
DCL Р POINTER ; /* Р - указатель */
ALLOCATE XYZ SET ( Р ); /* создание нового экземпляра XYZ, */
/* на который указывает Р */
Р -> XYZ = 3 ; /* присвоение значения 3 экземпляру */
/* XYZ, на который указывает Р */
Этот записанный на языке PL/I код очень похож на рассмотренный ранее объектный
код. В частности, объявление базовой переменной подобно объявлению класса объектов,
а операция ALLOCATE — созданию нового экземпляра объекта этого класса. Таким обра-
зом, основная причина, по которой в объектной модели необходимы идентификаторы,
заключается в том, что те объекты, которые они идентифицируют, не обладают уникаль-
ными именами (точно так же, как базовые переменные в языке PL/I).
Иерархии классов
Описание концепций объектного подхода было бы неполным без рассмотрения ие-
рархий классов (их не следует путать с иерархиями вложения). Однако объектная кон-
цепция “иерархии классов”, в сущности, является тем же, что и концепция иерархии ти-
пов, рассмотренная в главе 19. Следовательно, здесь можно ограничиться несколькими
краткими определениями (большей частью это перефразированные выражения из
главы 19) и соответствующими примерами.
Замечание. Напомним, что в объектном мире, как и в остальных случаях, все еще
нет полной согласованности относительно концепции абстрактной модели наследова-
ния, поэтому различные системы наследования существенно отличаются одна от дру-
гой на уровне деталей.
Начнем с того, что объектный класс Y является подклассом класса X, а объектный
класс X — суперклассом объектного класса Y тогда и только тогда, когда каждый объект
класса Y обязательно является и объектом класса X (т.е. “Y ISA X”). В этом случае объ-
ект класса Y наследует переменные экземпляра и методы класса X. Наследование пере-
менных экземпляра обычно называют наследованием структуры, а наследование мето-
дов — наследованием поведения. В истинно объектных системах не может быть насле-
дования структуры, а возможно лишь наследование поведения (по крайней мере для ска-
ляров и инкапсулированных объектов), поскольку нет структуры для наследования (т.е.
пользователю никакая структура не видна). Однако на практике объектные системы
обычно несовершенны и в какой-то мере поддерживают структурное наследование, ко-
торое, подчеркиваем, означает наследование открытых переменных экземпляра.
Если класс Y является подклассом класса X, то пользователю предоставляется воз-
можность применять объект класса Y вместо объекта класса X везде, где это допустимо,
т.е. в качестве аргумента различных методов. Этот принцип называется принципом
подстановки и весьма полезен для повторного использования кода. Однако, посколь-
Глава 24. Объектные базы данных
961
ку в объектных системах не всегда четко прослеживается разница между значениями и
переменными (т.е. между неизменяемыми и изменяемыми объектами), возникают про-
блемы различения значения и возможного замещения переменной (этот вопрос обсужда-
ется в главе 19). Возможность применять один и тот же метод для объектов класса X и
класса Y называется полиморфизмом.
Обычно объектные системы поставляются с определенной встроенной иерархией
классов. Например, в системе OPAL (см. раздел 24.4) каждый класс рассматривается как
подкласс некоторого уровня встроенного класса OBJECT (поскольку “все является объек-
тами”). Встроенные подклассы класса OBJECT включают классы BOOLEAN, CHAR, INTEGER,
COLLECTION и др. Класс COLLECTION, в свою очередь, включает подкласс BAG, а класс BAG
содержит класс SET и т.д. и т.п.
Наконец, в некоторых системах, кроме одиночного наследования, в той или иной
форме поддерживается множественное наследование. Однако автору не известно ни од-
ной системы, которая поддерживала бы наследование кортежей или отношений (как
одиночное, так и множественное) в смысле, который подразумевался в [3.3].
24.4. Простой пример
В предыдущей главе были представлены базовые концепции объектного подхода. В
данной главе на простом примере последовательно демонстрируется применение этих
идей на практике, а именно — как определяется объектная база данных, как она попол-
няется данными, как в ней выполняются операции извлечения и обновления данных. В
рассматриваемом примере используются объектная СУБД GemStone (разработка корпо-
рации GemStone Systems) и ее язык запросов OPAL [24.14]. Язык OPAL, в свою очередь,
основывается на языке Smalltalk [24.26], одном из наиболее истинно объектных языков
(поэтому он здесь и используется).
Замечание Необходимо добавить, что язык Smalltalk появился на рынке раньше, чем
язык C++, и гораздо раньше, чем язык Java. Однако несмотря на это два последних языка
являются менее “чистыми” объектными языками, чем Smalltalk.
В качестве примера воспользуемся упрощенной версией базы данных профессио-
нальной подготовки из упр. 8.10 главы 8. В этой базе данных содержится информация о
схеме подготовки и обучения специалистов внутри некоторой компании. Для каждого
курса обучения (COURSE) в базе данных содержится описание отдельных потоков, органи-
зованных для его изучения (OFFERING). Для каждого потока хранятся данные обо всех его
слушателях (ENROLLMENT) и преподавателях (TEACHER). Кроме того, в базе содержатся
сведения о сотрудниках компании. Реляционную версию базы данных можно описать сле-
дующим образом.
COURSE { COURSE#, TITLE }
OFFERING { COURSE#, OFF#, OFFDATE, LOCATION }
TEACHER { COURSE#, OFF#, EMP# }
ENROLLMENT { COURSE#, OFF#, EMP#, GRADE }
EMP { EMP#, ENAME, SALARY, POSITION }
На рис. 24.6 показана диаграмма связей для рассматриваемой базы данных. Более
подробно она описана в главе 8, в упражнениях и ответах к упражнениям.
962
Часть VI. Объектные и объектно-реляционные базы данных
Рис. 24.6. Диаграмма связей для образовательной
базы данных
Определение данных
Теперь перейдем к определению данных на языке OPAL для образовательной базы
данных. Ниже приводится первое определение объектного класса ЕМР, описывающего
сотрудников (для удобства строки этого определения пронумерованы).
1 OBJECT SUBCLASS : 'ЕМР'
2 INSTVARNAMES : #[ 'ЕМР#', 'ENAME', 'POSITION' ]
3 CONSTRAINTS : #[ #[ #ЕМР#, STRING ] ,
4 [ ШАМЕ, STRING ],
5 [ #POSITION, STRING ] ] .
Пояснения. В строке 1 определен объектный класс ЕМР, производный от встроенно-
го класса OBJECT. (Согласно терминологии языка OPAL в строке 1 отсылается сооб-
щение объекту OBJECT с запросом выполнить метод SUBCLASS, причем с помощью
предложений INSTVARNAMES и CONSTRAINTS указываются параметры вызова этого ме-
тода. Для определения нового класса (как и всего прочего) необходимо отослать со-
общение объекту.) В строке 2 указывается, что объекты класса ЕМР имеют три закры-
тые переменные экземпляра— ЕМР#, ENAME и POSITION, а в строках 3-5 на эти пере-
менные экземпляра накладываются ограничения, указывающие, что они должны со-
держать объекты класса STRING.
Замечание. В настоящей главе опускаются чисто синтаксические подробности, несу-
щественные для преследуемых нами целей (например, вездесущие знаки “#”, присутст-
вующие в приведенном выше примере).
Подчеркнем, что переменные экземпляра ЕМР#, ENAME и POSITION — закрытые пере-
менные для класса ЕМР, поэтому доступ к ним по именам допустим только в методах это-
го класса. В качестве примера ниже даны определения методов “получить и установить”,
т.е. методов, позволяющих выбрать и обновить номера служащих (здесь символ “А”
можно читать как “возвратить”).
METHOD : ЕМР
GET EMP#
~EMP#
%
Глава 24. Объектные базы данных
963
METHOD : EMP
SET_EMP# : EMP# PARM
EMP# := EMP#_PARM
%
В следующем подразделе о методах определения мы поговорим подробнее. А сейчас
рассмотрим определение класса описания курса COURSE.
1 OBJECT SUBCLASS : 'COURSE'
2 INSTVARNAMES : #[ 'COURSE#', 'TITLE', 'OFFERINGS' ]
3 CONSTRAINTS : #[ #[ #COURSE#, STRING ] ,
4 [ #TITLE, STRING ] ,
5 [ #OFFERINGS, OSET ] ] .
Пояснения. В строке 5 определена переменная OFFERINGS, которая содержит объект
класса OSET, или, точнее, идентификатор объекта класса OSET. Выражаясь неформально,
переменная OFFERINGS обозначает множество всех потоков для данного курса. Иначе го-
воря, связь “курс — поток” моделируется с помощью иерархии вложения, в которой по-
токи концептуально содержатся внутри соответствующего курса. Определение класса
OSET будет дано ниже, а определение класса потока OFFERING может быть записано так.
1 OBJECT SUBCLASS : 'OFFERING'
2 INSTVARNAMES : #[ 'OFF#', 'ODATE', 'LOCATION',
3 'ENROLLMENTS', 'TEACHERS' ]
4 CONSTRAINTS : #[ #[ #OFF#, STRING ] ,
5 [ #ODATE, DATETIME ],
6 [ #LOCATION, STRING ],
7 [ #ENROLLMENTS, NSET ],
8 [ #TEACHERS, TSET ] ] .
Пояснения. В строке 7 определяется закрытая переменная экземпляра ENROLLMENTS,
содержащая идентификатор объекта класса NSET. Говоря неформально, переменная
ENROLLMENTS описывает множество всех слушателей в данном потоке. Аналогично пере-
менная TEACHERS описывает множество всех преподавателей потока. Следовательно,
здесь вновь используется представление иерархии вложения. Определения классов NSET
и TSET будут даны ниже. Определение класса слушателей ENROLLMENT может быть запи-
сано следующим образом.
1 OBJECT SUBCLASS : 'ENROLLMENT'
2 INSTVARNAMES : #[ 'EMP', 'GRADE' ]
3 CONSTRAINTS : #[ #[ #EMP, EMP ] ,
4 [ #GRADE, STRING ] ].
Пояснения. В строке 3 определяется закрытая переменная экземпляра ЕМР, содержа-
щая идентификатор объекта класса ЕМР, представляющий отдельного сотрудника, который
является слушателем курса.
Замечание. Чтобы продолжить иерархию вложения, объект ЕМР помещается в объект
ENROLLMENT. Однако здесь можно заметить асимметрию: зачисление сотрудника на обу-
чение в разные потоки описывается как отношение типа “многие ко многим”, однако
члены этого отношения, сотрудники и потоки, обрабатываются совершенно по-разному.
964
Часть VI. Объектные и объектно-реляционные базы данных
И наконец рассмотрим объекты, представляющие преподавателей. В нашем примере
следует несколько отвлечься от исходной реляционной версии базы данных и рассмот-
реть преподавателей (TEACHER) как подкласс класса сотрудников (ЕМР).
1 ЕМР SUBCLASS : 'TEACHER'
2 INSTVARNAMES : #[ 'COURSES' ]
3 CONSTRAINTS : #[ #[ #COURSES, CSET ] ] .
Пояснения. В строке 1 определен объектный класс TEACHER, который является подклассом
ранее определенного класса ЕМР (иначе говоря, TEACHER "ISA" ЕМР). Таким образом, каждый от-
дельный объект TEACHER имеет закрытые переменные экземпляра ЕМР#, ENAME и POSITION
(которые унаследованы от класса ЕМР8), а также переменную COURSES, которая содержит иден-
тификатор объекта класса CSET. Объект CSET определяет множество всех курсов, которые ведет
конкретный преподаватель. Каждый объект TEACHER также наследует все методы класса ЕМР.
Как уже отмечалось, в предыдущих определениях классов предполагалось существо-
вание нескольких классов коллекций (например, коллекций объектов потоков, учеников,
преподавателей и т.д.), но они не были определены. Теперь следует дать точное опреде-
ление коллекции каждого класса, а именно: ESET, CSET, OSET, NSET и TSET. Например,
объект класса CSET будет состоять из множества идентификаторов отдельных объектов
класса COURSE. Ниже даются определения всех этих классов, начиная с класса ESET.
1 SET SUBCLASS : 'ESET'
2 CONSTRAINTS : EMP .
Пояснения. В строке 1 дается определение класса ESET, который является подклассом
встроенного класса SET. В строке 2 на объекты класса ESET накладывается ограничение:
они должны быть множествами идентификаторов объектов класса ЕМР. В общем случае
может существовать произвольное число объектов класса ESET, но в данной ситуации будет
создан только один объект (подробности приводятся в следующем подразделе), который
будет содержать множество идентификаторов всех объектов класса ЕМР. Выражаясь не-
формально, объект ESET можно считать аналогом базовой переменной-отношения ЕМР в ре-
ляционной версии базы данных.
Определения классов CSET, OSET, NSET и TSET аналогичны (они приводятся ниже). Од-
нако для каждого из них придется создать не один, а несколько объектов соответствую-
щей коллекции классов. Например, в нашем случае будет существовать столько коллек-
ций объектов OSET, сколько существует отдельных объектов COURSE.
SET SUBCLASS : 'CSET'
CONSTRAINTS : COURSE .
SET SUBCLASS : 'OSET'
CONSTRAINTS : OFFERING .
SET SUBCLASS : 'NSET'
CONSTRAINTS : ENROLLMENT .
SET SUBCLASS : 'TSET'
CONSTRAINTS : TEACHER .
# Заметим, что здесь наследуется закрытое представление (т.е. физическая реализация).
Глава 24. Объектные базы данных
965
Заполнение базы данных
Теперь обсудим, как можно поместить в рассматриваемую базу данных требуемую
информацию. При этом остановимся на пяти основных типах объектов (сотрудники, кур-
сы, потоки, слушатели, преподаватели). Начнем с сотрудников. Напомним о нашем на-
мерении собрать вместе идентификаторы всех объектов ЕМР в единственном объекте
ESET. Таким образом, прежде всего необходимо создать объект ESET.
OID_OF_SET_OF_ALL_EMPS := ESET NEW .
Правая часть этого выражения возвращает объектный идентификатор (OID) нового
пустого экземпляра объекта класса ESET (т.е. пустое множество идентификаторов объек-
тов класса ЕМР), а затем идентификатор этого нового экземпляра присваивается про-
граммной переменной OID_OF_SET OF_ALL_EMPS. Говоря неформально, эта переменная
обозначает множество всех сотрудников.
Теперь всякий раз при создании нового объекта класса ЕМР идентификатор этого объ-
екта следует помещать в объект ESET, идентификатор которого хранится в переменной
OID_OF_SET_OF_ALL_EMPS. Для создания объекта класса ЕМР и вставки его идентификато-
ра в объект класса ESET необходимо определить метод или же написать программу, ко-
торая выполнит эту задачу.
1 METHOD : ESET " анонимный! "
2 ADD_EMP# : EMP#_PARM " параметры "
3 ADD“ENAME : ENAME PARM
4 ADD~POS : POS PARM
5 | EMP OID | " локальная переменная
6 EMP OID := EMP NEW . " новый сотрудник "
7 EMP“OID SET EMP# : EMP# PARM ; " инициализация "
8 " SET“ENAME : ENAME PARM ;
9 SET~POS : POS PARM .
10 SELF ADD: EMP OID . " вставка "
11 %
Пояснения
В строке 1 начинается запись кода данного метода (который завершается симво-
лом “%” в строке 11) для объектов класса ESET. (На самом деле в системе во время
выполнения программы будет существовать всего один объект этого класса.)
В строках 2-4 определены три параметра с внешними именами ADDJEMP#,
ADD_ENAME и ADDJPOS. Эти имена будут использованы в сообщениях, вызывающих
данный метод. Соответствующие внутренние имена EMP#_PARM, ENAME PARM и
POSJPARM будут использоваться только внутри кода реализации данного метода.
В строке 5 определена локальная переменная EMP__OID, а в строке 6 ей присвоен
идентификатор нового неинициализированного экземпляра объекта класса ЕМР.
В строках 7-9 посылается сообщение новому объекту класса ЕМР с указанием трех
методов (SET ЕМР#, SETJENAME и SETJPOS) и передачей одного аргумента каждому из
них (EMP#_PARM для SET JMP#, ENAME JP ARM для SETJSNAME и POSJPARM для SETPOS).
966
Часть VI. Объектные и объектно-реляционные базы данных
Замечание. Здесь предполагается, что SET EMP# является методом, который ис-
пользуется для объекта класса ЕМР и предназначается для присвоения некоторого
значения переменной ЕМР#. Аналогично определяются методы SET ENAME и
SETJPOS. Несколько подробнее эти методы рассматриваются ниже.
В строке 10 посылается сообщение объекту SELF. Это имя объекта является спе-
циальным обозначением, представляющим во время выполнения тот самый теку-
щий объект, в котором определен указанный метод (т.е. сообщение посылается
самому текущему целевому объекту). Сообщение вызывает встроенный метод ADD
(этот метод содержится в каждом классе, определяющем “коллекцию”). В резуль-
тате идентификатор объекта, который содержится в локальной переменной
EMPJDID, будет вставлен в объект, идентифицируемый значением переменной SELF
(в данном случае это будет объект ESET, содержащий идентификаторы всех суще-
ствующих на текущий момент объектов класса ЕМР).
Замечание. Переменная SELF необходима потому, что параметр, соответствующий
объекту-получателю, не имеет собственного имени (см. строку 1).
Обратите внимание, что, как отмечено в комментарии к строке 1, определенный
здесь метод остается анонимным. В общем случае в языке OPAL методы не имеют
имен; вместо этого для них используется сигнатура (т.е. комбинация имени класса,
в котором он применяется, и внешних имен их параметров). Однако при этом возни-
кает опасность создания неуклюжих и огромных выражений. Можно отметить и еще
один недостаток: если два метода одного и того же класса используют одни и те же
параметры, то для этих методов должны использоваться разные внешние параметры.
Теперь новый метод, созданный для вставки в базу данных новых объектов класса
ЕМР, можно применить следующим образом.
OID OF_SET_OF_ALL EMPS ADD EMP# : 'Е009'
ADD“ENAME : 'Helms'
ADD“POS : 'Janitor' .
При использовании приведенного выражения будет создан объект класса ЕМР для со-
трудника с номером ' Е009', а идентификатор этого объекта будет добавлен к множеству
всех идентификаторов объектов класса ЕМР.
Обратите внимание, что встроенный метод NEW никогда не должен использоваться
для класса ЕМР, кроме тех случаев, когда он является частью только что определенного
метода. Иначе могут быть созданы лишние объекты класса ЕМР, которые не будут пред-
ставлены в “множестве всех сотрудников”.
Замечание. Следует принести извинения за слишком частое повторение таких выра-
жений, как “множество всех сотрудников” и “только что определенный метод”, однако
сложно описывать то, что не имеет собственного имени.
А теперь займемся курсами. Объекты для сотрудников представляют собой наиболее
простой случай, поскольку они соответствуют “регулярным объектам” (согласно терми-
нологии модели типа “сущность/связь”) и не содержат никаких других объектов (не счи-
тая неизменяемых). Далее следует рассмотреть более сложный случай объектов для кур-
сов, которые (несмотря на то, что они все еще остаются “регулярными объектами”) кон-
цептуально содержат другие изменяемые объекты. В целом, чтобы создать объекты для
курсов, необходимо выполнить следующие действия.
Глава 24. Объектные базы данных
967
1. Применить метод NEW для класса CSET с целью создания исходно пустого
“множества всех курсов” (на самом деле — множества идентификаторов объектов
класса COURSE).
2. Определить метод для создания нового объекта класса COURSE и вставки его иден-
тификатора в “множество всех курсов”. При создании этого объекта потребуется
задать некоторые значения для параметров COURSE# и TITLE. Кроме того, с помо-
щью метода NEW класса OSET потребуется также создать исходно пустое множество
потоков (на самом деле— идентификаторов объектов класса OFFERING), а затем
разместить идентификатор этого пустого множества потоков в переменной
OFERINGS внутри нового объекта класса COURSE.
3. Вызвать только что определенный метод для каждого отдельного курса.
Теперь создадим объекты потоков. Для этого необходимо выполнить следующие
действия.
1. Определить метод для создания нового объекта класса OFFERING. Этот метод должен
принимать в качестве параметров значения переменных OFF#, ODATE и LOCATION и
приводить к созданию нового объекта класса OFFERING с указанными параметрами.
Кроме того, потребуется выполнить некоторые дополнительные действия.
Для создания исходно пустого множества слушателей (идентификаторов объек-
тов класса ENROLLMENT) следует применить метод NEW для класса NSET, а затем
разместить идентификатор этого пустого множества слушателей в переменной
ENROLLMENTS внутри нового объекта класса OFFERING.
Для создания исходно пустого множества преподавателей (идентификаторов объ-
ектов класса TEACHER) следует применить метод NEW для класса NSET, а затем раз-
местить идентификатор этого пустого множества преподавателей в переменной
TEACHERS внутри нового объекта класса OFFERING.
2. Данный метод принимает в качестве параметра значение переменной COURSE# и
применяет его следующим образом.
Используя указанное значение параметра, необходимо найти объект класса
COURSE, соответствующий новому объекту класса OFFERING. Как это можно вы-
полнить, описано в следующем подразделе.
Замечание. Безусловно, такой метод не позволит создать объект для нового по-
тока, если не будет найден соответствующий ему курс обучения. Далее в этой
главе такие исключительные случаи рассматриваться не будут.
Следует найти “множество всех потоков” для данного объекта класса COURSE.
Добавить идентификатор нового объекта класса OFFERING к соответствующему
“множеству всех потоков”.
Заметьте, что (как уже упоминалось в этой главе) здесь нельзя избежать примене-
ния таких пользовательских ключей, как COURSE#. Действительно, они необходимы
не только для отображения объектов окружающего мира, но и для организации
подстановок справочных данных внутри базы данных.
3. Наконец следует вызвать только что определенный метод для каждого отдель-
ного потока.
968
Часть VI. Объектные и объектно-реляционные базы данных
Обратите внимание, что (в соответствии с используемым представлением иерархии
вложения) здесь не было создано “множество всех потоков”. В результате для выполне-
ния запроса, в котором данные коллекции используются в качестве анализируемой об-
ласти (например, для запроса “Найти все потоки, преподаваемые в Нью-Йорке”), потре-
буется дополнительно создать некоторую процедуру (см. следующий подраздел).
Теперь рассмотрим процедуру создания объектов слушателей. Эти объекты
(ENROLLMENT) отличаются от объектов потоков тем, что содержат переменную экземпля-
ра ЕМР, значение которой является идентификатором соответствующего объекта ЕМР. По-
этому последовательность действий должна быть такой.
1. Определить метод для создания нового объекта класса ENROLLMENT. В этом методе в
качестве аргументов используются значения переменных COURSE#, OFF#, EMP# и
GRADE и создается новый объект ENROLLMENT с заданным значением аргумента
GRADE. Кроме того, требуется выполнить некоторые дополнительные действия.
Использовать значения COURSE# и OFF# для нахождения объекта OFFERING, соот-
ветствующего новому объекту класса ENROLLMENT.
Найти “множество всех слушателей” для данного объекта класса OFFERING.
Добавить идентификатор нового объекта класса ENROLLMENT к соответствующему
“множеству всех слушателей”.
Кроме того, потребуется следующее.
Использовать значение переменной EMP# для нахождения соответствующего
объекта ЕМР.
Разместить идентификатор объекта ЕМР в переменной ЕМР внутри нового объекта
класса ENROLLMENT.
2. Вызывать только что определенный метод для каждого отдельного потока.
И наконец перейдем к созданию объектов преподавателей. Различие между способа-
ми создания объектов для преподавателей и потоков заключается в том, что класс
TEACHER является подклассом класса ЕМР. Ниже приведена последовательность действий,
которые необходимо выполнить в данном случае.
1. Определить метод создания нового объекта класса TEACHER. Этот метод принимает
в качестве аргументов значения переменных COURSE#, OFF# и ЕМР#. Потребуются
также некоторые дополнительные действия.
Использовать значение переменной EMP# для нахождения соответствующего
объекта класса ЕМР.
Преобразовать объект класса ЕМР в объект класса TEACHER (поскольку этот со-
трудник теперь является также преподавателем). Специфика подобного преобра-
зования зависит от конкретной системы (см. главу 19), и здесь этот вопрос рас-
сматриваться не будет.
Использовать значения переменных COURSE# и OFF# для поиска объекта класса
OFFERING, соответствующего новому объекту класса TEACHER.
Найти “множество всех преподавателей” для этого объекта OFFERING.
Глава 24. Объектные базы данных
969
Добавить идентификатор нового объекта класса TEACHER к соответствующему
“множеству всех преподавателей”.
2. Определить множество всех курсов, которые может вести данный преподаватель, а
также задать соответствующим образом значение переменной COURSES в новом
объекте класса TEACHER. Однако здесь эти подробности будут опущены.
3. Вызывать только что определенный метод для каждого объекта, описывающего
отдельного преподавателя.
Операции извлечения
Прежде чем приступить к подробному описанию операций извлечения, следует отме-
тить, что (хотя это и вполне очевидно) язык OPAL, как и другие объектные языки в це-
лом, функционирует по принципу последовательной обработки отдельных записей, а не
их множеств. Следовательно, для решения большинства проблем программист должен
создать некоторую процедуру.
Рассмотрим в качестве примера запрос “Найти все потоки для курса с номером
'С001', которые преподаются в городе 'New York'”. Для простоты предположим, что
есть переменная OOSOAC, значение которой является идентификатором “набора всех кур-
сов”. Ниже приводится код для такого запроса.
1 | COURSE С001 , С001 OFFS , С001 NY OFFS |
2 course“cooi
3 := OOSOAC DETECT : [ :CX | ( CX GET COURSE# ) = 'C001' ] .
4 C001 OFFS
5 := COURSE C001 GET OFFERINGS .
б C001 NY OFFS"
7 := CO01 OFFS SELECT :
8 [ :OX | ( OX GET LOCATION ) = 'New York' ] .
9 Л C001_NY__OFFS .
Пояснения
В строке 1 объявлены три локальные переменные: COURSE С001, которая будет ис-
пользована для хранения идентификатора объекта курса с номером 'С001';
C001__OFFS, которая будет использована для хранения идентификатора объекта
“набора всех потоков” для курса с номером 'С001'; С001 NY OFFS, которая будет
использована для хранения идентификатора набора идентификаторов для требуе-
мых потоков (т.е. потоков, читаемых в Нью-Йорке).
В строках 2 и 3 посылается сообщение объекту (коллекции), определяемому зна-
чением переменной OOSOAC. Это сообщение вызывает встроенный метод DETECT
данной коллекции объектов с указанием следующего аргумента.
[ I PW 1
Здесь р(х) —условное выражение, включающее переменную х, а х— переменная
диапазона, изменяющаяся в пределах всех членов коллекции, к которой применя-
ется метод DETECT (т.е. множества объектов COURSE в рассматриваемом примере).
В результате выполнения метода DETECT возвращается идентификатор первого
найденного объекта этого множества, для которого выражение р(х) оказывается
970
Часть VI. Объектные и объектно-реляционные базы данных
истинным (в рассматриваемом примере это экземпляр объекта класса COURSE для
курса с номером ' СО 01' )9. Затем идентификатор этого объекта класса COURSE при-
сваивается переменной COURSE С001.
Замечание. В качестве аргумента метода DETECT можно также задать некоторый
аргумент “выхода” на случай, когда выражение р(х) не будет истинным ни для
одного объекта в коллекции. Однако такая детализация здесь опущена.
В строках 4 и 5 переменной C001_OFFS присваивается идентификатор “множества
всех потоков” для курса с номером ' С001'.
Строки 6-8 подобны строкам 2 и 3, поскольку встроенный метод SELECT подобен
методу DETECT, за исключением того, что он возвращает идентификатор коллекции
идентификаторов всех объектов (вместо того чтобы указывать только на первый
найденный объект), для которых выражение р(х) является истинным. В рассматри-
ваемом примере в результате выполнения этого метода переменной C001_NY OFFS
присваивается идентификатор набора идентификаторов для тех потоков курса с но-
мером 'С001', которые читаются в городе 'New York'.
В строке 9 этот идентификатор возвращается пользователю.
Следует обратить внимание на некоторые особенности приведенного примера.
1. Условное выражение р(х) в методах SELECT и DETECT может содержать (в самом
сложном случае) некоторое количество простых скалярных операторов сравнения,
которые соединяются с помощью операторов AND, т.е. сложность данного условия
поиска ограничена.
2. Квадратные скобки, окружающие выражение аргумента методов SELECT и DETECT, мож-
но заменить круглыми скобками. При использовании круглых скобок в языке OPAL бу-
дет предпринята попытка задействовать индекс (если соответствующий индекс сущест-
вует), а при использовании квадратных скобок индексы задействованы не будут.
3. Указание, что метод DETECT возвращает идентификатор “первого найденного” объек-
та, для которого значением выражения р(х) будет истина, означает, что найденный
объект будет первым найденным при использовании произвольной последовательно-
сти поиска, которая будет выбрана языком OPAL для просмотра коллекции (внутри
набора идентификаторов не задается никакой внутренней упорядоченности). В рас-
сматриваемом примере это замечание не имеет особого смысла, поскольку “первый”
объект, для которого выражение р(х) будет истинно, фактически является единст-
венным таким объектом.
4. Внимательный читатель непременно заметит выражения наподобие “метод DETECT”,
хотя, как отмечалось выше, методы в языке OPAL не имеют имен. Действительно,
DETECT и SELECT не являются названиями методов (а потому выражения наподобие
“метод DETECT” некорректны). Они, скорее всего, служат именами внешних парамет-
ров для некоторых встроенных (и анонимных) методов. Однако для краткости и про-
стоты далее в качестве имен методов по-прежнему будут использоваться названия
DETECT и SELECT (а также другие подобные им названия для других методов).
9 В этом примере подразумевается, что такие методы, как GET COURCE# (аналог метода
GET ЕМР#, описанного в этом разделе), уже определены.
Глава 24. Объектные базы данных
971
5. Кроме того, внимательный читатель заметит, что довольно часто используется вы-
ражение “метод NEW”. В данном случае оно вполне корректно. В качестве исключе-
ния в языке OPAL допускается применение анонимных методов, которые не со-
держат каких-либо аргументов, кроме указания объекта-получателя.
Операции обновления
Объектный аналог операции вставки INSERT уже обсуждался в предыдущем подраз-
деле, а аналоги операций обновления UPDATE и удаления DELETE рассматриваются ниже.
Обновление. Операции обновления выполняются так же, как операции извлечения,
но вместо методов GET_ используются методы SET_.
Удаление. Для удаления объектов используется встроенный метод REMOVE. Точ-
нее, он используется для удаления идентификатора некоторого объекта из неко-
торой коллекции. Если на данный объект больше не имеется никаких ссылок,
т.е. к нему вовсе не может быть осуществлен доступ, то в языке OPAL он авто-
матически удаляется системным процессом сборки мусора. Ниже приводится
пример реализации операции “удаления сотрудника с номером ' Е001' из набора
всех сотрудников”.
Е001 := OID_OF_SET_OF_ALL_EMPS
DETECT : [ :ЕХ | (EX GET_EMP# ) = 'E001' ].
OID_OF_SET_OF_ALL_EMPS REMOVE : E001 .
Но как в такой ситуации реализовать правило каскадного удаления DELETE
CASCADE? Например, как при удалении некоторого сотрудника одновременно уда-
лить и сведения обо всех потоках, в которых он проходит обучение? Для этого,
естественно, придется создать соответствующую процедуру.
Можно прийти к заключению, что механизм реализации удаления с помощью
процесса сборки мусора является всего лишь некоторой разновидностью реализа-
ции правила ограничения удаления ON DELETE RESTRICT, поскольку объект не
удаляется до тех пор, пока на него существует хотя бы одна ссылка. Однако в дан-
ном случае это не совсем так. Например, объекты потоков (OFFERING) не содержат
идентификаторов соответствующего объекта курса (COURSE), а потому потоки не
накладывают “ограничений” на удаление объектов курсов. (В иерархиях вложения
неявно подразумевается некоторая разновидность правила каскадного удаления,
кроме случаев, когда пользователь выполняет следующее:
либо включает идентификатор родительского объекта в дочерний объект;
либо включает идентификатор дочернего объекта в какой-то другой объект.
В таких ситуация интерпретация “иерархии вложения” не имеет никакого смысла.
В следующем разделе этот вопрос будет рассмотрен при обсуждении обратных
переменных.)
В заключение заметим, что операция удаления REMOVE может быть использована
для эмуляции реляционной операции DROP, например для удаления всего класса
ENROLLMENT. Подробности оставляем читателю в качестве упражнения.
972
Часть VI. Объектные и объектно-реляционные базы данных
24.5. Дополнительные аспекты
В этом разделе обсуждаются некоторые традиционные аспекты управления базами
данных, но в объектном контексте.
Произвольные запросы
Целостность базы данных
Реализация связей
Языки программирования баз данных
Повышение производительности
Является ли объектная СУБД действительно СУБД
Произвольные запросы
До сих пор мы преднамеренно не подчеркивали, что если для манипулирования
объектами заданы только заранее определенные методы, то произвольные запросы (не
предусмотренные этими методами) просто невозможны, если только классы и методы
не разработаны в соответствии со специальными правилами. Например, если для объ-
екта класса DEPT определены только методы HIRE_EMP (нанять сотрудника), FIRE_EMP
(уволить сотрудника) и CUT_BUDGET (урезать бюджет), то даже такой простой запрос,
как “Кто является менеджером (начальником) отдела программирования”, выполнить
будет невозможно.
По существу, по той же причине невозможно определить представления и деклара-
тивные ограничения целостности для объектов, опять же, если не следовать некоторым
конкретным правилам.
По нашему мнению, решение этих проблем (“специальные правила”) может быть
следующим.
1. Определить множество операторов (“операторов ТНЕ_”), с помощью которых мож-
но было бы получить некоторые возможные представления рассматриваемых
объектов, как в главе 5.
2. Надлежащим образом внедрить объекты в реляционную структуру. Эта часть ре-
шения подробно обсуждается в следующей главе.
Однако разработчики объектных систем обычно не придерживаются данных реко-
мендаций. Вместо этого они поступают следующим образом10.
1. Обычно определяются операторы, которые предоставляют не некоторые возмож-
ные представления, а реальные представления (см. обсуждение открытых перемен-
ных экземпляра в разделе 24.2). “В настоящее время для всех продуктов объектных
СУБД требуется, чтобы [переменные экземпляра], которые упоминаются в... запро-
сах, были открытыми” [24.38].
Здесь подразумевается, что рассматриваемая объектная система действительно под-
держивает произвольные запросы, как и большинство современных объектных систем. Однако
более ранние объектные системы иногда не поддерживали такие запросы, частично в силу при-
чин, которые будут рассмотрены в этом разделе.
Глава 24. Объектные базы данных
973
2. Обычно поддерживается не реляционная структура, а множество других структур,
которые основываются на пакетах, массивах и т.д. В связи с этим напомним наше
утверждение, что классы, т.е. типы, плюс отношения необходимы и достаточны на
логическом уровне (см. главу 3). А поскольку речь идет об основной модели, мы
считаем, что массивы и все остальное является ненужным и нежелательным. На
наш взгляд, причиной того, что в объектных системах отдано предпочтение кол-
лекциям, а не отношениям (фактически отношения почти полностью отвергнуты),
является, опять же, путаница между понятиями модели и реализации.
В связи с выполнением произвольных запросов возникает еще один важный вопрос, а
именно: какой класс является результатом. Предположим, например, что необходимо
выполнить запрос “Получить имена и размер заработной платы всех служащих в отделе
программирования” по базе данных отделов и служащих из раздела 24.3. Предположи-
тельно результат будет содержать открытые переменные экземпляра ENAME и SALARY.
Однако в базе данных нет класса, который имеет такую структуру. Должны ли мы пред-
варительно определить такой класс, прежде чем выполнять запрос? (Обратите внимание
на последствия: если бы было необходимо определить такой класс, для класса с п пере-
менными экземпляра потребовалось бы по крайней мере 2 п предварительно определен-
ных класса только для поддержки операций выборки!) А если есть какой-либо класс ре-
зультатов, то какие методы применимы к нему?
Аналогичные вопросы возникают в связи с операциями соединения. Если соединить
объекты отдела и служащего, то какой класс получится в результате? Какие методы
нужно использовать?
Возможно, из-за того, что на такие вопросы нелегко ответить, опираясь на чисто объ-
ектную структуру, в некоторых объектных системах поддерживаются операции “про-
хождения пути” (см. [24.25], [24.47]) вместо самих операций соединения. Для базы дан-
ных OPAL из раздела 24.4, например, допустимо следующее выражение пути.
ENROLLMENT . OFFERING . COURSE
Оно означает следующее. “Найти уникальный объект класса COURSE, на который ссы-
лается уникальный объект класса OFFERING, на который ссылается данный объект класса
ENROLLMENT”11. Реляционный аналог этого выражения обычно включает две операции
соединения и одну операцию проекции. Иными словами, в результате прохождения пути
предоставляется доступ только по предварительно определенным путям (как в дореляци-
онных системах) и только к объектам предварительно определенных классов (опять же,
как в дореляционных системах).
Целостность базы данных
В главе 8 утверждалось, что целостность данных в базе имеет фундаментальное зна-
чение. Тем не менее даже те объектные системы, которые поддерживают произвольные
запросы, декларативные ограничения целостности обычно не поддерживают. Выполне-
ние подобных ограничений достигается с помощью процедурного кода, т.е. методов или *
На самом деле это выражение не является допустимым путем для базы данных, как мы ее оп-
ределили, поскольку указатели определяют неверное направление. Например, объекты класса OFFERING
не ссылаются на объекты класса COURSE: наоборот, объекты класса COURSE ссылаются на них.
974
Часть VI. Объектные и объектно-реляционные базы данных
прикладных программ. Рассмотрим, например, следующее ограничение (или “бизнес-
правило”) из раздела 8.5: “Поставщики со статусом меньше 20 не должны поставлять бо-
лее 500 деталей”. Для того чтобы обеспечить выполнение этого ограничения, в процеду-
ре ее реализации должны содержаться по крайне мере следующие методы.
Метод для создания объекта поставки
Метод для изменения количества поставляемых деталей
Метод для изменения статуса поставщика
Метод для переназначения некоторой поставки другому поставщику
При внимательном изучении этого примера можно отметить важные особенности.
1. При такой организации, очевидно, утрачивается возможность проверки соблюде-
ния ограничений целостности с помощью системы.
2. Как убедиться в том, что все эти методы содержат весь необходимый для поддерж-
ки целостности базы данных код?
3. Как, например, при создании объектного класса для поставок предостеречь пользо-
вателя от случайного пренебрежения методом “создания поставки” и ошибочного
непосредственного использования метода NEW (т.е. без проверки целостности)?
4. Как при изменении ограничений целостности найти и внести соответствующие из-
менения во все методы, в которых они были определены?
5. Как убедиться в корректности кода, с помощью которого приводятся в действие
ограничения целостности?
6. Как выполнить проверку целостности для отложенных (во время выполнения)
операций?
7. Как поступить с транзитными ограничениями?
8. Как узнать обо всех ограничениях, которые заданы для данного объекта или ком-
бинации объектов?
9. Будут ли ограничения целостности приводиться в действие во время загрузки сис-
темы или во время выполнения каких-либо других действий?
10. Можно ли осуществить семантическую оптимизацию (т.е. упростить запросы с по-
мощью ограничений целостности так, как описано в главе 17)?
Кроме того, как повлияют перечисленные выше особенности на производительность
работы во время создания приложения и при последующем его использовании?
Реализация связей
Термин “связи” используется в объектно-ориентированных продуктах и в соответст-
вующей литературе в основном для связей, представленных в реляционной базе данных
внешними ключами. Обычно предоставляется особая поддержка для ограничений цело-
стности специального вида. В качестве примера снова рассмотрим базу данных отделов
и сотрудников. В обычной реляционной системе сотрудники имели бы внешний ключ,
который ссылался бы на отделы, и этим можно было бы ограничиться. В объектных же
системах, напротив, имеется по крайней мере три возможности.
Глава 24. Объектные базы данных
975
1. Объекты сотрудников могут содержать идентификатор, который ссылается на
объекты отделов. Такая возможность хотя и аналогична реляционному подхо-
ду, но не идентична ему, поскольку внешние ключи и идентификаторы — это
не одно и то же.
2. Объекты отделов могут иметь набор идентификаторов, ссылающихся на объекты
сотрудников. Эта возможность соответствует подходу, использующему иерархию
вложения и описанному в разделе 24.3.
3. Кроме того, указанные выше подходы могут комбинироваться, как в следующих
определениях.
CLASS ЕМР ...
( ... DEPT REF ( DEPT ) INVERSE DEPT.EMPS ) ...
CLASS DEPT ...
( ... EMPS REF
( SET ( REF ( EMP ) ) ) INVERSE EMP.DEPT ) ... ;
Отметим, что ключевое слово INVERSE относится к двум переменным: ЕМР.DEPT и
DEPT.EMPS. Говорят, что эти две переменные являются обратными одна по отноше-
нию к другой. Переменная ЕМР. DEPT — это ссылочная переменная, a DEPT. EMPS —
переменная набора ссылок. (Если бы обе переменные были переменными набора
ссылок, то связь имела бы тип “многие ко многим”, а не “один ко многим”.)
Конечно, для каждой из указанных выше возможностей требуется определенного ви-
да поддержка ссылочной целостности (см. ниже). Однако прежде всего необходимо от-
ветить на вполне очевидный вопрос: как в объектных системах обрабатываются связи, в
которых используются два и более классов, например, поставщиков, деталей и проектов.
Наилучшим (т.е. наиболее симметричным) ответом на этот вопрос, конечно, будет соз-
дание объектного класса SPJ. Причем каждый объект класса будет обладать связями,
реализованными с помощью “обратных переменных”, с соответствующим поставщиком,
соответствующей деталью и соответствующим проектом. Если создание нового объект-
ного класса на основе трех объектов является наилучшим подходом для “связей” между
двумя и более объектами, возникает вопрос, почему бы не использовать его для связей
на основе двух объектов.
Кроме того, зачем нужно вводить асимметрию, задавать направленность и два разных
имени для одного и того же понятия? Например, рассмотрим два следующих реляцион-
ных выражения.
SP.P# WHERE SP.S# = S#('S1')
SP.S# WCodeHERE SP.P# = P#('P1')
Их объектные аналоги выглядят так.
S.PARTS.P# WHERE S.S# = S#('S1')
P.SUPPS.S# WHERE P.P# = P#('P1')
(Здесь использован некий гипотетический синтаксис, выбранный специально таким
образом, чтобы избежать несущественных в данном случае различий.)
976
Часть VI. Объектные и объектно-реляционные базы данных
Целостность на уровне ссылок
Рассмотрим уже упомянутую ранее объектную поддержку целостности на уровне
ссылок, которая, кстати, как часто утверждают, является сильной стороной объектных
систем. Уровни такой поддержки могут быть самыми разными; например, ниже приво-
дится классификация таких уровней, предложенная в работе Каттелла (Cattell) [24.11].
Отсутствие системной поддержки. За поддержку целостности на уровне ссылок
полностью несут ответственность пользователь и созданные им методы (как это,
между прочим, и было определено в исходном варианте стандарта языка SQL).
Проверка достоверности ссылки. В системе проверяется соответствие типа дан-
ных для объекта, на который задана ссылка. Однако в этом случае может быть за-
прещено удаление объектов (т.е. объекты, на которые нет ссылок, могут быть
“собраны вместе в мусорной куче”), как обусловлено в стандарте языка OPAL.
Как уже объяснялось в разделе 24.4, этот уровень поддержки эквивалентен (но
лишь весьма приблизительно) правилам каскадного удаления (ON DELETE
CASCADE) в иерархии для подчиненных объектов без возможности совместного
доступа и контролируемого удаления (ON DELETE RESTRICT) для других объектов
(но если только “указатели ссылаются в верном направлении”).
Системная поддержка. На этом уровне отслеживание и обновление ссылок про-
исходит автоматически (например, с помощью установки значения nil для ссылок
на удаленные объекты). Этот уровень в некоторой степени подобен правилу уда-
ления ON DELETE SET NULL, используемому в реляционной системе.
“Настраиваемая семантика”. Правило каскадного удаления ON DELETE CASCADE
(применяемое за пределами иерархии вложения) может рассматриваться как при-
мер “настраиваемой семантики”. К моменту написания этой книги такие действия
не поддерживались в объектных системах и должны были контролироваться соот-
ветствующими методами, т.е. с помощью процедур, созданных пользователем.
Языки программирования баз данных
Приведенные в предыдущей главе примеры на языке OPAL демонстрируют, что, в от-
личие от большинства современных реляционных программных продуктов (на основе язы-
ка SQL), в объектных системах обычно не используется “встроенный подъязык данных”.
Вместо этого для операций, выполняемых как с базами данных, так и с другими объектами,
используется один и тот же интегрированный язык. Согласно принятой в главе 2 терми-
нологии базовый язык и язык, ориентированный на работу с базами данных, в объектных
системах тесно связаны (фактически эти два языка образуют один и тот же язык).
Такой подход, безусловно, обладает определенными преимуществами12. Одно из са-
мых существенных— возможность осуществления усовершенствованной проверки ти-
пов [24.2]. В предлагаемой цитате из [24.47] отмечено еще одно важное достоинство.
“Благодаря простому единому языку не возникает никакого затруднения из-за не-
совпадения процедурного языка программирования и внутреннего языка, ориентиро-
ванного на обработку данных и обладающего декларативной семантикой. ”
12 В языке Tutorial D, который широко используется в данной книге, выбран такой же под-
ход. Соображения по этому поводу изложены в [3.3].
977
Глава 24. Объектные базы данных
Термин затруднения из-за несовпадения используется для описания различий между ти-
пичными современными языками программирования, функционирующими на основе после-
довательной обработки записей, и реляционными языками наподобие SQL, функционирую-
щими на основе последовательной обработки множеств. Очевидно, что такие различия на
практике приводят к возникновению разнообразных проблем в реляционных программных
продуктах. Но для их решения не нужно переводить язык, ориентированный на работу с база-
ми данных, на уровень последовательной обработки отдельных записей (именно такое реше-
ние реализовано в объектных системах!). Необходимо в языках программирования ввести ин-
струменты для последовательной обработки множеств записей. Применение последователь-
ной обработки отдельных записей в объектных языках (т.е. процедурный подход) отбрасыва-
ет нас к временам, когда использовались такие дореляционные системы, как IMS и IDMS.
В отношении последнего замечания следует отметить, что в действительности боль-
шинство существующих объектных языков является либо процедурными, либо языками
третьего поколения (3GL). В результате утрачиваются все преимущества реляционного
подхода на основе последовательной обработки множеств. В частности, заметно умень-
шается способность системы к оптимизации запросов пользователя, а значит, как и в до-
реляционных системах, производительность в значительной степени определяется самим
пользователем (разработчиком программы или администратором базы данных). Об этом
мы поговорим более подробно в следующем подразделе.
Повышение производительности
Низкая производительность— один из самых существенных недостатков всех объ-
ектных систем. И снова процитируем, несколько перефразировав, Каттелла [24.11]:
“Различие производительности на порядок реально может привести к функциональному
различию, поскольку для решения некоторых задач будет невозможно использовать дан-
ную систему, если ее производительность гораздо ниже требуемого уровня”.
Среди многочисленных факторов, влияющих на общую производительность системы,
можно отметить следующие13.
Кластеризация. Как сказано в главе 18, физическая кластеризация логически свя-
занных данных, размещенных на жестком диске, является одним из наиболее важ-
ных факторов повышения производительности системы. В объектных системах ло-
гическая информация из определений базы данных (относительно иерархии классов,
иерархии вложения или других явно заданных связей между объектами) обычно ос-
нована на макете системы и используется в качестве приблизительного плана для
физической кластеризации данных. Кроме того, часто рекомендуется, чтобы адми-
нистратор базы данных сам осуществлял явное и непосредственное управление ото-
бражением концептуального уровня на внутренний (по терминологии главы 2).
Кэширование. Объектные системы обычно используются в системах типа
“клиент/сервер”, в которых пользователи “копируют” на свои рабочие станции
информацию из базы данных на сервере и хранят ее на своих рабочих станциях в
течение некоторого времени. Очевидно, что в такой системе было бы полезно кэ-
шировать логически связанные данные на рабочем месте клиента.
Кроме перечисленных факторов, можно отметить, что в объектных системах произво-
дительность, дополнительная к той, которая существует на самом деле, достигается за счет
“приближения пользователя к компьютеру”, т.е. предоставления таких возможностей, как ука-
затели, которые должны быть скрыты в реализации.
978
Часть VI. Объектные и объектно-реляционные базы данных
Подмена. Термин “подмена” (swizzling) означает процесс замены указателей на-
подобие идентификаторов объекта, в качестве которых обычно используются ло-
гические дисковые адреса, адресами оперативной памяти при считывании объек-
тов в оперативную память (и наоборот, когда объекты записываются обратно в ба-
зу данных). Преимущества такого метода очевидны для приложений, в которых
обрабатываются достаточно “сложные объекты”, и поэтому необходимо часто
осуществлять поиск указателей.
Выполнение методов на сервере. В качестве примера рассмотрим запрос “Найти
все книги, в которых содержится более 20 глав”. В традиционной реляционной
системе книги могут быть представлены в виде объектов BLOB14, которые, по су-
ти, являются строкой байтов произвольной длины. При такой организации систе-
мы клиент вынужден извлекать каждую книгу и проверять, не содержит ли она
более 20 глав. Однако при наличии должной объектной поддержки на сервере мо-
жет быть выполнен некоторый специализированный метод “число глав”, а затем
клиенту будут переданы все требуемые книги15.
Замечание. Приведенные выше преимущества на самом деле являются аргументом
не в пользу объектных систем, а в пользу хранимых процедур (см. главы 8 и 21).
Традиционная реляционная система с хранимыми процедурами будет обладать в
этом случае таким же быстродействием, как и объектная система с методами.
В [24.13] обсуждается тестовая программа 001 для измерения производительности
системы на основе базы данных, содержащей информацию о счетах и материалах. Эта
программа выполняет следующие операции.
1. Случайное извлечение 1 000 деталей с применением заданного пользователем ме-
тода для каждой детали..
2. Случайная вставка 1 000 деталей с присоединением каждой к трем другим.
3. Случайное разузлование деталей (до семи уровней) с применением заданного поль-
зователем метода для каждой детали, подсчитывающего соответствующие вхожде-
ния в узлы.
Согласно данным, опубликованным в [24.13], производительность некоторой (не сказано,
какой) объектной системы на два порядка выше производительности некоторой (не сказано,
какой) современной реляционной системы, особенно при условии, что кэш уже заполнен дан-
ными (так называемый “теплый” доступ). Однако в той же работе отмечается следующее.
14 Замечание относительно объектов BLOB. Хотя такой тип данных не включен в стандарт
SQL/92, SQL-продукты традиционно предоставляют возможности обработки данных типа
BLOB в качестве основы для работы с “большими двоичными объектами" (binary large object).
Здесь объект понимается в общепринятом смысле, а не в том, который вкладывается в это по-
нятие в объектных системах. Данные типа BLOB представляют собой по существу просто ка-
кую-то строку байтов произвольной длины, для которой в системе предоставляется поддержка
с целью организации ее хранения и извлечения; этим вся поддержка и ограничивается. Физически
такие данные часто хранятся в специально отведенной для них области, отдельно от основной
области хранения данных тех отношений, которые логически содержат эти данные. Данные
типа BLOB могут занимать (и часто занимают) огромные области дискового пространства.
15 На самом деле это сверхупрощение: методы, которые поддерживают интенсивный обмен
данными, лучше выполняются на сервере; однако другие методы, т.е. те, которые преимущест-
венно отображают данные, может быть, лучше выполнять на компьютере клиента.
Глава 24. Объектные базы данных
979
“Это отличие... не следует приписывать различию между собственно реляци-
онной и объектными моделями... В основном, эти различия обусловлены [особен-
ностями реализации]. ”
Это утверждение может быть подкреплено тем фактом, что различия в производи-
тельности становились заметно меньше при увеличении размера базы данных (когда в
кэш нельзя было поместить всю базу данных).
Подобная, но более обширная, тестовая программа 007 описана в [24.10].
Является ли объектная СУБД действительно СУБД?
Замечание. В данном подразделе излагаются суждения и наблюдения, которые, в ос-
новном, взяты из [24.18]. В этой работе, помимо всего прочего, утверждается, что разли-
чия между объектными и реляционными системами гораздо существеннее, чем это
обычно представляется.
“Объектные базы данных возникли благодаря желанию отдельных програм-
мистов объектных приложений (продиктованному самыми разными причи-
нами) хранить созданные ими специализированные объекты в постоянной па-
мяти. При этом под такой “постоянной памятью ” могла подразумеваться и
база данных, но, что особо следует подчеркнуть, база данных, предназначен-
ная для специальных приложений; она не была разделяемой и не являлась ба-
зой данных общего назначения, предназначенной для приложений, особенно-
сти которых во время определения базы данных еще нельзя предвидеть в пол-
ном объеме. Потому многие возможности, которые профессионалами по ба-
зам данных расцениваются как существенные, просто не считались необхо-
димыми в объектном мире, по крайней мере изначально. ”
На первых порах создания объектных баз данных не было достаточного понимания
необходимости в том, чтобы базы данных предоставляли следующие возможности.
1. Совместный доступ со стороны нескольких приложений.
2. Физическая независимость данных.
3. Возможность выполнения произвольных запросов.
4. Поддержка представлений и логической независимости данных.
5. Поддержка декларативных ограничений целостности, независимых от приложений.
6. Поддержка прав владения данными и гибкий механизм обеспечения их защиты.
7. Управление совместным доступом.
8. Каталог общего назначения.
9. Возможность проектирования базы данных независимо от приложений.
“Впоследствии, после представления основной идеи хранения объектов в базе
данных, эти возможности были рассмотрены и реализованы как усовершенст-
вования и дополнения к исходной объектной модели... Один из важных выводов...
заключается в том, что объектная СУБД и реляционная СУБД— системы, ко-
торые различны по сути. На самом деле можно было бы доказать, что объ-
ектная СУБД фактически вовсе не является СУБД, по крайней мере в том
смысле, в котором это применимо к реляционной СУБД. ”
980
Часть VI. Объектные и объектно-реляционные базы данных
Для сравнения рассмотрим следующие замечания.
Реляционные СУБД поступают от изготовителя готовыми к использованию.
Иными словами, как только система установлена, пользователи могут начать
строить базы данных, писать приложения, запускать запросы и т.д.
Объектную же СУБД можно считать лишь некоторого рода набором средств по-
строения СУБД. После исходной установки объектная СУБД не готова к немед-
ленному использованию. Сначала она должна быть подогнана опытными специа-
листами, которые определят необходимые классы и методы, и т.п. Для этого пре-
доставляется набор строительных блоков — средства для сопровождения библио-
теки классов, компиляторы методов и т.д. Только после завершения такой подгон-
ки систему можно использовать прикладным программистам и пользователям.
Иными словами, результат такой подгонки уже будет больше походить на СУБД в
привычном смысле этого термина.
“Кроме того, отметим, что результат подгонки такой базы будет специ-
фическим для конкретных приложений. Эта система может подходить,
например, для приложений САПР/АСУТП, но быть совершенно непригодной,
например, для медицинских приложений. Иначе говоря, она все еще не стала
СУБД общего назначения в том смысле, в котором реляционная СУБД явля-
ется СУБД общего назначения. ’’
В той же статье [24.18] оспаривается так называемая идея устойчивой нечувстви-
тельности к типам из [24.2], в соответствии с которой в базу данных можно включать
(изменяемые) объекты произвольной сложности.
“Для объектной модели требуется поддержка [большого количества] генера-
торов типа... Например, таких типов, как структура (STRUCT), кортеж (TUPLE),
список (LIST), массив (ARRAY), набор (SET), пакет (BAG) и т.д... Вместе с иден-
тификаторами объектов наличие таких генераторов типов означает, что лю-
бая структура данных, которая может быть создана в программе приложения,
может быть также создана как объект в объектной базе данных, и, кроме того,
такая структура объектов видна пользователю. Например, рассмотрим объ-
ект (скажем, ЕХ), который является (или обозначает) коллекцией служащих в
отделе. Тогда объект ЕХможет быть реализован как связанный список или как
массив, и пользователи должны будут знать, как именно реализован этот объ-
ект, поскольку соответствующие операторы доступа отличаются. ”
Такая вседозволенность по отношению к типам данных, сохраняемых в базе дан-
ных, — главное отличие объектной модели от реляционной модели. По сути, подходы в
двух моделях можно сформулировать так.
В объектной модели можно сохранять все, что заблагорассудится, т.е. любые
структуры данных, которые можно создать с помощью механизмов обычного
языка программирования.
В реляционной модели, по существу, также можно сохранять все что угодно, од-
нако требуется, чтобы то, что сохраняется, было представлено для пользователя в
строго реляционной форме.
Глава 24. Объектные базы данных
981
"Выражаясь точнее, в реляционной модели почти совсем ничего не говорится о
том, как могут физически храниться данные... И следовательно, реляционная
модель не накладывает никаких ограничений на структуры данных, которые
допустимы на физическом уровне. Единственное требование заключается в
том, что, если какая-либо структура реально физически сохранена, она должна
отображаться в отношения на логическом уровне, а значит, быть скрытой от
пользователя. Таким образом, реляционные системы проводят четкую границу
между логическим и физическим представлениями, т.е. моделью данных и их
реализацией, а объектные системы этого не делают. И как следствие вопреки
обычному здравому смыслу объектные системы могут обеспечить значительно
меньшую независимость данных, чем реляционные системы. Предположим, на-
пример, что в некоторой объектной базе данных реализация упоминавшегося
объекта ЕХ, обозначающего коллекцию служащих в данном отделе, изменилась с
массива на связанный список. Каковы будут последствия для существующего
кода, с помощью которого осуществлялся доступ к объекту ЕХ? ”
24.6. Резюме
В завершение этой главы перечислим представленные в ней важнейшие понятия и
возможности объектной модели, давая им свою субъективную оценку: какие из них важ-
ны, какие “хороши”, но не существенны, какие “скверны”, а каким безразлично, какая из
систем используется — объектная или реляционная. Эти выводы будут служить мости-
ком для продолжения обсуждения объектно-реляционных систем в главе 25.
Классы объектов. Классы объектов соответствуют типам данных и, безусловно,
очень важны. По существу, это наиболее фундаментальная концепция из всех.
Объекты. Сами объекты, “изменяемые” и “неизменяемые”, очевидно, составляют
основу объектных систем, хотя мы предпочли бы их называть просто переменны-
ми и значениями соответственно.
Идентификаторы объектов. Не нужны и даже вредны (на уровне модели), по-
скольку по существу это указатели. См. [24.19], где этот вопрос рассматривается
подробно.
Инкапсуляция. Как уже отмечалось в разделе 24.2, “инкапсулированный” озна-
чает просто скалярный, и мы бы предпочли именно такой термин, всегда помня
при этом, что некоторые “объекты”, тем не менее, не являются скалярами.
Переменные экземпляра. Во-первых, закрытые (и защищенные) переменные эк-
земпляра по определению относятся к реализации, поэтому они не соответствуют
определению абстрактной модели, которую мы здесь рассматриваем. Во-вторых,
открытых переменных экземпляра не существует в чисто объектной системе, по-
этому они также здесь неуместны. Таким образом, приходим к заключению, что
переменные экземпляра можно игнорировать, а “объекты” должны обрабатывать-
ся исключительно “методами”.
Иерархия вложения. Как уже отмечалось в разделе 24.3, мы считаем, что поня-
тие иерархии вложения вводит в заблуждение и на самом деле является неверным,
поскольку речь идет о содержании идентификаторов, а не “объектов”.
982
Часть VI. Объектные и объектно-реляционные базы данных
Замечание. Иерархия (некапсулированная), которая действительно включала бы
объекты как таковые, могла бы быть возможной, хотя и противопоказанной. Это
могло бы быть аналогом чему-то, подобному переменной-отношению, имеющей
атрибуты, значением которых служат отношения (см. часть II и III этой книги).
Методы. Это, конечно, важное понятие, хотя мы предпочли бы более привычный
термин операторы. Но объединение методов с операторами не является обяза-
тельным и приводит к некоторым проблемам [3.3]. Раздельное определение
“классов” (типов) и “методов” (операторов), как было показано в главе 5, позволя-
ет обойтись без использования понятия объекта-получателя.
Существуют некоторые операторы, на включении которых мы бы настаивали:
операторы выборки, которые, кроме всего прочего, предоставляют возможность
записи литеральных значений соответствующего типа, операторы ТНЕ_, опера-
торы присвоения и сравнения на эквивалентность, а также операторы проверки
типа (см. главу 19).
Замечание. Однако мы бы отказались от функций-конструкторов. Конструкторы
создают переменные. А поскольку для нас единственными необходимыми пере-
менными в базе данных являются переменные-отношения, единственный “кон-
структор”, который нам нужен, — это оператор создания переменной-отношения,
т.е. CREATE TABLE или CREATE VIEW (по терминологии языка SQL). Операторы вы-
борки, наоборот, выбирают значения. Конечно, дополнительное отличие в том,
что конструкторы возвращают указатели на созданные переменные, в то время
как операторы выборки возвращают сами выбранные значения.
Сообщения. Это также одно из основных понятий, хотя мы предпочли бы более
привычный термин вызов. Опять же, можно обойтись без использования понятия
объекта-получателя, если отказаться от требования непосредственного обращения
к некоторому объекту-получателю, а считать все аргументы равноправными.
Иерархия классов. С иерархией классов связаны такие понятия, как наследова-
ние, полиморфизм, перегрузка, переопределение и т.д. Считаем, что понятие нуж-
ное, но производное. Мы рассматриваем поддержку иерархии классов как состав-
ляющую поддержки самих классов.
Классы, экземпляры, коллекции. Различия между этими понятиями, конечно,
существенные, но они касаются не только объектного подхода (здесь мы ограни-
чимся констатацией, что данные понятия различаются).
Связи. В главе 13 (раздел 13.6) уже оспаривалась идея трактовки “связей” как
формально отдельной конструкции (особенно если это лишь бинарная связь, ко-
торая и заслужила такую специальную трактовку). Мы также не считаем удачной
трактовку связанных ограничений ссылочной целостности, которая расходится с
трактовкой ограничений целостности вообще (см. ниже).
Интегрированные языки программирования баз данных. Весьма полезны, но
не относятся исключительно к объектной технологии. Тем не менее следует отме-
тить, что языки, которые поддерживаются современными объектными системами,
обычно являются процедурными (языки третьего поколения), поэтому, что можно
доказать, они неудачны (фактически это огромный шаг назад).
Глава 24. Объектные базы данных
983
Теперь перечислим возможности, которые в “объектных моделях” обычно не под-
держиваются или поддерживаются не в полной мере.
Произвольные запросы. В ранних версиях объектных моделей поддержка про-
извольных запросов обычно не предусматривалась, поскольку в той среде, в ко-
торой возникли объектные системы, в них не было особой необходимости. В
более поздних версиях появилась поддержка произвольных запросов, но для их
выполнения обычно требуется либо отказываться от инкапсуляции, либо вво-
дить ограничения на виды запросов, которые могут быть выполнены (думается,
что в последнем случае такие запросы вряд ли заслуживают того, чтобы назы-
ваться произвольными).
Представления. Обычно не поддерживаются (в основном по тем же причинам,
что и обработка произвольных запросов).
Замечание. В некоторых объектных системах поддерживаются “производные” или
“виртуальные” переменные экземпляра (обязательно открытые). Например, пере-
менная экземпляра AGE (возраст) может наследоваться с помощью вычитания зна-
чения переменной экземпляра BIRTH-DATE (дата рождения) от текущей даты. Од-
нако такая возможность еще очень далека от возможностей, которые предостав-
ляются с помощью механизма представлений; и кроме того, мы уже отказались от
понятия открытой переменной экземпляра.
Декларативные ограничения целостности. Обычно не поддерживаются (в ос-
новном, по тем же причинам, что и представления и обработка незапланирован-
ных запросов ). Более того, они обычно не поддерживаются даже теми системами,
которые поддерживают незапланированные запросы.
Внешние ключи. В “объектной модели” предусмотрено несколько разных мето-
дов поддержки целостности на уровне ссылок, ни один из которых не похож на
более универсальный метод внешних ключей, используемый в реляционной моде-
ли. Такие понятия, как ограниченное (ON DELETE RESTRICT) и каскадное (ON
DELETE CASCADE) удаления, обычно реализуются с помощью процедурного кода
(размещенного либо в методах, либо в коде приложений).
Замыкание. Сложно найти объектный аналог реляционному свойству замк-
нутости.
Каталог. Где же каталог в объектной системе? Как он выглядит? Есть ли какие-
либо стандарты?
Замечание. Конечно, это вопросы риторические. Каков будет реальный ре-
зультат, если такой каталог будет создан специалистом-профессионалом, ко-
торому будет поручено выполнить подгонку объектной СУБД, устанавливае-
мой для какого-либо приложения, как обсуждалось в разделе 24.5. (Такой ка-
талог будет специфическим для данного приложения, как, впрочем, и вся на-
строенная СУБД.)
Подытожив сказанное выше, можно отметить полезные (существенные, фундамен-
тальные) понятия и концепции “объектной модели” (такие, которые желательно под-
держивать).
984
Часть VI. Объектные и объектно-реляционные базы данных
Понятие
Класс объекта
Неизменяемый объект
Изменяемый объект
Метод
Предпочтительный
термин__________
Тип
Значение
Переменная
Оператор
Сообщение
Вызов оператора
Замечания
Скаляр и нескаляр; может опре-
деляться пользователем
Скаляр и нескаляр
Скаляр и нескаляр
Включает операторы выборки,
операторы “ТНЕ_”, “=” и
оператор проверки типа
Никаких “целевых” операндов
Более кратко можно сказать, что единственная хорошая идея объектных систем в це-
лом — это надлежащая поддержка типов данных (все остальное, включая понятия
операторов, определяемых пользователем, следует из этой идеи)16. Но данную идею вряд
ли можно назвать новой!
Упражнения
24.1. Дайте определения следующим терминам.
закрытая переменная экземпляра
защищенная переменная экземпляра
идентификатор объекта
иерархия вложения
иерархия классов
инкапсуляция
класс
метод
обратная переменная
открытая переменная экземпляра
объект
объект, определяющий класс
сообщение
функция конструктора
24.2. В чем заключаются недостатки и преимущества использования идентификаторов
объектов? Каким образом можно реализовать идентификаторы?
24.3. В разделе 24.2 были представлены две формулировки SQL-запроса “Найти все пря-
моугольники, которые покрывают какую-нибудь область квадрата (0, 0, 1, 1)”. До-
кажите, что эти формулировки эквивалентны.
24.4. Исследуйте любую доступную вам объектную СУБД. Какой язык программирова-
ния поддерживается в этой системе? Поддерживается ли в ней язык запросов? Ес-
ли поддерживается, то какой? Является ли он, по вашему мнению, более мощным,
чем язык SQL? Как организован каталог системы? Как пользователь опрашивает
каталог? Предусмотрена ли в этой системе поддержка представлений? Если преду-
смотрена, то в какой степени (например, поддерживается ли в ней обновление
представлений)? Как обрабатывается “отсутствующая информация”?
24.5. Составьте макет объектной версии используемой в этой книге базы данных по-
ставщиков и деталей.
Замечание. Этот макет будет использоваться как основа для приведенных ниже
упр. 24.6-24.8.
16 Кое-кто может возразить, что наследование типа — также хорошая идея. Мы против
этого не возражаем, а лишь настаиваем на том, что поддержка наследования не относится ис-
ключительно к поддержке объектов как таковых.
Глава 24. Объектные базы.данных
985
24.6. Составьте подходящий набор утверждений определения данных на языке OPAL
для объектной версии базы данных поставщиков и деталей.
24.7. Схематически обрисуйте детали методов “пополнения базы данных” объектной
версии базы данных поставщиков и деталей.
24.8. Составьте код на языке OPAL для реализации приведенных ниже запросов в объ-
ектной версии базы данных поставщиков и деталей.
а) Выбрать сведения обо всех поставщиках, находящихся в городе 'London'.
б) Выбрать сведения обо всех деталях красного цвета ('Red').
24.9. Еще раз рассмотрите образовательную базу данных. Покажите, какие объекты бу-
дут задействованы при выполнении следующих процедур.
а) Удаление слушателя
б) Удаление служащего
в) Удаление курса
г) Удаление класса слушателей
д) Удаление класса служащих
Подразумевается, что в каждом случае используется механизм автоматической
сборки мусора языка OPAL. Приведите любые допущения, которые необходимо
сделать относительно таких аспектов, как организация каскадного удаления и др.
24.10. Допустим, что база данных поставщиков, деталей и проектов организована с ис-
пользованием простой объектной иерархии вложения. Сколько таких иерархий
можно реализовать? Какая из них является наилучшей?
24.11. Рассмотрите вариант базы данных поставщиков, деталей и проектов, в котором вме-
сто записей о том, что некоторые поставщики поставляют некоторые детали для не-
которых проектов, содержатся записи о том, что некоторые поставщики поставляют
некоторые детали, некоторые детали поставляются для некоторых проектов и неко-
торые проекты обеспечиваются деталями от некоторых поставщиков. Сколько таких
объектных макетов можно реализовать (с учетом или без учета иерархии вложения)?
24.12. Опишите основные факторы, оказывающие влияние на производительность объ-
ектных систем и кратко обсуждавшиеся в разделе 24.5. Справедливо ли утвержде-
ние, что они характерны только для объектных систем? Обоснуйте свой ответ.
24.13. В объектных системах ограничения целостности обычно поддерживаются процедур-
но, т.е. с помощью методов, за исключением ограничений целостности на уровне
ссылок, которые обычно поддерживаются, по крайней мере частично, декларативно.
В чем состоит преимущество процедурного способа поддержки ограничений целост-
ности? Почему ограничения целостности на уровне ссылок поддерживаются иначе?
24.14.Объясните смысл концепции обратных переменных.
Список литературы
Публикации [24.5], [24.7], [24.11], [24.15], [24.26], [24.31], [24.38], [24.41] и [24.50] пред-
ставляют собой книги по объектной тематике и связанным с ней вопросам. Публикации
[24.35], [ 24.36] и [24.52] — это сборники научно-исследовательских работ, а [24.27], [
24.28], [24.44] и [24.47]— учебные пособия. В работах [24.4], [24.9], [24.23] и [24.37]
описываются конкретные системы.
986
Часть VI. Объектные и объектно-реляционные базы данных
24.1. Atkinson M.P. et al. The Object-Oriented Database System Manifesto // Proc. 1st Int.
Conf, on Deductive and Object-Oriented Databases. — Kyoto, Japan, 1989. New York,
N.Y.: Elsevier Science. — 1990.
Одна из первых попыток достичь согласия по вопросу, что же должна включать в
себя “объектная модель”. Предлагаются следующие обязательные возможности
(т.е., по мнению автора, возможности, которые должны поддерживаться, если рас-
сматриваемая СУБД заслуживает называться “объектно-ориентированной”).
1. Коллекции
2. Объектные идентификаторы
3. Инкапсуляция
4. Типы или классы
5. Наследование
6. Позднее связывание
7. Вычислительная полнота
8. Типы, определяемые пользователем
9. Устойчивость
10. Поддержка больших баз данных
11. Параллельный доступ к данным
12. Восстановление
13. Произвольные запросы
Также обсуждаются необязательные возможности, включая множественное насле-
дование и проверку типов на этапе компиляции; некоторые открытые возможно-
сти, включая “парадигмы программирования”; вопросы, по которым авторы не
смогли достичь согласия, включая (как это ни странно, учитывая их важность)
представления и ограничения целостности.
Замечание. В [3.3] и [25.34] комментируется эта статья. Относительно коммента-
риев в [3.3] необходимо отметить, что они основываются на предпосылке, что на-
значение статьи — определить свойства лучших, настоящих СУБД общего назна-
чения. Мы не отрицаем, что перечисленные выше свойства могут быть полезны
для специализированных СУБД, которые связаны с конкретным приложением, на-
пример САПР/ОАСУП, для которого не требуется, скажем, поддержка ограниче-
ний целостности. Однако тогда возникает вопрос, является ли такая система сис-
темой управления базами данных в полном смысле этого понятия.
24.2. Atkinson М.Р., Buneman О.Р. Types and Persistence in Database Programming
Languages // ACM Comp. Surv. — June, 1987. — 19, № 2.
Одна из ранних статей, если не самая ранняя, в которой формулируется точка зре-
ния, согласно которой перманентность в языках программирования баз данных не
должна зависеть от типов. Эта статья рекомендуется в качестве вводного пособия
по изучению языков программирования баз данных в целом (“языки программиро-
вания баз данных” многими воспринимались как необходимое условие объектных
систем; см., например, [24.11], [24.12]).
24.3. Bancilhon F. A Logic-Programming/Object-Oriented Cocktail // ACM SIGMOD. —
September, 1986. — 15, № 3.
Цитата из введения: “Объектно-ориентированный подход... кажется наиболее приемле-
мым для управления такими новыми типами приложений, как САПР, для разработки
программного обеспечения и для исследований в области искусственного интеллекта.
Однако естественное расширение управления базами данных до реляционной методики
является... не объектно-ориентированной, а логической программной парадигмой. В
данной статье рассматривается возможность совмещения этих двух парадигм”. Отсюда
с некоторой долей предосторожности можно заключить, что они совместимы.
Глава 24. Объектные базы данных
987
Замечание. В [24.49] предлагается противоположная точка зрения.
24.4. Banerjee J. et al. Data Model Issues for Object-Oriented Applications // ACM TOOIS
(Transaction on Office Information Systems). — March, 1987. — 5, № 1. (Эта работа
также опубликована в М. Stonebraker (ed.). Readings in Database Systems. — San
Mateo, Calif: Morgan Kaufmann, 1994, а также в [24.52].)
24.5. Barry D.K. et al. The Object-Oriented Database Handbook: How to Select, Implement, And
Use Object-Oriented Databases. —New York, N.Y.: John Wiley and Sons. — 1996.
Основная мысль этой книги заключается в том, что если мы имеем дело со
“сложными данными”, необходима объектная система, а не реляционная. Сложные
данные характеризуются как а) вездесущие, б) зачастую с недостаточной уникаль-
ной идентификацией, в) с использованием многочисленных связей типа “многие ко
многим” и г) часто требующие использования кодов типов “в реляционной схеме”
(поскольку в современных SQL-продуктах имеется недостаточная непосредствен-
ная поддержка для подтипов и супертипов).
Замечание. Автор является исполнительным директором группы Object Data
Management Group (ODMG) [24.12].
24.6. Beech D. A Foundation for Evolution from Relational to Object Databases // Schmidt, Ceri,
Missikoff. Extending Database Technology. —New York, N.Y.: Springer Verlag, 1988.
Это одна из многих статей, в которых обсуждались возможности расширения язы-
ка SQL до некоторой разновидности “объектного SQL” (необходимо предупредить
читателя, что такой “объектный SQL” часто не очень похож на привычный SQL).
Более подробно этот вопрос рассматривается также в [24.39].
24.7. Bertino Е., Martino L. Object-Oriented Database Systems: Concepts and
Architectures. — Reading, Mass.: Addison-Wesley, 1993.
24.8. Bjomerstedt A., Hulten C. Version Control in an Object-Oriented Architecture.
(Опубликована в [24.36].)
Для многих приложений необходима концепция отдельных версий данного объек-
та. Примерами таких приложений могут служить разработки программного обес-
печения, проекты аппаратных средств, создание документов и т.д. И некоторые
объектные системы поддерживают эту концепцию непосредственно (хотя на самом
деле данная концепция не связана именно с объектной системой или с какой-либо
другой). Такая поддержка обычно включает следующее.
Возможность создания новой версии данного объекта, обычно с помощью
оформления выдачи копии объекта и ее пересылки из базы данных на собст-
венную рабочую станцию пользователя, где эта копия может корректироваться
в течение продолжительного времени (например, несколько часов или дней).
Возможность получения версии данного объекта как версии текущей базы
данных, обычно с помощью ее регистрации (сдачи на хранение) и пере-
сылки с рабочей станции пользователя обратно в базу данных, для кото-
рой, в свою очередь, может потребоваться некоторый механизм слияния
отдельных версий.
Возможность удаления и, возможно, архивирования устаревших версий.
Возможность запроса истории версий данного объекта.
988
Часть VI. Объектные и объектно-реляционные базы данных
Заметим, что, как показано на рис. 24.7, истории версий не обязательно связаны
линейно (из версии V. 2 образуются две разные версии, V. За и V. ЗЬ, которые затем
сливаются в версию V.4).
Поскольку объекты обычно взаимосвязаны различными способами, концепция
версий приводит к концепции конфигураций. Конфигурацией называется коллек-
ция взаимно согласованных версий взаимосвязанных объектов. Причем под этим
подразумевается выполнение некоторых основных операций.
Возможность копирования версии объекта из одной конфигурации в другую
(например, из “старой” конфигурации в “новую”).
Возможность перемещения версии объекта из одной конфигурации в другую
(т.е. ее вставки в “новую” конфигурацию и удаления из “старой”).
Для реализации таких возможностей требуется выполнить довольно много опера-
ций с указателями, что оказывает значительное влияние на синтаксис и семантику
языка вообще и на средства выполнения произвольных запросов в частности. Опи-
сание последствий такой реализации выходит за рамки этой книги, впрочем мате-
риал главы 22 имеет некоторое отношение к данному вопросу.
24.9. Butterworth Р., Otis A., Stein J. The GemStone Object Database Management System //
CACM. — October, 1991. —34, № 10.
24.10. Carey M.J., DeWitt D.J., Naughton J.F. The 007 Object-Oriented Databases Benchmark
11 Proc. 1993 ACM SIGMOD Int. Conf, on Management of Data. — Washington, DC,
May, 1993.
24.11. Cattell R.G.G. Object Data Management (пересмотренное издание).— Reading,
Mass.: Addison-Wesley, 1994.
Первое подробное учебное пособие по применению объектной технологии специ-
ально для систем управления базами данных. Цитируемый ниже текст дает пред-
ставление о том, что какая-либо форма единства мнений в этой области еще не
достигнута: “языкам программирования может понадобиться новый комбиниро-
ванный синтаксис... подстановка, репликация и новые методы доступа также нуж-
даются в дальнейшем исследовании... требуются новые инструменты пользователя
и средства разработки прикладных программ... необходимо разработать более
мощные языки составления запросов... необходимо исследовать управление парал-
лельностью... создание временных отметок и семантика параллельности в терми-
нах объектов также нуждаются в более детальном исследовании... необходимы мо-
дели оценки производительности... новые исследования в области управления зна-
ниями следует интегрировать с инструментами управления объектами и данными...
Глава 24. Объектные базы данных
989
это приведет к сложным проблемам оптимизации, и лишь некоторые исследовате-
ли обладают необходимым опытом... объединенные [объектные] базы данных тре-
буют более глубокого изучения”.
24.12. Cattell R.G.G., Barry D.K. The Object Database Standard: ODMG 2.0.— San
Francisco, Calif.: Morgan Kaufmann, 1997.
Термин ODMG, говоря нестрого, обозначает проекты группы Object Data Management
Group, консорциума представителей “членов компаний, [охватывающих] почти всю от-
расль объектных СУБД”. Эти проекты включают объектную .модель, объектный язык оп-
ределений (ODL), объектный формат обмена (OIF), объектный язык запросов (OQL) и
привязки этих возможностей к языкам C++, Smalltalk и Java. (Компонент “язык обработки
объектов” отсутствует, а вместо него предоставляются возможности обработки объектов с
помощью любого языка, для которого ODMG предоставляет привязку.)
Детальный анализ и критику объектной модели ODMG можно найти в [3.3]; к это-
му вопросу также имеет отношение [24.34].
24.13. Cattell R.G.G., Skeen J. Object Operations Benchmark // ACM TODS. — March,
1992. — 17, № 1.
24.14. Copeland G., Maier D. Making Smalltalk a Database System // Proc. 1984 ACM
SIGMOD Intern. Conf, on Management of Data.— Boston, Mass.,— June, 1984.
(Переиздано: M. Stonebraker. Readings in Database Systems (2-е изд.). — San Mateo,
Calif.: Morgan Kaufmann, 1994.)
В работе описаны некоторые усовершенствования и изменения, внесенные в язык
Smalltalk [24.26] при создании СУБД GemStone и языка OPAL.
24.15. Cox B.J. Object Oriented Programming: An Evolutionary Approach. — Reading, Mass.:
Addison-Wesley, 1986.
Учебное пособие по использованию объектных методов в области программирова-
ния. Некоторое внимание в нем уделяется применению этих методов для разработ-
ки программного обеспечения.
24.16. Dahl O.J., Myhrhaug В., Nygaard К. The SIMULA 67 Common Base Language. Pub.
S-22. — Oslo, Norway: Norwegian Computing Center, 1970.
Язык SIMULA 67 спроектирован специально для создания имитационных прило-
жений. Именно на основе таких языков программирования и была создана объект-
ная технология. Фактически язык SIMULA 67 был первым объектным языком.
24.17. Date C.J. An Optimization Problem // C.J. Date and Hugh Darwen. Relational Database
Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.
24.18. Date C.J. Why the Object Model’ Is Not a Data Model // Date C.J., Darwen H. and
McGoveran D. Relational Database Writings 1994-1997.— Reading, Mass.:
Addison-Wesley, 1998.
24.19. Date C.J. Object Identifiers vs. Relational Keys // Date C.J., Darwen H. and McGoveran
D. Relational Database Writings 1994-1997. — Reading, Mass.: Addison-Wesley, 1998.
24.20. Date C.J. Encapsulation Is a Red Herring // DBP&D. — September, 1998. — 12, № 9.
В этой главе уже упоминалось о том, что следствием инкапсуляции является неза-
висимость данных. Но мы также указывали, что предпочли бы не использовать
термин “инкапсуляция”, а заменили бы его термином скаляр. С другой стороны,
“инкапсулированные объекты” не могут предоставить дополнительную независи-
990
Часть VI. Объектные и объектно-реляционные базы данных
мость по сравнению с той, которую могут предоставить не инкапсулированные от-
ношения (по крайней мере, в принципе). Например, нет абсолютно никаких причин
для того, чтобы базовое отношение, которое представляет точку в декартовой сис-
теме координат X и Y, нельзя было хранить, используя полярные координаты R и 0.
24.21. Date C.J. Persistence Not Orthogonal to Type // DBP&D website www.dbpd.com.—
October, 1998.
24.22. Date C.J. Decent Exposure // DBP&D website www.dbpd.com. —November, 1998.
24.23. Deux O. et al. The 02 System // CACM. — October, 1991. — 34, № 1.
24.24. Ferrandina F., Meyer T., Zicari R., Ferran G., Madec J. Schema and Database Evolution
in the 02 Object Database System // Proc. 21st Int. Conf, on Very Large Data Bases. —
Zurich, Switzerland, September, 1995.
См. аннотацию к [24.43].
24.25. Frohn J., Lausen G., Uphoff H. Access to Object by Path Expressions and Rules // Proc.
20th Int. Conf, on Very Large Data Bases. — Santiago, Chile, September, 1994.
24.26. Goldberg A., Robson D. Smalltalk-80: The Language and its Implementation. —
Reading, Mass.: Addison-Wesley, 1983.
Перечень передовых исследований специалистов из исследовательского цен-
тра фирмы Xerox в Пало Альто, посвященных проектированию и созданию
системы Smalltalk-80. В первой из четырех частей этой книги подробно опи-
сывается язык программирования Smalltalk-80, на котором основаны язык
OPAL и система GemStone.
24.27. Goodman N. Object Oriented Database Systems // InfoDB. — 1989. — 4, № 3.
В предыдущих изданиях данной книги приводилась следующая цитата из этой ста-
тьи. “На данном этапе не имеет смысла сравнивать реляционный и объектный под-
ходы. Следует сравнивать лишь подобные понятия, например яблоки с яблоками,
мечты с мечтами, теорию с теорией и зрелые продукты со зрелыми продуктами...
Некоторое время реляционный подход использовался потому, что имел строгий
теоретический базис и лежал в основе большого количества добротных программ-
ных продуктов. Объектный подход, наоборот, является новым (по крайней мере в
области создания баз данных). Он не обладает той теоретической основой, которая
сравнилась бы с реляционной моделью, и немногие программные продукты, соз-
данные на его основе, могут быть охарактеризованы как добротные. Таким обра-
зом, прежде чем заявить об объектном подходе как об альтернативе реляционному
подходу, придется выполнить очень большой объем работы.”
Несмотря на то что большая часть высказанных здесь замечаний еще остается в
силе, все же со времени предыдущего издания этой книги некоторые неясные
прежде вопросы несколько прояснились. Во многих сравнениях реляционные и
объектные системы уже могут рассматриваться, как “яблоки и апельсины”, в чем
мы убедимся в главе 25.
24.28. Goodman N. The Object Database Debate, The Object Data Model, The Object Data
Model in Action // InfoDB. — 1990-1991.— 5, №4; InfoDB. — 1990-1991.— 6,
№ 1; InfoDB. — 1991. —6, №2.
24.29. Goodman N. Object Oriented DBMS War Story: Developing a Genome Mapping
Database in C++ (опубликовано в [24.35]).
Глава 24. Объектные базы данных
991
В статье поддерживаются многие критические замечания, которые были высказа-
ны в этой главе. Далее приводится цитата из резюме статьи. “Вопреки распростра-
ненному мнению, наш опыт подсказывает, что было бы ошибкой создавать слиш-
ком интеллектуальные базы данных с помощью сложных программ в виде методов
внутри объектов базы данных. Также наш опыт свидетельствует о том, что язык
C++ — это язык, который подходит исключительно для реализации баз данных, с
проблемами, связанными с механизмами определения атрибутов, механизмами ус-
тановления ссылок на объекты систематическим путем, недостатками при “сборке
мусора” и тонкими ловушками в модели наследования. Мы также считаем, что со-
временным СУБД, основанным на C++, недостает некоторых важных функций баз
данных, и чтобы это компенсировать, нам пришлось предоставлять собственные
простые реализации стандартных функций СУБД: ведения журнала транзакций для
прямого восстановления, отслеживания многопоточных транзакций, язык запросов
и процессор запросов, а также структуры памяти. В результате мы использовали
СУБД, основанную на C++, как объектно-ориентированный диспетчер памяти и,
кроме того, встроили систему управления данными, предназначенную для широ-
комасштабного геномного отображения.”
24.30. Jagadish H.V., Xiaolei Q. Integrity Maintenance in an Object-Oriented Database // Proc
18th Int. Conf, on Very Large Data Bases. — Vancouver, Canada, August, 1992.
В работе предлагается декларативный метод указания ограничений целостности для
объектных систем. При этом описывается, как компилятор ограничений помещает в
методы соответствующих объектных классов необходимый код проверки целостности.
24.31. Jordan D. C++ Object Databases: Programming with the ODMG Standard. — Reading,
Mass.: Addison-Wesley, 1997. (Имеется русский вариант этой книги: Джордан Д.
Обработка объектных баз данных в C++. Программирование с использованием
стандарта ODMG.: Пер. с англ. — М.: Издательский дом “Вильямс”, 2001.)
24.32. Kifer М., Kim W., Sagiv Y. Querying Object-Oriented Databases // Proc. ACM
SIGMOD Int. Conf, on Management of Data. — San Diego, Calif., June, 1992.
В работе предлагается еще один “объектный вариант языка SQL” под названи-
ем XSQL.
24.33. Kim W. Object-Oriented Database Systems: Promises, Reality, and the Future // Proc.
19th Int. Conf, on Vary Large Data Bases. — Dublin, Areland, August, 1993.
24.34. Kim W. Observations on the ODMG-93 Proposal for an Object-Oriented Database
Language // ACM SIGMOD Record. — March, 1994. — 23, № 1.
24.35. Kim W. Modem Database Systems: The Object Model, Interoperability, and Beyond. —
New York, N.Y.: ACM Press/Reading, Mass.: Addison-Wesley, 1995.
24.36. Kim W., Lochovsky F.H. Object-Oriented Concepts, Databases and Applications. —
Reading, Mass.: Addison-Wesley, 1989.
24.37. Lamb C., Landis G., Orenstein J., Weinreb D. The Objectstore Database System //
CACM. — October, 1991. — 34, № 10.
24.38. Loomis M.E.S. Object Databases: Essentials. — Reading, Mass.: Addison-Wesley, 1995.
24.39.Lyngbaek P. et al. OSQL: Language for Object Databases. — Technical Report HPL-
DTD-91-4. — Hewlett-Packard Company, January, 1991.
См. комментарий к [24.6].
992
Часть VI. Объектные и объектно-реляционные базы данных
24.40. Meyer В. The Future of Object Technology // IEEE Computer. — January, 1998. — 31, № 1.
“Будущее [объектных] баз данных — это интересная тема для размышлений... Из-
готовители реляционных баз данных с 1986 года старались подавить рост
[объектных] баз данных с помощью упреждающих извещений... Десять лет спустя
эксперты [объектных баз данных] будут говорить вам, что предложения от основ-
ных производителей реляционных СУБД... еще далеки от реальных потребностей...
Рынок объектных баз данных будет продолжать расти, но часть рынка традицион-
ных баз данных останется.”
24.41. Parsaye К., Chignell М., Koshafian S., Wong Н. Intelligent Databases.— New York,
N.Y.: John Wiley & Sons, 1989.
24.42. Poulovassilis A., Small C. Investigation of Algebraic Query Optimisation for Database
Programming Languages // Proc. 20th Int. Conf, on Vary Large Data Bases. — Santiago,
Chile, September, 1994.
24.43. Roddick J.F. Schema Evolution in Database Systems— An Annotated Bibliography //
ACM SIGMOD. — December, 1992. — Record 21, № 4.
В традиционных СУБД обычно поддерживаются только очень простые изменения
существующего макета СУБД (например, добавление нового атрибута к сущест-
вующей базовой переменной-отношению). Однако в отдельных случаях требуется
выполнить более сложные изменения, и в некоторых объектных прототипах эта
проблема исследована достаточно глубоко. Причем в случае объектной системы
она становится более сложной, поскольку сама по себе такая система имеет более
сложный макет.
В [24.4] обсуждается система ORION, которая служит прототипом объектной систе-
мы, и приводится перечень основных возможных изменений макета. Отметим, что
некоторые из них (какие?) вводят в заблуждение, не отличая модель от реализации.
Изменения объектного класса
1. Изменения переменной экземпляра:
добавление переменной экземпляра;
удаление переменной экземпляра;
переименование переменной экземпляра;
изменение принятого по умолчанию значения переменной экземпляра;
изменение типа данных переменной экземпляра;
изменение источника наследования переменной экземпляра.
2. Изменения метода:
добавление метода;
удаление метода;
переименование метода;
изменение кода метода;
изменение источника наследования метода.
Изменения в иерархии классов (предполагается множественное наследование):
добавление класса А к списку суперклассов класса В;
удаление класса А из списка суперклассов класса В.
Глава 24. Объектные базы данных
993
Изменения общего макета:
добавление класса (в произвольном месте);
удаление класса (в произвольном месте);
переименование класса;
разбиение класса;
слияние классов.
Поскольку поддержка представлений обычно не включается в “объектную мо-
дель”, не совсем ясно, насколько сильным окажется влияние таких изменений на
прозрачность системы. Возможность внесения изменений в макет системы пред-
ставляет собой достаточно сложную проблему именно из-за того, что в объектных
системах осуществляется последовательная обработка записей. Как отмечается в
[24.34], если при внесении изменений индексы или данные распределены по раз-
ным группам (кластерам), то никаких способов автоматически получить преиму-
щества от таких изменений с помощью методов не существует.
Более того, постепенное развитие схемы является еще одним требованием объект-
ной системы, поскольку многие решения, которые могли бы быть решениями ад-
министратора базы данных (или даже решениями СУБД!) в реляционной базе дан-
ных, в объектной системе становятся решениями программиста приложения (см.
[24.44]). В частности, приведение в соответствие производительности системы
может также повлечь перепроектирование макета (опять же, см. [24.44]).
24.4 4.Saracco С.М. Writing an Object DBMS Application (в двух частях) // InfoDB.—
1993-1994. — 7, № 4; InfoDB. — 1994. — 8, № 1.
Приводятся несложные, но достаточно полные и информативные примеры программ.
24.4 5.Shaw G.M., Zdonik S.B. A Query Algebra for Object-Oriented Databases // Proc. 6th
IEEE Int. Conf, on Data Engineering. — February, 1990. (Опубликована также в виде
технического отчета: Technical Report TR CS-89-19, Dept, of Computer Science.—
Providence, R.I.: Brown University, March, 1989.)
Эта статья подтверждает мнение автора данной книги о том, что “любая объектная
алгебра” является сложной из-за сложной организации самих объектов. В частно-
сти, для выполнения операции сравнения иерархических объектов с произвольной
сложностью вложенных уровней потребуется очень тщательная организация всего
этого процесса. Основная идея статьи заключается в том, что каждый оператор ал-
гебры запросов приводит к созданию отношения, каждый кортеж которого содер-
жит идентификаторы некоторых объектов базы данных. В случае операции соеди-
нения, например, каждый кортеж будет содержать идентификаторы объектов, ко-
торые соответствуют друг другу для заданного условия соединения. Эти кортежи
не наследуют никаких методов объектов-компонентов.
24.4 6.Shipman D.W. The Functional Data Model and the Data Language DAPLEX // ACM
TODS.— March, 1981.— 6, № 1. (Переиздано: M. Stonebraker (ed.). Readings in
Database Systems (2-nd edition). — San Mateo, Calif.: Morgan Kaufmann, 1994.)
Существует несколько попыток создания систем, в основе которых вместо отноше-
ний используются функции, и среди них наиболее известной является система
DAPLEX. Функциональные подходы обладают некоторыми чертами, характерными
для объектных систем, включая, в частности, стиль адресации объектов (с помощью
994
Часть VI. Объектные и объектно-реляционные базы данных
указания пути), которые функционально относятся к другим объектам (которые, в
свою очередь, также относятся к другим объектам, и т.д.)- Обратите внимание, одна-
ко, что термин “функция” в этих так называемых функциональных моделях не имеет
никакого отношения к математической функции. Например, такая функция вполне
может быть многозначной. Практически традиционное понятие функции должно
претерпеть значительные изменения для того, чтобы удовлетворить всем требовани-
ям, которые предъявляются в контексте “функциональной модели данных”.
24.4 7.Stein J., Maier D. Concepts in Object-Oriented Data Management // DBP&D. — April,
1988, — 1,№ 4.
Прекрасный учебный материал по объектным концепциям, представленный созда-
телями системы GemStone.
24.48. Tsichritzis D.C., Nierstrasz О.М. Directions in 00 Research (опубликовано в [24.36]).
В этой статье также подтверждается высказанная автором настоящей книги мысль
об отсутствии единства мнений в области объектных подходов: “...разногласия су-
ществуют по самым основным понятиям, например: “Что такое объект?.. ”. Однако
причин для беспокойства нет, поскольку нестрогие определения неизбежны, а по-
рой они даже крайне желательны во время динамичного развития научных иссле-
дований. Они должны стать и неизбежно станут строгими спустя некоторое вре-
мя”. Однако объектные концепции известны уже более 30 лет! — фактически они
предшествовали реляционной модели.
24.49. Ullman J.D. A Comparison between Deductive and Object-Oriented Database Systems //
Proc. 2nd Int. Conf, on Deductive and Object-Oriented Databases. — Munich, Germany,
December, 1991. Delober C., Kifer M., Masunaga Y. (eds). Lecture Notes in Computer
Science 566. — New York, N.Y.: Springer Verlag, 1992.
Хотя мы и не согласны по многим отдельным вопросам, представленным в данной ста-
тье, мы согласны с общим выводом, что “дедуктивная” (т.е. основанная на логике) сис-
тема баз данных имеет большие перспективы по сравнению с объектными системами.
В статье также затронут важный вопрос относительно возможностей оптимизации
систем. Предположим, что мы определили “какой-то объектный класс, поведение кото-
рого такое же, как поведение бинарных отношений, и... метод join (соединение) для
этого класса, тогда можно записать, например, выражение R JOIN S JOIN Т. Его мож-
но вычислять как (R JOIN S) JOIN Т или как R JOIN (S JOIN Т). Но сможем ли мы
это сделать? Никто не определял, что означает метод join. Является ли он, например,
ассоциативным?.. Отсюда можно сделать вывод, что если мы желаем программировать,
используя объектную технологию, оставаясь на уровне отношений или выше, то необ-
ходимо предоставить системе информацию в виде законов реляционной алгебры. Такая
информация не может быть выведена системой, но может быть встроена в нее. Таким
образом, ...единственной частью языка запросов, которая будет поддаваться оптимиза-
ции, является фиксированное множество методов, для которых... соответствующая се-
мантика предоставлена системе”.
24.50. Vossen G. Data Models, Database Languages, and Database Management Systems. —
Reading, Mass.: Addison-Wesley, 1991.
24.51. Zaniolo C. The Database Language GEM // Proc. 1983 ACM SIGMOD Int. Conf, on
Management of Data. — San Jose, Calif., May, 1983. (Переиздано: M. Stonebraker. Readings in
Database Systems (2-nd edition). — San Mateo, Calif.: Morgan Kaufmann, 1994.)
Глава 24. Объектные базы данных
995
Аббревиатура GEM (General Entity Manipulator) обозначает расширение языка QUEL,
в котором поддерживаются отношения, не находящиеся в первой нормальной форме
(т.е. отношения с атрибутами, значениями которых являются множества), и отноше-
ния с альтернативными атрибутами (например, одни объекты сотрудников ЕМР имеют
атрибут постоянной зарплаты SALARY, а другие объекты сотрудников ЕМР имеют ат-
рибут почасовой оплаты HOURLY_WAGE и атрибут сверхурочной оплаты OVERTIME).
Кроме того, в нем поддерживается объектная идея о том, что одни объекты концеп-
туально содержат другие объекты (они используются вместо внешних ключей, кото-
рые ссылаются на другие объекты). Причем привычная запись с использованием
точки расширена для ссылок на атрибуты таких объектов (хотя на самом деле при
этом неявно просматриваются некоторые предпочтительные пути соединения). На-
пример, выражение ЕМР. DEPT. BUDGET может быть использовано для обращения к
бюджету отдела, в котором работает определенный сотрудник. Многие другие сис-
темы либо адаптированы к восприятию этой идеи, либо построены на ее основе.
24.52. Zdonik S.B., Maier D. Readings in Object-Oriented Database Systems. — San
Francisco, Calif.: Morgan Kaufmann, 1990.
Ответы к некоторым упражнениям
24.1. Здесь мы объясним лишь термин объект. Ниже приведено несколько “определений”,
которые можно найти в литературе.
“Объектами называются многократно используемые программные модули, в ко-
торых хранятся данные, информация о связях между данными, приложениями и
процессами, контролирующими данные и связи” (из анонса коммерческого про-
граммного продукта).
“Объектом называется область закрытой памяти с открытым интерфейсом” [24.47].
“Объектом называется абстрактная конструкция, определяющая протокол, с помощью
которого пользователи этого объекта могут с ним общаться” (введение к [24.52]).
“Объектом называется программная структура, которая содержит данные и про-
граммы” [24.27].
“...все что угодно является объектом... объект имеет закрытую память и откры-
тый интерфейс” [24.50].
Отметим, что ни одно из этих “определений” не объясняет суть понятия, а имен-
но — что объект является, по существу, просто значением (если он неизменяемый)
или переменной (в противном случае).
Также стоит прокомментировать точку зрения, что “все что угодно является объек-
том”. Вот, например, конструкции, которые не являются объектами в большинстве
объектных систем: переменная экземпляра, отношения (по крайней мере в ODMG
[24.12]), методы, идентификаторы, программные переменные. А в некоторых
системах (опять же, включая ODMG) значения также не являются объектами.
24.2. Ниже перечислены преимущества идентификаторов.
Идентификаторы не характеризуются “разумностью”. В [13.9] объясняется, по-
чему такое “качество” идентификаторов полезно.
Идентификаторы никогда не изменяются до тех пор, пока существуют объекты,
которые они идентифицируют.
996
Часть VI. Объектные и объектно-реляционные базы данных
Идентификаторы не являются сложными конструкциями. В [8.12], [13.10] и
[18.8] объясняется, почему и это свойство идентификаторов полезно.
Все объекты объектной базы данных идентифицируются одинаковым образом (в
отличие от реляционных баз данных).
При ссылке на объекты не нужно повторять пользовательские ключи, поэтому
нет нужды в правилах обновления ON UPDATE.
Некоторые недостатки идентификаторов были кратко перечислены в разде-
лах 24.2-24.4, например они не позволяют избежать необходимости в пользова-
тельских ключах, следствием их применения является низкоуровневый стиль про-
граммирования с “поиском указателей”, их можно применять только для
“базовых”, т.е. не производных, объектов.
Среди возможных способов реализации идентификаторов нужно указать следующие.
Физические дисковые адреса (это очень высокопроизводительный способ, но он
характеризуется слабой независимостью данных).
Логические дисковые адреса (т.е. адреса страниц и смешений; это также высокопро-
изводительный способ, причем он характеризуется большей независимостью данных).
Искусственные идентификаторы (например, временные метки, номер по порядку;
для такого способа требуется также дополнительное отображение на действи-
тельные адреса).
24.3. См. [24.17].
24.5. Вместо подробного ответа здесь будет предложено несколько соображений по вопро-
сам проектирования объектных баз данных в целом. Иногда можно услышать утвер-
ждения, что объектные системы облегчают проектирование (и использование) баз дан-
ных, поскольку они предоставляют высокоуровневые конструкции для моделирования
и поддерживают эти конструкции в системе. (В реляционных же системах высший уро-
вень используется косвенно, а именно: в процессе отображения объектов реального ми-
ра в переменные-отношения, атрибуты, внешние ключи и т.д.) В этом утверждении есть
доля истины. Однако позвольте прежде задать вопрос “Как выполнен проект объектной
базы данных?”. Действительно, “объектная модель”, как это принято считать, имеет
значительно больше степеней свободы (или, другими словами, больше выбора) по
сравнению с реляционной моделью. Но автору этой книги неизвестно о существовании
хотя бы одного стоящего пособия, которое помогло бы реализовать эти возможности.
Например, как определить представление, скажем, множества всех служащих: как мас-
сив, как список или как множество и т.д. и т.п. “Для мощной модели данных требуется
мощная методология проектирования... и за это ответственна объектная модель дан-
ных” (выдержки из [24.27]). Мы могли бы возразить, что характеристику “мощная” не-
обходимо заменить характеристикой “сложная”.
24.9. Вместо подробного ответа здесь будет сделано одно замечание относительно сложно-
сти этого упражнения. Прежде всего, следует обратить внимание на то, что термин
“удалить” будет использоваться как сокращение для выражения “выбрать в качестве
кандидата для физического удаления” (т.е. удалить все ссылки на этот объект). Тогда
для того, чтобы удалить объект X, сначала следует найти все объекты Y, которые содер-
жат ссылку на X, а затем следует либо удалить такие объекты Y, либо удалить в этих
объектах все ссылки на объект X (задав для таких ссылок специальное значение nil, т.е.
997
Глава 24. Объектные базы данных
отсутствие значения). Частично проблемы могут возникнуть потому, что невозможно
на основании одного только определения данных указать те объекты, которые содержат
ссылку на объект X, или хотя бы даже сказать, сколько их существует. Рассмотрим, на-
пример, объекты сотрудников и объектный класс ESET. В принципе, может существо-
вать любое количество экземпляров класса ESET, и каждое подмножество экземпляров
класса ESET может содержать ссылку на некоторого конкретного сотрудника.
24.10. Существует шесть возможных иерархий.
S содержит ( Р содержит ( J ) )
S содержит ( J содержит ( Р ) )
Р содержит ( J содержит ( S ) )
Р содержит ( S содержит ( J ) )
J содержит ( S содержит ( Р ) )
J содержит ( Р содержит ( S ) )
Без какой-либо дополнительной информации невозможно дать ответ на вопрос
“Какой из вариантов является лучшим?”, но можно почти с полной уверенностью
сказать, что все они одинаково плохи.
24.11. Су шествует по _ мере двенадцать “очевидных” макетов иерархии контейнеров.
Ниже _ только четыре из них.
S содержит ( Р содержит ( J ) )
S содержит ( J содержит ( Р ) )
S содержит ( сначала Р, затем J )
S содержит ( сначала J, затем Р )
Существует достаточно много других возможных макетов, например объект SP,
который прямо указывает на то, какими поставщиками какие детали поставляются,
а также включает два внедренных множества проектов: одно для поставщиков,
другое — для деталей.
Можно также составить проект безо всяких иерархий из объектов SP, PJ и JS.
24.12. Среди основных факторов, оказывающих влияние на производительность, были пе-
речислены следующие: кластеризация, кэширование, замена указателей и выполне-
ние методов на сервере. Все эти способы обработки данных могут применяться в
любой системе для обеспечения разумного уровня независимости от данных, поэто-
му они характерны не только для объектных систем. На самом деле, идея использо-
вания определения логической базы данных для выбора типа физической кластери-
зации (используемой в той или иной объектной системе) может рассматриваться как
некий фактор, потенциально подрывающий независимость от данных.
Замечание. Следует отметить, что другой очень важный фактор, оказывающий
влияние на производительность, а именно — оптимизация, обычно не учитывается
в объектных системах.
24.13. FIo мнению автора, декларативная поддержка, если она возможна, всегда лучше
процедурной (по многим причинам, а не только для создания ограничений целост-
ности). Короче говоря, декларативная поддержка означает, что система выполняет
некоторую работу вместо пользователя. Вот почему в реляционной системе под-
держиваются декларативные запросы, декларативные определения представлений,
декларативные ограничения целостности и т.д.
998
Часть VI. Объектные и объектно-реляционные базы данных
Глава 25
Объектно-реляционные
базы данных
25Л. Введение
Со времени выхода предыдущего издания прошло около пяти лет. За это время не-
сколько изготовителей выпустили “объектно-реляционные” СУБД, известные на рынке
как универсальные серверы. Среди них— Universal Database version of DB2, Universal
Data Option for Informix Dynamic Server и Oracle 8i Universal Server, Database Server или
Enterprise Server (по-видимому, используются все три названия). Основная идея, поло-
женная в основу всех перечисленных продуктов, заключается в том, что они должны
поддерживать как объектные, так и реляционные возможности, иначе говоря, они пред-
ставляют попытку сближения этих двух технологий.
По глубокому убеждению автора, такое сближение должно основываться на реля-
ционной модели (которая, как объяснялось ранее в этой книге, помимо всего прочего,
служит основой современной технологии баз данных в целом). Это значит, что следует
таким образом изменить реляционную систему, чтобы в нее вошли по крайней мере
самые лучшие возможности объектных систем1. При этом не следует полностью отка-
зываться от реляционных систем, но также не нужно параллельно развивать две раз-
ные системы, реляционную и объектную. Это мнение разделяется многими специали-
стами, включая авторов манифеста “Third Generation Database System Manifesto”
[25.34]. Они в весьма категоричной форме заявляют, что СУБД третьего поколения
должны включать СУБД второго поколения, где под СУБД первого поколения
подразумеваются дореляционные СУБД, под СУБД второго поколения — SQL-
системы и под СУБД третьего поколения — системы будущего. Некоторые разработ-
чики объектных систем, очевидно, такое мнение не разделяют, подтверждением чему
может служить следующее высказывание из [25.4].
“Развитие компьютерных наук сопровождалось появлением многих поколений ме-
тодов управления данными, начиная с индексных файлов, сетевых и иерархических
СУБД... и заканчивая более современными реляционными СУБД... Теперь мы наблю-
даем появление еще одного поколения СУБД... в которых обеспечивается управление
объектами, поддерживаются гораздо более сложные виды данных. ”
1 Отметим, что мы, несомненно, поддерживаем эволюционный, а не революционный путь
развития СУБД. Для сравнения приведем цитату из книги группы ODMG [24.13]: “[Объектные
СУБД] — это результат революционного, а не эволюционного развития”. Мы не верим, что ры-
нок в целом готов к революционным переменам, и не считаем, что они необходимы или должны
непременно произойти. В частности, поэтому работа “The Third Manifesto” [3.3] — это, по су-
ти, именно эволюционный манифест, а не революционный.
Глава 25. Объектно-реляционные базы данных
999
Здесь четко выражена мысль, что, как реляционные системы в свое время заменили
иерархические и сетевые, так и объектные системы заменят реляционные.
Причина несогласия автора настоящей книги с этим мнением состоит в том, что ре-
ляционный подход значительно отличается [25.13] от объектного, так как он предпо-
лагает теоретическую обоснованность принимаемых решений. Напротив, более старые
системы, существовавшие до появления первых реляционных систем, строились на со-
вершенно произвольных посылках. Они позволяли решать важные текущие задачи, но
не имели сколько-нибудь прочного теоретического обоснования. К сожалению, при-
верженцы реляционного подхода (и автор этой книги в том числе) в начальный период
оказали себе в некотором роде “медвежью” услугу, восхваляя относительные достоин-
ства как реляционных систем, так и их предшественниц. Эти похвалы были уместны в
свое время, но впоследствии благодаря им у многих сложилось впечатление, что реля-
ционные и предшествующие им системы были, по сути, одинаковы. И это ошибочное
представление, в свою очередь, привело к процитированному выше выводу, что объ-
екты по сравнению с отношениями — это такой же шаг вперед, какой был при замене
иерархий и сетей отношениями.
Так что же можно сказать об объектах? Является ли эта методология также произ-
вольной? На этот вопрос проливает свет следующая цитата из манифеста объектно-
ориентированных СУБД “The Object-Oriented Database System Manifesto” [24.1]: “В от-
ношении объектно-ориентированных систем следует применить принцип естественного
отбора, описанный Дарвином, т.е. наиболее пригодная объектно-ориентированная мо-
дель появится на основе создания некоторого множества экспериментальных прототи-
пов”. Иными словами, предложение заключается в том, что мы должны писать код и
строить системы без какой-либо заранее определенной теоретической модели и
смотреть, что из этого получится!
Исходя из этого, мы принимаем в качестве аксиомы, как, кстати, и большинство ос-
новных производителей СУБД, что реляционные системы будут обогащены за счет до-
бавления в них самых лучших возможностей объектной технологии. При этом не следует
отвергать реляционную технологию, перечеркивая 30-летний опыт исследований и раз-
работки реляционного подхода.
В главе 24 утверждалось (см. также комментарии к [25.23]), что в ориентации на
объекты есть только одна хорошая идея, а именно — совершенная поддержка типов
данных (или две хорошие идеи, если считать наследование типов отдельно). Тогда
возникает вопрос, каким образом можно включить в реляционную модель надлежа-
щую поддержку типов данных. Ответ на этот вопрос, как вы уже, по-видимому, дога-
дались, прост— такая поддержка существует в форме доменов (которые мы все же
предпочитаем называть типами}. Другими словами, для реляционной модели ничего
не требуется, чтобы достичь объектной функциональности в реляционной системе, т.е.
ничего, кроме ее реализации, полной и правильной, которую большинство современ-
ных систем с треском провалило2.
2 В частности, такие системы послужили слишком широкому распространению заблужде-
ния, что реляционные системы могут поддерживать только ограниченное количество очень
простых типов. Вот довольно типичные выдержки из литературы по объектным базам данных:
“Реляционные системы баз данных поддерживают очень малый фиксированный набор типов
данных’' [25.25], “Реляционная СУБД может поддерживать лишь... встроенные типы [в основ-
1000
Часть VI. Объектные и объектно-реляционные базы данных
Поэтому мы считаем, что реляционная система, которая в полной мере поддерживала
бы домены, могла бы справляться со всеми такими “проблемными” типами данных, ко-
торые, как часто утверждают, в объектных системах могут обрабатываться, а в реляци-
онных системах — нет. К таким данным обычно относят хронологические последова-
тельности данных, биологические данные, финансовые данные, данные технического
проектирования, данные автоматизации офиса и т.д. Поэтому мы считаем, что истинная
“объектно-реляционная” система могла бы быть ни чем иным, как истинной реляционной
системой, т.е. системой, которая поддерживает реляционную модель со всеми вытекаю-
щими отсюда последствиями. Значит, необходимо рекомендовать изготовителям СУБД
делать то, что они фактически и пытались делать, а именно — расширять свои системы
для включения поддержки необходимых типов или доменов. Конечно, можно возразить,
и вполне резонно, что в целом объектные системы выглядят более привлекательно, по-
скольку реляционная модель неудовлетворительно поддерживается поставщиками SQL-
продуктов. Однако это не должно быть причиной отказа от реляционных систем в целом.
В качестве примера вернемся к незаконченным исследованиям из раздела 24.1 гла-
вы 24 и покажем подходящее реляционное решение задачи о прямоугольниках. Прежде
всего следует определить тип прямоугольника (назовем его RECT).
TYPE RECT POSSREP ( Xl RATIONAL, Yl RATIONAL,
X2 RATIONAL, Y2 RATIONAL ) ... ;
Предполагается, что физическое представление данных основывается на одном из ти-
пов структур хранения, которые позволяют весьма эффективно сохранять такие про-
странственные структуры данных, как Q-деревья, R-деревья т.д. [25.27].
Далее нужно определить оператор для проверки, не пересекаются ли два прямоугольника.
OPERATOR OVERLAP ( Rl RECT, R2 RECT )
RETURNS ( BOOLEAN ) ;
RETURN ( THE_X1(R1) < THE_X2(R2) AND
THE_Y1(R1) < THE_Y2(R2) AND
THE_X2(R1) > THE_X1(R2) AND
THE_Y2(R1) > THE_Y1(R2) ) ;
END OPERATOR ;
В этом операторе используется эффективная “краткая” формулировка (см. главу 24)
условия пересечения прямоугольников для эффективной структуры хранения.
Теперь пользователь может создать базовую переменную-отношение с атрибутом ти-
па RECT.
VAR RECTANGLE RELATION { R RECT, ... } KEY { R } ;
В таком случае формулировка запроса “Найти все прямоугольники, которые пересе-
кают данный единичный квадрат” значительно упрощается.
RECTANGLE WHERE OVERLAP ( R, RECT (0.0, 0.0, 1.0, 1.0 )) ;
Это решение позволяет устранить все недостатки, которые обсуждались в главе 24 в
связи с предыдущим запросом. |
ном, просто числа, строки, даты и время]” [24.38], “Объектно-реляционные модели расширяют
реляционную модель данных, предоставляя более богатую систему типов” [17.61 ]; и т.д.
Глава 25. Объектно-реляционные базы данных
1001
В разделах 25.2 и 25.3 рассматриваются две грубейшие ошибки', несомненно, по край-
ней мере одна из них допущена в каждой объектно-реляционной системе из числа
имеющихся на рынке. В разделе 25.4 обсуждаются некоторые аспекты реализации объ-
ектно-реляционных систем. В разделе 25.5 описываются преимущества истинных объ-
ектно-реляционных систем (т.е. таких систем, в которых нет этих двух грубейших оши-
бок). И наконец в разделе 25.6 приводится резюме.
25.2. Первая грубейшая ошибка
Начнем с цитаты из [3.3].
"[Прежде] чем подробно обсуждать вопрос об интеграции объектов и отноше-
ний, необходимо ответить на ключевой вопрос:
Какая из концепций в реляционной модели соответствует концеп-
ции объектного класса в объектной модели?
Выбор такой концепции очень важен, потому что объектный класс — это наибо-
лее фундаментальное понятие в объектном мире, и все остальные объектные по-
нятия в той или иной мере зависят от него. В качестве ответа на рассматривае-
мый вопрос могут быть и были предложены два уравнения:
" домен - объектный класс;
" переменная-отношение = объектный класс;
Далее мы приведем строгое обоснование того, что первое из уравнений верное, а
второе — нет. ”
На самом деле очевидно, что первое уравнение верно, поскольку и объектные классы, и
домены являются просто типами. Поэтому из того, что переменная-отношение — это пе-
ременная, а класс — это тип, также непосредственно ясно, что второе уравнение не верно
(переменные и типы — это не одно и то же). По указанным причинам в работе The Third
Manifesto [3.3] категорически утверждалось, что переменные-отношения — это не доме-
ны. Тем не менее во многих работах и в некоторых продуктах фактически используется
второе уравнение, что мы и называем грубейшей ошибкой, а точнее — первой грубейшей
ошибкой, поскольку далее будет рассмотрена еще одна. Очень поучительно было бы более
внимательно присмотреться ко второму уравнению, что мы и сделаем ниже.
Замечание. Далее в этом разделе почти дословно повторяется [3.3].
Почему же может быть допущена такая грубая ошибка? Рассмотрим определение
простого класса, написанное на гипотетическом объектном языке, который не совсем
(что сделано преднамеренно) совпадает с тем языком, который использовался в разде-
ле 24.3, хотя и похож на него.
CREATE OBJECT CLASS ЕМР
( EMP# CHAR(5),
ENAME CHAR(20),
SAL NUMERIC,
HOBBY CHAR(20),
WORKS_FOR CHAR(20) ) ... ;
1002
Часть VI. Объектные и объектно-реляционные базы данных
(Здесь EMP# и ENAME — открытые переменные экземпляра.) Сравним это определение
с определением “базовой переменной-отношения” на языке SQL.
CREATE TABLE ЕМР
( EMP# CHAR(5),
ENAME CHAR(20),
SAL NUMERIC,
HOBBY CHAR(20),
WORKS_FOR CHAR(20) ) ... ;
Эти выражения, несомненно, очень похожи, и, конечно же, очень велико искушение
их приравнять. И как отмечалось выше, в некоторых системах именно так и было сдела-
но. Рассмотрим этот вопрос подробнее. Возьмем, например, показанный выше оператор
CREATE TABLE и ряд возможных его расширений, которые, как может показаться, делают
его более “объектно-подобным”.
Замечание. Далее мы будем основываться на конкретном коммерческом продукте, а
точнее — на примере, взятом из документации для этого продукта. Однако здесь не ука-
зывается, что это за продукт, поскольку в данном случае у нас нет намерения критико-
вать или хвалить какой-либо конкретный продукт. Критика же, которая будет встречать-
ся ниже, с соответствующими изменениями применима к любой системе, в которой бы-
ло принято уравнение “переменная-отношение = объектный класс”.
Первое расширение позволяет использовать составные атрибуты, т.е. значения этих
атрибутов представляют собой кортежи из некоторых других переменных-отношений
(или из той же самой переменной-отношения). В нашем примере можно заменить исход-
ный оператор CREATE TABLE следующим набором операторов (рис. 25.1).
CREATE TABLE ЕМР
( EMP# CHAR(5),
ENAME CHAR(20),
SAL NUMERIC,
HOBBY ACTIVITY,
WORKS_FOR COMPANY ) ;
CREATE TABLE ACTIVITY
( NAME CHAR(20),
TEAM INTEGER ) ;
CREATE TABLE COMPANY
( NAME CHAR(20),
LOCATION CITYSTATE ) ;
CREATE TABLE CITYSTATE
( CITY CHAR(20),
STATE CHAR(2) ) ;
Пояснения. Для атрибута HOBBY (Хобби) в переменной-отношении ЕМР объявлен тип
ACTIVITY (Деятельность), который, в свою очередь, является атрибутом, состоящим из
двух атрибутов— NAME (Название команды) и TEAM (Команда), где TEAM представляет
Глава 25. Объектно-реляционные базы данных
1003
число игроков в соответствующей команде. Например, в столбец ACTIVITY может быть
помещено следующее значение: ('Fooball', 11). Каждое значение HOBBY в действи-
тельности является заданной парой значений, т.е. значением переменной NAME и значени-
ем переменной TEAM. (Точнее, это пара значений, которая в данный момент присутствует
как кортеж в переменной-отношении ACTIVITY.)
Рис. 25.1. Атрибуты, содержащие кортежи или указатели на них (это решение не ре-
комендуется)
Замечание. Обратите внимание, что мы уже нарушили предупреждение из третьего
манифеста, что переменная-отношение — это не домен, поскольку “домен” для атрибута
HOBBY определен как переменная-отношение ACTIVITY. Подробнее этот вопрос будет
рассмотрен ниже.
Аналогично для атрибута WORKS_FOR (место работы) в переменной-отношении ЕМР
объявлен тип COMPANY (компания), который, в свою очередь, является переменной-
отношением, состоящим из двух атрибутов, причем один из них— атрибут CITYSTATE
(город, штат) — также является переменной-отношением из двух атрибутов, и т.д. Иначе
говоря, переменные-отношения ACTIVITY, COMPANY и CITYSTATE рассматриваются и как
типы (или домены), и как переменные-отношения. То же правило, конечно, верно и для
переменной-отношения ЕМР.
Таким образом, первое расширение языка, грубо говоря, аналогично разрешению од-
ним объектам содержать другие объекты, тем самым обеспечивая поддержку концепции
иерархии вложения (см. главу 24).
В качестве небольшого отступления отметим, что первое расширение мы характери-
зовали как “атрибуты, содержащие кортежи”, поскольку так его характеризуют сами за-
щитники уравнения “переменная-отношение = класс” (см., например, [24.33]). Но точнее
его было бы охарактеризовать как “атрибуты, содержащие указатели на кортежи”
(вопрос, который вскоре будет рассмотрен). Поэтому на рис. 25.1 во всех трех случаях
следовало бы заменить термин кортеж термином указатель на кортеж.
Замечания, которые были сделаны в отношении первого расширения, справед-
ливы и для второго расширения. Оно допускает атрибуты со значениями, пред-
ставляющими собой отношения, т.е. значениями могут быть множества корте-
жей какой-либо другой переменной-отношения (или, возможно, той же самой).
Предположим, например, что сотрудники могут иметь не одно, а произвольное
число увлечений (рис. 25.2).
1004
Часть VI. Объектные и объектно-реляционные базы данных
ЕМР
EMP# ENAME SAL отношение HOBBIES кортеж WORKS FOR
NAME TEAM NAME кортеж
LOCATION
| CITY | STATE |
Рис. 25.2. Атрибуты, содержащие множества кортежей или указатели на них (это
решение не рекомендуется)
CREATE TABLE ЕМР
( EMP# CHAR(5),
ENAME CHAR(20),
SAL NUMERIC,
HOBBIES SET OF ( ACTIVITY ),
WORKS_FOR COMPANY ) ;
Пояснения. Теперь значением столбца HOBBIES внутри данного кортежа переменной-
отношения ЕМР концептуально является множество пар значений (NAME, TEAM), т.е. кор-
тежей переменной-отношения ACTIVITY. Это второе расширение, попросту говоря, ана-
логично разрешению объектам содержать “коллекции” объектов, что, по сути, является
более сложной версией иерархии вложения.
Замечание. Отметим, между прочим, что в продукте, на котором основывается наш
пример, объекты коллекции сами по себе могут быть последовательностями или паке-
тами, а также множествами.
В качестве третьего расширения выступает разрешение переменным-отношениям
иметь связанные с ними методы, как, например, показано ниже.
CREATE TABLE ЕМР
( EMP# CHAR(5),
ENAME CHAR(20),
SAL NUMERIC,
HOBBIES SET OF ( ACTIVITY ),
WORKS_FOR COMPANY )
METHOD RETIREMENT_BENEFITS ( ) : NUMERIC ;
Пояснения. В этом примере RETIREMENT_BENEFITS является методом, который в качестве
аргумента принимает заданный экземпляр кортежа ЕМР и возвращает результат типа NUMERIC.
Наконец, последнее расширение заключается в разрешении определять подклассы
(рис. 25.3).
CREATE TABLE PERSON
( SS# CHAR(9),
BIRTHDATE DATE,
ADDRESS CHAR(50) ) ;
Глава 25. Объектно-реляционные базы данных
1005
CREATE TABLE EMP
AS SUBCLASS OF PERSON
( EMP# CHAR(5),
ENAME CHAR(20),
SAL NUMERIC,
HOBBIES SET OF ( ACTIVITY ),
WORKS_FOR COMPANY )
METHOD RETIREMENT_BENEFITS ( ) : NUMERIC ;
Puc. 25.3. Переменные-отношения в качестве суперклассов и подклассов (это решение
не рекомендуется)
Пояснения. Переменная-отношение ЕМР имеет три дополнительных атрибута (SS#,
BIRTHDATE, ADDRESS), которые наследуются из переменной-отношения PERSON (поскольку
каждый экземпляр класса ЕМР также является ("ISA") экземпляром класса PERSON). Если пе-
ременная-отношение PERSON обладает какими-то методами, эти методы также наследуются.
Замечание. Переменные-отношения PERSON и ЕМР являются примерами так называе-
мых супертаблиц и подтаблиц соответственно. В [13.12], а также в приложении Б эти
понятия рассматриваются подробнее.
Наряду с описанными вкратце расширениями, касающимися определения данных,
потребуются и расширения, связанные с манипулированием этими данными, как, напри-
мер, показано ниже.
Выражения пути, например ЕМР.WORKS_FOR.LOCATION.STATE. В общем случае та-
кие выражения могут возвращать скаляры, кортежи или отношения. Заметим, что
в последних двух случаях компоненты таких кортежей или отношений сами могут
быть кортежами или отношениями, например выражение ЕМР.HOBBIES.NAME воз-
вращает отношение. Следует отметить, что выражения пути записываются в по-
рядке снижения иерархии вложения, а выражения пути, которые рассматривались
в главе 24, — в порядке возрастания.
Литеральные кортежи и отношения, которые могут быть и вложенными.
( 'Е001', 'Smith', $50000,
( ( 'Fooball', И ), ( 'Baseball', 9 ) ),
( 'IBM', ( 'San Jose', 'CA' ) ) )
(Реальный синтаксис может отличаться.)
1006
Часть VI. Объектные и объектно-реляционные базы данных
Операторы реляционного сравнения, например SUBSET, SUBSETEQ и т.д. (Примеры
операторов взяты из рассматриваемого продукта. В этом продукте оператор
SUBSET на самом деле означает “собственное подмножество”, a SUBSETEQ —
“подмножество”.)
Операторы для отслеживания иерархии классов.
Замечание. Здесь также требуется осторожность. Вполне возможно, что результат
выполнения запроса данных из отношения PERSON вместе с соответствующими
данными из отношения ЕМР не будет отношением. Фактически это означает нару-
шение фундаментального реляционного свойства замкнутости со всеми выте-
кающими отсюда плачевными последствиями. (В связи с этим в [25.31] — где та-
кой результат называют “обкусанным возвратом”— беспечно замечают, что
“программа клиента должна быть готова справиться со всеми сложностями обра-
ботки обкусанного возврата”!)
Возможность вызывать методы в предложениях SELECT и WHERE в терминах языка SQL.
Возможность осуществлять доступ к отдельным компонентам внутри значений
атрибутов, которые являются кортежами или отношениями.
Для краткого обзора практической реализации уравнения “переменная-отношение =
класс” этого, пожалуй, будет достаточно. Теперь разберемся, что же тут плохого.
Прежде всего отметим, что, как уже указывалось, переменная-отношение — это пе-
ременная, а класс — это тип. Так как же они могут быть одним и тем же? Одного этого
достаточно, чтобы идею уравнения “переменная-отношение = класс” отбросить без
дальнейшего обсуждения. Однако не будем торопиться, поскольку в связи с этим возни-
кают и дополнительные вопросы, рассмотреть которые было бы весьма полезно.
Из уравнения “переменная-отношение = класс” следуют уравнения “кортеж = объ-
ект” и “атрибут = (открытая) переменная экземпляра”. Таким образом, хотя (как
было показано в главе 24) настоящий объектный класс — по крайней мере скаляр
или “инкапсулированный” объектный класс — имеет методы и не имеет открытых
переменных экземпляра, “объектный класс” переменной-отношения имеет откры-
тые переменные экземпляра и лишь необязательно имеет методы (разумеется, он
не “инкапсулирован”). И снова возникает вопрос, как могут эти два понятия быть
одним и тем же?
Между определениями атрибутов, например SAL NUMERIC и WORKS_FOR COMPANY,
имеется значительное отличие. Тип NUMERIC— это настоящий тип данных
(равносильный настоящему, хотя и примитивному, домену). Он накладывает незави-
симое от времени ограничение на значения, которые может законно принимать ат-
рибут SAL. Тип COMPANY, напротив, не является истинным типом данных. Ограниче-
ние, которое он накладывает на значения атрибута WORKS_FOR, зависит от времени
(оно, очевидно, зависит от текущего значения переменной-отношения COMPANY).
Фактически здесь стерты все различия между переменными-отношениями и доме-
нами или согласно объектной терминологии между коллекциями и классами.
Как мы уже видели, одни “объекты” кортежей могут содержать другие такие же
“объекты”. Например, “объекты” ЕМР воспринимаются как содержащие “объекты”
COMPANY. Однако в действительности они содержат не их, а указатели на эти
Глава 25. Объектно-реляционные базы данных
1007
“содержащиеся в них объекты”, и это нужно четко себе представлять. Предполо-
жим, что пользователь каким-то образом обновляет один из кортежей отношения
COMPANY (см. рис. 25.1). Тогда это изменение немедленно распространяется на все
кортежи ЕМР, которые содержат данный кортеж COMPANY.
Замечание. Указанные здесь последствия обновления не должны восприниматься
как нежелательные — они были приведены лишь для объяснения эффекта такого
обновления. Однако “модель” на рис. 25.1, которая использовалась нами в обсуж-
дении, показана неверно: кортежи ЕМР содержат не кортежи COMPANY, а лишь ука-
затели на них.
Этот аспект требует некоторых дополнительных пояснений.
а) Можно ли вставить кортеж ЕМР и задать значение для “содержащегося” в
нем кортежа COMPANY, которого в данный момент еще не существует в пе-
ременной-отношении COMPANY? Если ответ будет положительным, то зада-
ние типа COMPANY для атрибута WORKS_FOR не будет значить практически ни-
чего, поскольку при этом на операцию вставки INSERT не накладывается
никаких ограничений. А если ответ будет отрицательным, то операция
вставки INSERT становится очень сложной, так как пользователь должен
указать не только допустимый “внешний ключ” COMPANY.NAME (как следова-
ло бы поступить в аналогичной ситуации в реляционной системе), но и весь
допустимый кортеж COMPANY. Более того, в лучшем случае при указании
всего кортежа COMPANY системе будет повторно передана информация, ко-
торая ей уже известна, а в худшем — в случае ошибки пользователя при
определении кортежа COMPANY в целом корректная операция INSERT выпол-
нена не будет.
б) Предположим, что для переменной-отношения COMPANY необходимо реали-
зовать правило ограничения удаления ON DELETE RESTRICT (т.е. запретить
удаление объекта компании, если в этой компании работают какие-либо со-
трудники). Допустим, что это правило может быть реализовано процедур-
ным способом, скажем, с помощью метода М. (Обратите внимание, что пе-
ременная-отношение ЕМР не имеет внешнего ключа, к которому можно бы-
ло бы подключить декларативную версию этого правила.) Более того,
обычные операции DELETE языка SQL для переменной-отношения ЕМР не
должны теперь выполняться иначе, чем посредством вызова метода Л/. Как
обеспечить соблюдение этого требования? Аналогичные замечания и во-
просы относятся, конечно, и к другим правилам внешних ключей, например
к правилам ON DELETE CASCADE.
в) Также отметим, что при выполнении операции DELETE для кортежа ЕМР
“каскадное” удаление соответствующего кортежа COMPANY, скорее всего, вы-
полняться не будет, несмотря на видимость того, что он “содержится” внутри
кортежа ЕМР.
Из сказанного выше следует, что речь идет вовсе не о реляционной модели. Фун-
даментальным объектом данных является не отношение, содержащее значения, а
“отношение”, содержащее значения и указатели. На самом деле такое
1008
Часть VI. Объектные и объектно-реляционные базы данных
“отношение” не является настоящим отношением, по крайней мере в соответствии
с реляционной моделью. Иначе говоря, мы разрушили концептуальную цело-
стность реляционной модели3.
Предположим, что определено представление V, которое является проекцией пе-
ременной-отношения ЕМР лишь по одному атрибуту HOBBIES. Представление V,
конечно, также является переменной-отношением, но не базовой, а производной.
Тогда, если уравнение “переменная-отношение = класс” верно, значит, представ-
ление V — также класс. А что такое класс? Классы имеют методы. Какие .методы
есть у представления V?
В рассматриваемом случае “класс” ЕМР имеет только один метод, а именно —
RETIREMENT_BENEFITS, который, очевидно, не применяется к “классу” V. Практиче-
ски вряд ли было бы разумно, чтобы любые методы, которые применяются к
“классу” ЕМР, применялись также к “классу” V. Тем более это касается всех осталь-
ных методов. Таким образом, получается, что никакие методы не могут применять-
ся для результата выполнения операции проекции, т.е. каким бы ни был результат,
он на самом деле не является классом. (Его можно так назвать, однако от этого он
не станет классом, поскольку может иметь переменные экземпляра, но не может со-
держать методов, тогда как ранее отмечалось, что истинный “инкапсулированный”
класс обладает методами, но не имеет открытых переменных экземпляра.)
Совершенно ясно, что при сравнении переменных-отношений и объектных клас-
сов на самом деле имеются в виду базовые переменные-отношения.
(Упоминавшиеся выше указатели — это указатели на кортежи в базовых перемен-
ных-отношениях, а не в производных.) Но делать такое различие между базовыми
и производными переменными-отношениями— значит допускать грубейшую
ошибку, поскольку вопрос о переменной-отношении (какой она является: базовой
или производной) в определенном смысле относительный (см. обсуждение прин-
ципа взаимозаменяемости в главе 9).
И наконец чем же поддерживаются домены? Похоже, что защитникам уравнения
“переменная-отношение = класс” нечего сказать о доменах, по-видимому, потому,
что они не могут представить, как домены могут вписаться в их схему. Тем не ме-
нее, как неоднократно указывалось, домены — это фундаментальное понятие (см.,
например, главу 3).
Общую идею всего сказанного можно сформулировать следующим образом. Безуслов-
но, можно построить систему, которая основывается на неверном уравнении “переменная-
отношение - класс”, и в действительности такие системы уже созданы. Точно так нет ника-
3 Термин концептуальная целостность получил распространение благодаря Фреду Бруксу (Fred
Brooks), который в [25.1] сказал следующее: “[Концептуальная] целостность— это наиболее
важный вопрос в системном проектировании. Лучше не включить в систему определенные несо-
вместимые возможности [и] отразить единый ряд проектных идей, чем иметь систему, кото-
рая поддерживает много полезных, но несвязанных и несогласованных идей". Спустя 20 лет он
добавил: “Цельный первоклассный программный продукт должен представлять... логически по-
следовательную мысленную модель... [Концептуальная] целостность— наиболее важный фак-
тор для удобства в использовании... И сейчас я в этом убежден больше, чем когда бы то ни
было. Концептуальная целостность — это основа для получения качественного продукта”.
Глава 25. Объектно-реляционные базы данных
1009
ких сомнений, что подобные системы (как и автомобиль, не имеющий масла в двигателе,
или дом, который построен из песка) могут даже предоставлять полезный сервис в течение
некоторого времени, но в конечном счете они обречены на провал.
Как возникла первая грубейшая ошибка
Интересно поразмышлять об источнике возникновения первой грубейшей ошибки.
На наш взгляд, ее корни кроются в отсутствии согласия, как отмечалось в главе 24, отно-
сительно значений терминов в объектном мире. В частности, не всеми принимается сам
термин объект, нет у него и общепризнанного значения. Именно это и послужило при-
чиной того, что мы отказались использбвать его в дальнейшем.
Тем не менее совершенно очевидно, что, по крайней мере в области объектных язы-
ков программирования, термин объект означает то, что традиционно называлось значе-
нием или переменной (или тем и другим). Однако, к сожалению, этот термин использует-
ся и в других областях, в частности в области семантического моделирования как части
множества различных методов и методологий “объектного анализа и проектирования”
или “объектного моделирования” (см., например, [13.3]). А в этой области, похоже, он не
соответствует понятию “значение” или “переменная”. Скорее, он означает то, что среди
специалистов по базам данных называют сущностью (откуда следует, между прочим,
что в отличие от объектов языков программирования такие объекты, разумеется, не ин-
капсулированы). Иначе говоря, “объектное моделирование” — это на самом деле просто
моделирование отношений “сущность/связь”, с чем автор публикации [13.3] в какой-то
мере также соглашается. Поэтому то, что в подобных методологиях идентифицировалось
как “объекты”, затем корректно отображалось в кортежи переменных-отношений, а не в
значения доменов. Вот и весь фокус!
25.3. Вторая грубейшая ошибка
В этом разделе будет рассмотрена вторая грубейшая ошибка. Как мы вскоре убе-
димся, она логически следует из первой, но также показательна и сама по себе (более то-
го, такая ошибка может быть допущена даже в том случае, если удалось избежать первой
грубейшей ошибки). Суть второй ошибки в смешивании указателей и отношений.
Начнем с пересмотра основных возможностей, используемых в подходе “переменная-
отношение = класс”, как мы его определили в предыдущем разделе. Возможно, кое-кто
сочтет этот раздел несколько запутанным, поскольку некоторые из возможностей, кото-
рые не одобряются, ранее в этой книге защищались (например, атрибуты со значениями
кортежа и отношения). Итак, перейдем к их последовательному рассмотрению.
Атрибуты со значениями-кортежами и значениями-отношениями. Конечно,
мы не возражаем против таких атрибутов (да и как мы можем?). Мы возражаем
против того, что, во-первых, эти атрибуты должны иметь именно такие значе-
ния, которые в данный момент должны быть и в некоторой другой (базовой) пе-
ременной-отношении; во-вторых, такие атрибуты действительно имеют значе-
ния, которые сами не являются кортежами или отношениями, а представляют
собой указатели на кортежи или отношения. Последнее означает, что в дейст-
вительности об атрибутах, имеющих в качестве значений кортежи или отноше-
ния, речь не идет совсем.
1010
Часть VI. Объектные и объектно-реляционные базы данных
Замечание. На самом деле идея использования указателей на “кортежи или отно-
шения”, означающих именно значения в виде кортежей или отношений, — это
вздор. Мы еще обсудим данный вопрос подробнее.
Операторы (“.методы”), связанные с переменными-отношениями. Против такой
идеи мы также не имеем ничего против — под этой личиной скрывается привыч-
ная концепция хранимых и триггерных процедур. Однако мы не согласны с тем,
что подобные операторы должны быть связаны с переменными-отношениями (и
только с ними), а не с доменами и типами. Не поддерживаем мы и точку зрения,
что они должны быть связаны с одной определенной переменной-отношением
(понятие целевых операндов в другом обличье).
Подклассы и суперклассы. А вот с этой идей мы не согласны... В системе, которая
отождествляет переменные-отношения с классами, подклассы и суперклассы ста-
новятся «одтаблицами и супертаблицами, а к этой концепции мы относимся
[13.12] весьма скептически. Мы выступаем за настоящую поддержку наследова-
ния, как уже объяснялось в главе 19.
Выражения пути. Мы бы не возражали против использования выражений, кото-
рые служили бы просто сокращениями для последующих ассоциативных ссылок,
т.е. от внешнего ключа к совпадающему потенциальному ключу, как предлагалось
в [25.11]. Однако, как указывалось в разделе 25.2, такие выражения служат сокра-
щениями для последующих цепочек указателей, а этого мы не признаем
(поскольку, прежде всего, мы против использования указателей).
Литералы кортежей и отношений. Это важные понятия, но их необходимо
обобщить в понятия выборок кортежей и отношений [3.3].
Реляционные операторы сравнения. Также существенное понятие (хотя требуется
правильная его реализация).
Операторы для обхода иерархии класса. Если “иерархия класса” действительно
означает “иерархию переменных-отношений”, то, как отмечалось в предыдущем
разделе, мы категорически возражаем, поскольку возможны нарушения свойства
реляционной замкнутости (см. также [25.31]). Если же “иерархия класса” означает
“иерархию типов” в смысле главы 19, никаких возражений нет (но в действитель-
ности это не так).
Вызов методов внутри предложений, например, SELECT и WHERE. Конечно, за.
Доступ к отдельным компонентам внутри значений атрибута, которые явля-
ются кортежами или отношениями. Конечно, за.
А теперь остановимся на вопросе смешивания указателей и отношений. Основной
аргумент очень прост. По определению указатели указывают на переменные, а не на
значения (поскольку у переменных есть адрес, а у значений нет). Следовательно, если
переменная-отношение R1 может иметь атрибуты, значения которых являются указа-
телями “на” переменную-отношение R2, то эти указатели будут указывать на перемен-
ные кортежей, а не на их значения. Но в реляционной модели нет такого понятия,
как переменная кортежа. В реляционной модели рассматриваются значения отноше-
ний, которые, попросту говоря, являются множествами значений кортежей, которые, в
свою очередь, являются множествами скалярных значений. В реляционной модели
также рассматриваются переменные-отношения, которые являются переменными, зна-
Глава 25. Объектно-реляционные базы данных
1011
чения которых — отношения. Однако в ней не используются переменные кортежей
(т.е. переменные, значения которых — кортежи) или скалярные переменные
(переменные, значения которых — скаляры). Единственный вид переменных, который
включен в реляционную модель (и единственный вид переменных, который допустим
в реляционных базах данных), — это именно переменные-отношения. Отсюда следу-
ет, что смешивание указателей и отношений представляет ЗНА ЧИТЕЛЬНОЕ от-
клонение от реляционной модели, вводя совершенно новый вид переменной. Как отме-
чалось в предыдущем разделе, мы бы могли доказать, что это серьезное нарушение
концептуальной целостности реляционной модели.
В [24.21] и [25.11] можно найти дополнительные аргументы в поддержку этой пози-
ции. А в [25.8]—[25.10] и [25.13] обсуждается важное связанное понятие существенности
(конструкций данных в модели данных).
Из приведенного выше аргумента следует, что большинство (а может быть, и все) со-
временных объектно-реляционных продуктов и даже те, в которых нет первой грубей-
шей ошибки, все же смешивают указатели и отношения, как это ранее объяснялось. Ко-
гда Кодд впервые определил реляционную модель, он умышленно исключил указатели.
Вот цитата из его работы [5.2].
“С уверенностью можно считать, что все группы пользователей и, в частности,
конечные пользователи, понимают действие сравнения значений, но относительно
немногие понимают сложность использования указателей. Реляционная модель ос-
новывается на этом фундаментальном принципе... Обработка указателей в боль-
шей степени подвержена ошибкам, чем выполнение сравнения значений, даже если
пользователям понятны все тонкости работы с указателями. ”
Обработка указателей часто требует их кэширования, а это, как известно, процесс, в
котором довольно легко допустить ошибку. Как уже отмечалось в главе 24, именно этот
аспект объектных систем дает повод для критики, которая в некоторых случаях форму-
лируется в выражениях, прямо утверждающих, что “такие системы выглядят, как изби-
тый CODASYL”.
Как возникла вторая грубейшая ошибка
В литературе трудно найти действительное объяснение второй грубейшей ошибки
(имеются всякие технические объяснения, но есть основания полагать, что это вовсе не
технические, а политические объяснения). Конечно, учитывая тот факт, что все объектные
системы и языки включают указатели (в виде идентификаторов объектов), можно считать,
что идея смешивания указателей и отношений почти наверняка возникла от желания сде-
лать реляционные системы более “объектно-подобными”, но такое “объяснение” просто
передвигает проблему на другой уровень. Мы уже разъясняли, и, на наш взгляд, более чем
достаточно, что объектные системы предоставляют пользователям указатели именно пото-
му, что в них модель недостаточно отличается от реализации.
Поэтому мы можем только предположить, что главная причина широкого рас-
пространения идеи смешивания указателей и отношений, в первую очередь, состоит
в том, что слишком мало пользователей понимают, почему указатели были исклю-
чены из отношений. Как говорил Сантаяна, те, кто не помнят прошлого, обречены
повторить его. Мы совершенно согласны с точкой зрения Мориса Вилкеса, кото-
рый писал следующее [25.35].
1012
Часть VI. Объектные и объектно-реляционные базы данных
“Мне хотелось бы рассматривать множество относящихся к компьютерным
наукам предметов непременно в историческом контексте... Студентам необ-
ходимо понимать, как возникла настоящая ситуация, что было опробовано,
что работало, а что нет и какой возможен прогресс за счет усовершенствова-
ния аппаратного обеспечения. Отсутствие исторического аспекта в их обуче-
нии приводит к тому, что студенты пытаются решить каждую проблему, ис-
ходя из начальных условий. Они способны предложить решения, которые мож-
но было бы считать подходящими в прошлом. Вместо того чтобы опираться
на своих предшественников, они пытаются идти в одиночку. ”
25.4. Вопросы реализации
Одним из важных следствий надлежащей поддержки типов данных является то, что
сторонние изготовители, а также сами изготовители СУБД могут встраивать и продавать
отдельно пакеты “типов данных”, которые могут эффективно включаться в СУБД. При-
мерами таких пакетов могут служить пакеты для поддержки сложной обработки текстов,
пакеты для обработки финансовых хронологических рядов данных, анализа геокосмиче-
ских (картографических) данных и т.д. Такие пакеты называются по-разному, “data
blades” (“пластины данных”) в СУБД Informix, “data cartridges” (“кассеты данных”) в
СУБД Oracle, “relational extenders” (“реляционные расширители”) в СУБД DB2 корпора-
ции IBM4 и т.д. Мы же здесь будем использовать термин пакеты типов.
Однако добавление в систему нового пакета типов — это нетривиальная задача, и
возможность такого добавления оказывает существенное влияние и на проектирование, и
на структуру самой СУБД. Чтобы разобраться, почему так происходит, рассмотрим, что
случится, если, например, некоторые запросы включают ссылки на данные некоторого
типа, определенного пользователем, или вызовы некоторых операторов, определенных
пользователем (или то и другое).
Во-первых, транслятор языка запросов должен уметь выполнять грамматический
разбор и проверку запрашиваемого типа, поэтому он должен кое-что знать о типах
и операторах, определяемых пользователем.
Во-вторых, оптимизатор должен уметь решать соответствующие запросные схемы
для таких запросов, поэтому ему также должны быть известны определенные
свойства этих определяемых пользователем типов и операторов. В частности, ему
должно быть известно, как физически хранятся соответствующие данные
(см. следующий абзац).
В-третьих, компонент, который контролирует физическое хранение данных, дол-
жен поддерживать новые структуры хранения (Q-деревья, R-деревья и т.д.), уже
упоминавшиеся в разделе 25.1. Ему может также потребоваться поддержка воз-
можности вводить новые структуры хранения и собственные методы доступа,
предоставляемой достаточно подготовленным пользователям (см. [25.21], [25.33]).
Все это вместе приводит к тому, что фактически система должна быть открытой
или расширяемой, причем на нескольких уровнях. Далее мы рассмотрим каждый из
этих уровней.
4 По нашему мнению, совершенно несоответствующий термин.
Глава 25. Объектно-реляционные базы данных
1013
Анализ запросов и проверка типа
В обычных системах, где все допустимые операторы и типы встроены, информация
относительно них может быть (обычно так и есть в действительности) “зашита” в компи-
ляторе языка запросов. В системе, где пользователи могут определять собственные типы
и операторы, наоборот, такой жесткий подход, очевидно, не годится. Поэтому в них не-
обходимо реализовать следующее.
1. Информация относительно типов и операторов, определяемых пользователем, а
также, возможно, и относительно встроенных типов и операторов хранится в сис-
темном каталоге. Поэтому такой каталог должен быть перепроектирован или по
крайней мере расширен. Очевидно, что при установке нового пакета типов потре-
буются многочисленные изменения в каталоге. (В терминах языка Tutorial D такое
обновление каталога может быть выполнено неявно, как часть процесса выполне-
ния соответствующих операторов определения — TYPE и OPERATOR.)
2. Сам компилятор должен быть переписан, чтобы иметь доступ к каталогу с целью
получения необходимых данных о типах и операторах. Эти данные будут исполь-
зоваться компилятором для проверки типа во время компиляции, как описано в
главах 5, 8 и 19.
Оптимизация
Хотя проблема оптимизации включает множество вопросов, мы можем затронуть ее
здесь лишь в самых общих чертах. Перечислим некоторые из этих вопросов.
Преобразование выражения (“переписывание запроса”). Как указывалось в гла-
ве 17, обычный оптимизатор переписывает запросы, используя определенные за-
коны преобразования. Исторически так сложилось, что все эти законы “зашиты” в
оптимизатор, поскольку все типы и операторы встроены. В объектно-реляционной
системе, напротив, соответствующие правила (по крайней мере для того, чтобы
использовать типы и операторы, определяемые пользователем) должны храниться
в каталоге. Поэтому требуется дополнительное расширение каталога, а также пе-
реработка оптимизатора. Приведем несколько конкретных примеров.
а) Пусть имеется выражение NOT (QTY > 500). Хороший обычный оптимизатор
преобразует его в выражение QTY < 500, поскольку в этом виде индекс QTY
можно использовать, а в первоначальном — нет. По аналогичным причинам
новому оптимизатору необходимо знать, когда один определенный пользовате-
лем оператор является отрицанием другого.
б) Хорошему обычному оптимизатору известно, что, например, выражения
QTY > 500 и 500 < QTY логически эквивалентны. Поэтому для нового оптими-
затора также требуется информация, когда два определенных пользователем
оператора являются противоположными в этом смысле.
в) Хорошему обычному оптимизатору известно, что, например, операторы “+” и
нейтрализуют друг друга (т.е. являются обратными). Например, выражение
QTY + 500 - 500 сокращается просто до QTY. Поэтому для нового оптимизато-
ра также требуется информация, когда два определенных пользователем опера-
тора являются обратными в этом смысле.
1014
Часть VI. Объектные и объектно-реляционные базы данных
Селективность. Булево выражение, такое как QTY > 500, оптимизаторы
обычно приблизительно оценивают на селективность, т.е. определяют процент
кортежей, для которых оно будет иметь значение true. Для обычных оптими-
заторов информация о селективности, опять же, может быть “зашита” в опти-
мизатор. Для типов и операторов, определяемых пользователем, необходимо
обеспечить способ передачи информации оптимизатору с помощью вызова
некоторого определяемого пользователем кода, позволяющего оценить селек-
тивность выражения.
Стоимость формулы. Оптимизатору необходимо знать, какова стоимость выпол-
нения данного оператора, определяемого пользователем. Например, пусть задано
выражение р AND g, где р, скажем, — вызов оператора AREA, область определения
которого представляет какой-то сложный многоугольник, ад— операция просто-
го сравнения, такая как QTY > 500. По-видимому, предпочтительнее была бы та-
кая система, которая вначале выполняет операцию д. Тогда вызов р выполнялся
бы только в том случае, когда результат выполнения операции сравнения g был бы
равен true. В действительности некоторые классические эвристические алгоритмы
преобразования выражений, которые всегда проверяют ограничение перед опера-
цией соединения, не всегда пригодны для типов и операторов, определяемых
пользователем (см. [25.7], [25.18]).
Структуры хранения и методы доступа. Очевидно, оптимизатору необходимо
знать, какие структуры хранения и методы доступа используются в системе
(см. следующий подраздел).
Структуры хранения
Должно быть ясно, что для объектно-реляционных систем требуется больше спосо-
бов, возможно, значительно больше способов хранения и доступа к данным на физиче-
ском уровне по сравнению с тем, что обычно предоставляется традиционными SQL-
системами. Перечислим некоторые из новых подходов.
Новые структуры хранения. Как уже отмечалось, системе может потребо-
ваться поддержка новых структур хранения на внешних носителях (R-дере-
вья и т.д.) и даже возможность вводить дополнительные структуры хране-
ния и собственные методы доступа, предоставляемая достаточно подготов-
ленным пользователям.
Индексы для данных, тип которых определяется пользователем. Обычные ин-
дексы строятся для данных некоторого встроенного типа со встроенным
“пониманием”, что означает для них оператор “<”. В объектно-реляционных сис-
темах необходима возможность создавать индексы по данным, тип которых опре-
деляется пользователем и которые основываются на семантике соответствующего
оператора “<”, также определенного пользователем (конечно, подразумевается,
что такой оператор определен в первую очередь).
Индексы по результатам выполнения оператора. Возможно, будет не слишком
много пользы в построении индекса непосредственно по значениям данных типа
POLYGON (многоугольник). Вероятнее всего, все, что удастся получить, — это та-
кой индекс, в котором многоугольники будут упорядочены в соответствии с их
Глава 25. Объектно-реляционные базы данных
1015
внутренним кодированным представлением в виде строк байтов5. Однако в дейст-
вительности более полезен был бы индекс, построенный на основании областей,
охватываемых этими многоугольниками.
Замечание. В главе 21 мы назвали такие индексы функциональными.
25.5. Преимущества реального сближения двух
технологий
В [25.1] Стоунбрейкер предлагает “матрицу классификации” для СУБД (рис. 25.4).
Квадрант 1 этой матрицы представляет приложения, которые обрабатывают простые
данные и которым не требуется поддержка произвольных запросов (обычный текстовый
процессор— неплохой пример для этого случая). Такие приложения на самом деле не
являются приложениями баз данных в полном смысле этого слова. “СУБД”, которая
лучше всего подойдет для подобных приложений, — встроенная файловая система, пре-
доставляемая пользователю как часть операционной системы.
есть запросы 2 4
нет запросов 1 3
простые данные сложные данные
Рис. 25.4. Матрица классификации СУБД, предложенная Стоунбрейкером
Квадрант 2 представляет приложения, которые предусматривают ввод произвольных
запросов, но все же имеют дело лишь с относительно простыми данными. В эту катего-
рию попадает большинство современных бизнес-приложений. Подобные приложения
довольно хорошо поддерживаются традиционными реляционными СУБД (или по край-
ней мере СУБД, использующими язык SQL).
Квадрант 3 представляет приложения, в которых используются сложные данные и
выполняется обработка запросов, но лишь заранее запланированных. К этой категории,
например, могут принадлежать приложения САПР/АСУТП. Современные объектные
СУБД первоначально нацеливались именно на этот сегмент рынка, поскольку традици-
онные СУБД не слишком хорошо справляются с задачами, характерными для данной ка-
тегории приложений.
Квадрант 4 представляет приложения, которые нуждаются как в поддержке сложных
данных, так и в обработке произвольных запросов к этим данным. В качестве примера
Стоунбрейкер приводит базу данных, содержащую оцифрованные 35-миллиметровые
слайды, и типичный запрос к этой базе — “Получить все снимки закатов, сделанные в
пределах 20 миль от Сакраменто, Калифорния”. Затем он продолжает приводить аргу-
менты в поддержку своей позиции; он считает, что объектно-реляционные СУБД необ-
ходимы для приложений, попадающих в этот квадрант, и через несколько лет в него бу-
5 Напомним, что, как указывалось в главе 24, традиционные системы предоставляют тип
данных BLOB для обработки “больших двоичных объектов ’. В объектно-реляционных системах
значения данных некоторых типов, определяемых пользователем, могут физически храниться
как данные типа BLOB.
1016
Часть VI. Объектные и объектно-реляционные базы данных
дет попадать или перейдет большая часть приложений. Например, даже обычные прило-
жения кадрового учета будут расширены для поддержки хранения фотографий сотруд-
ников, звуковых записей (речевых сообщений) и т.п.
Подводя итог, Стоунбрейкер утверждает (и мы с ним согласны), что “объектно-
реляционные системы в будущем потребуются всем” и что они — отнюдь не преходящая
причуда, которая скоро будет заменена другим, таким же недолговечным, но модным вея-
нием. Однако здесь следует напомнить, что, как мы выяснили, настоящая объектно-
реляционная система является просто настоящей реляционной системой. В частности, это
система, в которой не допущена ни одна из двух грубейших ошибок. Стоунбрейкер, похо-
же, не совсем согласен здесь с нашей позицией, по крайней мере в [25.31] он об этом ни ра-
зу не упомянул, поэтому мы можем предполагать, что, с его точки зрения, смешивание ука-
зателей и отношений не только приемлемо, но даже желательно (фактически — требуется).
Но как бы то ни было, мы могли бы согласиться, что истинная объектно-реляционная
система могла бы решить все проблемы, которые (как мы это утверждали в предыдущей
главе) являются проблемами именно объектных систем, а не систем объектно-
реляционных. Перечислим конкретные возможности, которые должны поддерживаться
истинной объектно-реляционной системой без каких-либо ограничений.
Произвольные запросы, определение представлений и поддержка декларативных
ограничений целостности данных
Методы, которые охватывают классы (нет необходимости в выделении “целевого
операнда”)
Динамически определяемые классы (для размещения результатов произвольных
запросов)
Двойственный режим доступа (в главе 24 мы подчеркивали этот вопрос, но в объ-
ектных системах обычно принцип двойственного режима не поддерживается; в
них, как правило, используются разные языки для программного и интерактивного
доступа к базе данных)
Отложенные проверки целостности (до момента фиксации)
Ограничения переходов
Семантическая оптимизация
Связи, степень которых больше двух
Правила внешних ключей (ON DELETE CASCADE и т.п.)
Возможности оптимизации
И т.д. Кроме того, желательно следующее.
Идентификаторы и указатели используются неявно и полностью скрыты от поль-
зователя
“Сложные” объектные вопросы (например, что означает соединение двух объек-
тов?) больше не возникают
Преимущества инкапсуляции как таковые используются, но по отношению к ска-
лярным значениям в отношениях, а не к самим отношениям
Реляционные системы теперь могут справляться с задачами в области “сложных”
приложений, таких как САПР/АСУТП, которые нами уже обсуждались
При этом реляционный подход остается концептуально чистым.
Глава 25. Объектно-реляционные базы данных
1017
25.6. Резюме
В этой главе вкратце были рассмотрены объектно-реляционные системы. Выясни-
лось, что такие системы в своей основе являются (или должны быть) просто реляцион-
ными системами, которые поддерживают реляционную концепцию доменов (т.е. типов)
надлежащим образом, а это, в частности, означает, что пользователи имеют (или должны
иметь) возможность определять собственные типы. Для реляционной модели ничего не
требуется, чтобы достичь необходимой нам объектной функциональности, кроме как
реализовать такую модель.
Затем обсуждались две грубейшие ошибки. Первая заключалась в отождествлении
объектных классов и переменных-отношений (уравнение, которое, к сожалению, выгля-
дит привлекательно). Мы выдвинули предположение, что ошибка возникла из-за путани-
цы с двумя совершенно различными интерпретациями термина объект. Был подробно
рассмотрен пример, который наглядно продемонстрировал, какой может быть система, в
которой допущена первая грубейшая ошибка, а также показал, к каким последствиям
приводит такая ошибка. Одним из последствий этой ошибки является то, что она приво-
дит непосредственно ко второй грубейшей ошибке, а именно — к смешиванию указате-
лей и отношений (хотя на самом деле вторая ошибка может быть допущена и без первой,
и почти все системы на современном рынке, к сожалению, ее допускают). На наш взгляд,
вторая грубейшая ошибка нарушает концептуальную целостность реляционной модели
во многих отношениях. В частности, она нарушает принцип взаимозаменяемости базо-
вых и производных отношений.
Далее бегло рассматривались некоторые вопросы реализации. Важнейший из них —
добавление новых “пакетов типов”— влияет по крайней мере на компилятор и компо-
ненты управления хранением данных в системе. Поэтому объектно-реляционные систе-
мы не могут быть реализованы простым добавлением нового уровня программ к уже су-
ществующей системе. Система должна быть перестроена с самого основания, чтобы ка-
ждый из ее компонентов в случае необходимости был открытым.
И наконец мы познакомились с матрицей классификации СУБД Стоунбрейкера и крат-
ко обсудили те преимущества, которые могли бы быть получены от истинного сближения
объектных и реляционных технологий (здесь под “истинным сближением” подразумевает-
ся, в частности, что не допущены две указанные выше грубейшие ошибки).
Список литературы
В последние годы было создано несколько объектно-реляционных прототипов. Среди
них наиболее известны система Postgres, разработанная в университете штата Калифор-
ния в Беркли ([25.26], [25.30], [25.32]), и система Starburst, разработанная в корпорации
IBM ([25.14], [25.17], [25.21], [25.22]). Обратите внимание, что ни одна из них не может
быть отнесена, по крайней мере в оригинальной версии, к системам, объектный подход
которых основывался бы на “очевидно корректном” уравнении домен = класс.
Также необходимо отметить, что в язык SQL3 включено несколько возможностей, кото-
рые специально предназначены для поддержки объектно-реляционных систем, (см. при-
ложение Б).
25.1. Brooks F.P., Jr. The Mythical Man-Month (20th anniversary edition).— Reading,
Mass.: Addison-Wesley, 1995.
1018
Часть VI. Объектные и объектно-реляционные базы данных
25.2. Carey M.J., Mattos N.M., Nori A.K. Object/Relational Database Systems: Principles,
Products, and Challenges // Proc. 1997 ACM SIGMOD Int. Conf, on Management of
Data. — Tucson, Ariz., May, 1997.
Цитата из работы: “Абстрактные типы данных, определяемые пользователем
функции, типы строк, ссылки, наследование, подтаблицы, коллекции, триггеры...
Что же все-таки это такое?”. Хороший вопрос! В списке есть восемь возможностей
и по умолчанию предполагается, что они присутствуют в языке SQL3. Мы могли
бы доказать, что четыре из них нежелательны, две другие относятся к тому же раз-
ряду, а остальные две не являются специфическими для объектно-реляционной
системы (см. приложение Б).
25.3. Carey M.J. et al. The BUCKY Object/Relational Benchmark // Proc. 1997 ACM
SIGMOD Int. Conf, on Management of Data. — Tucson, Ariz., May, 1997.
Цитата из резюме: “BUCKY (Benchmark of Universal or Complex Kwery Ynterfaces
[так!]) — эталонный тест, ориентированный на запросы, с помощью которого про-
веряются многие из ключевых возможностей объектно-реляционной системы,
включая типы строк и наследование, ссылки и выражения путей, множества ато-
марных значений и ссылок, методы и позднее связывание, а также определяемые
пользователем абстрактные типы данных и их методы”.
25.4. Cattell R.G.G. What Are Next-Generation DB Systems? // CACM. — October, 1991. —
34, № 10.
25.5. Chamberlin D.D. Relations and References — Another Point of View // InfoDB. —
April, 1997, — 10, №6.
См. аннотацию к [25.11].
25.6. Chaudhuri S., Gravano L. Optimizing Queries over Multi-Media Repositories // Proc. 1996
ACM SIGMOD Int. Conf, on Management of Data. — Montreal, Canada, June, 1996.
Объектно-реляционные базы данных могут быть использованы как “мультимедиа-
хранилища”. Для запросов мультимедиаданных обычно недостаточно просто мно-
жества результирующих объектов; необходимо еще знать степень соответствия
для каждого такого объекта, которая показывает, в какой мере он удовлетворяет
поисковому условию (например, “степень красноты” изображения). Такими запро-
сами можно задавать порог степени соответствия, а также квоту [6.4]. В этой ста-
тье рассматривается оптимизация таких запросов.
25.7. Chaudhuri S., Shim К. Optimizing Queries with User-Defined Predicates П Proc. 22nd
Int. Conf, on Vary Large Data Bases. — Mumbai (Bombay), India, September, 1996.
25.8. Codd E.F. and Date C.J. Interactive Support for Nonprogrammers: The Relational and
Network Approaches // Date C.J. Relational Database: Selected Writings. — Reading,
Mass.: Addison-Wesley, 1986.
В статье вводится понятие существенности — концепция, которая очень важна
для правильного понимания моделей данных (в обоих смыслах этого термина! —
см. главу 1, раздел 1.3). Реляционная модель в своей основе имеет лишь одну су-
щественную конструкцию, а именно — отношение. Объектная модель, напротив,
имеет много конструкций: множества, мультимножества, списки, массивы и т.д.
(не говоря уже об идентификаторах объектов). См. [25.9], [25.10] и [25.13].
Глава 25. Объектно-реляционные базы данных
1019
25.9. Date C.J. Support the Conceptual Schema: The Relational and Network Approaches //
Relational Database Writings 1985-1989. — Reading, Mass.: Addison-Wesley, 1990.
Один из аргументор против смешивания указателей и отношений [25.11]— это
сложность, к которой приводят указатели. В данной статье приводится пример,
очень ясно иллюстрирующий эту сложность (рис. 25.5 и 25.6).
MAJOR_P# MINOR_P# QTY
Р1 Р2 2
Р1 Р4 4
Р5 РЗ 1
РЗ Р6 3
Р6 Р1 9
Р5 Р6 8
Р2 Р4 3
Рис. 25.5. Отношение спецификации материалов
Сплошные линии: "входимость деталей"
Пунктирные линии: "где используется"
Рис. 25.6. Аналог отношения, показанного на рис. 25.5, который основан на ука-
зателях
1020
Часть VI. Объектные и объектно-реляционные базы данных
25.10. Date C.J. Essentiality // Relational Database Writings 1991-1994.— Reading, Mass.:
Addison-Wesley, 1995.
25.11. Date C.J. Don’t mix Pointers and Relations! и Don’t mix Pointers and Relations! —
Please // Date C.J., Darwin H. and McGoveran D. Relational Database Writings 1994-
1997. — Reading, Mass.: Addison-Wesley, 1998.
В первой из этих статей приводятся аргументы против второй грубейшей ошибки.
В [25.5] Чемберлин опровергает некоторые аргументы данной статьи. Вторая ста-
тья является прямым ответом на опровержение Чемберлина.
25.12. Date C.J. Objects and Relations: Forty-Seven Points of Light // Date C.J., Darwin H. and
McGoveran D. Relational Database Writings 1994-1997.— Reading, Mass.: Addison-
Wesley, 1998.
Подробный ответ на [25.19].
25.13. Date C.J. Relational Really Is Different. Выпуск № 10 серии статей [5.9].
www.intelligententerprise. com.
25.14. DeMichael L.G., Chamberlin D.D., Lindsay B.G., Agrawal R. and Arya M. Polyglot:
Extentions to Relational Databases for Shrable Types and Functionas in a Muti-
Language Environment// IBM Research Report RJ8888. — 1992.
Цитата из резюме: “Polyglot — расширяемая система типов реляционной базы дан-
ных, поддерживающая наследование, инкапсуляцию и динамическое назначение
методов”. (Динамическое назначение методов (dynamic method dispatch)— это
другое название связывания во время выполнения программы (синонимы: позднее
связывание (late binding) и динамическое связывание (dynamic binding). — Прим,
перев.) Далее: “[Polyglot] позволяет использовать несколько прикладных языков,
причем объекты сохраняют свое поведение при переходе между приложениями баз
данных и прикладными приложениями. В статье описано устройство системы
Polyglot, расширения языка SQL для поддержки используемых системой типов и
методов и реализация системы в [прототипе] проекта Starburst”.
Система Polyglot имеет непосредственное отношение к вопросам этой главы (а также
глав 5, 19 и 24). Здесь следует сделать несколько замечаний. Во-первых, реляцион-
ный термин домен в статье ни разу не упоминается (что очень удивительно). Во-
вторых, в системе Polyglot имеются встроенные генераторы типов (в терминах этой
системы — метатипы)'. базовый тип, тип-кортеж, переименованный тип, тип-
массив и тип-язык, но (что также удивительно) нет типа-отношения. Однако в
системе имеется возможность вводить новые генераторы типов.
25.15. DeWitt D.J., Karba N., Luo J., Patel J.M., Yu J.-B. Client-Server Paradise // Proc. 20th
Int. Conf, on Vary Large Data Bases. — Santiago, Chile, September, 1994.
Система Paradise (Parallel Data Information System — информационная система
параллельных данных) — это разработанный в Висконсинском университете
объектно-реляционный прототип системы, “созданный для ГИС-приложений”
(ГИС — геоинформационная система). В статье описаны архитектура и реализа-
ция системы Paradise.
25.16. Godfrey М., Mayr Т., Seshadri Р. and Thorsten von Eichen. Secure and Portable
Database Extensibility // Proc. 1998 ACM SIGMOD Int. Conf, on Management of
Data. — Seattle, Wash, June, 1998.
Глава 25. Объектно-реляционные базы данных
1021
“Поскольку операторы, определяемые пользователем, поставляются неизвестными
или ненадежными клиентами, в СУБД должны быть предусмотрены меры предосто-
рожности по отношению к операторам, которые могут разрушить систему, модифи-
цировать ее файлы или непосредственно память (в обход механизма санкционирова-
ния), монополизировать центральный процессор, память или дисковые ресурсы”
(цитата несколько изменена). Очевидно, необходим дополнительный контроль. В
этой статье рассказывается об исследованиях данного вопроса с использованием
языка Java и объектно-реляционного прототипа PREDATOR [25.24]. В обнадежи-
вающем заключении говорится, что система базы данных “может поддерживать
безопасные и переносимые расширения с использованием языка Java без значи-
тельных потерь в производительности”.
25.17. Haas L.M., Freytag J.C., Lohman G.M., Pirahesh Н. Extensible Query Processing in
Starburst // Proc. ACM SIGMOD Intern. Conf, on Management of Data. — Portland,
Ore., June, 1989.
В работе представлены цели расширенного проекта Starburst [25.21]: “В
Starburst предусмотрено добавление новых методов хранения таблиц, новых
типов доступа и ограничений целостности, новых типов данных, функций и
новых операций с таблицами”. При этом система делится на два основных
компонента, Core и Corona, которые соответствуют компонентам RSS и RDS
оригинальной системы System R [4.2]. В компоненте Core поддерживаются
функции расширения, описанные в [25.21], а в компоненте Corona— язык за-
просов Hydrogen, который является диалектом языка SQL. В этом диалекте ис-
ключено большинство ограничений реализации языка SQL, принятого в систе-
ме System R, он более независим, поддерживает рекурсивные запросы и может
быть расширен пользователем. В статье содержится интересное обсуждение
проблемы “переписывания запросов”, т.е. правил преобразования выражений
(см. главу 17). Об этом также можно прочесть в [17.50].
25.18. Hellerstein J.M., Naughton J.F. Query Execution Techniques for Caching Expensive
Methods 11 Proc. 1996 ACM SIGMOD Int. Conf, on Management of Data. — Montreal,
Canada, June, 1996.
25.19. Kim W. On Marrying Relations and Objects: Relation-Centric and Object-Centric
Perspectives // Data Base Newsletter. — November/December, 1994. — 22, № 6.
В этой статье приводятся аргументы, оспаривающие мнение, согласно которому
отождествление переменных-отношений и классов— серьезная ошибка (“первая
грубейшая ошибка”). Статья [25.12] — ответ на данную статью.
25.20. Kim W. Bringing Object/Relational Down to Earth // DBP&D.— July, 1997.—
10, №7.
В этой статье автор утверждает, что на рынке объектно-реляционных систем
“путаница наверняка будет продолжаться”, поскольку, во-первых, “на расширения
типов данных была взвалена непомерная ноша” и, во-вторых, “степень полноты
объектно-реляционных продуктов... вызывает серьезные опасения”. Предлагается
“практическая метрика объектно-реляционной полноты, которая может быть ис-
пользована как руководство для определения, является ли продукт действительно
объектно-реляционным”. В схему автора включаются следующие критерии.
1022
Часть VI. Объектные и объектно-реляционные базы данных
1. Модель данных 5. Производительность и масштабируемость
2. Язык запросов 6. Инструменты базы данных
3. Критические к сбоям службы 7. Полнота использования вычислительной
4. Вычислительная модель мощности
Отдавая должное первому критерию (самому важному), Ким придерживается
точки зрения (отличной от той, которая представлена в Третьем манифесте
[3.3]), что модель данных должна быть “основной объектной моделью, опреде-
ленной группой Object Management Group (OMG)”, которая “включает реляци-
онную модель данных, а также основные концепции объектно-ориентированного
моделирования объектно-ориентированных языков программирования”. По мне-
нию Кима, сюда входят следующие понятия: класс (в статье добавляется “или
тип”), экземпляр, атрибут, ограничения целостности, идентификаторы объ-
ектов, инкапсуляция, (.множественное) наследование классов, (множественное)
наследование ADT, данные типа ссылок, атрибуты со значениями-
множествами, атрибуты классов, методы классов и т.п. Заметим, что отноше-
ния, которые мы относим и к критическим, и к фундаментальным понятиям, ни-
где явно не упоминаются. Ким утверждает, что основная объектная модель груп-
пы OMG в дополнение ко всему перечисленному в списке полностью включает
реляционную модель, хотя на самом деле это не так.
25.21. Lindsay В., McPherson J., Pirahesh Н. A Data Management Extension Architecture
// Proc. ACM SIGMOD Intern. Conf, on Management of Data. — San Francisco,
Calif., May, 1987.
В работе описана архитектура прототипа системы Starburst, в котором
“реализованы расширения управления данными для реляционных СУБД”. Описа-
ны два типа таких расширений: на основе определенных пользователем структур
хранения и методов доступа, а также на основе определенных пользователем огра-
ничений целостности (но непременно все ограничения целостности должны быть
определены пользователем?) и триггерных процедур. Однако “помимо этих, суще-
ствуют также другие направления расширения СУБД, включая определенные
пользователем абстрактные типы данных и технологии оценки запросов”.
25.22. Lohman G.M. et al. Extensions to Starburst: Objects, Types, Functions and Rules //
CACM. — October, 1991. — 34, № 10.
25.23. Maier D. Comments on the Third-Generation Database Sytem Manifesto // Tech. Report
No. CS/E 91-012. — Oregon Gradulate Center, Ore. — April, 1991.
Майер весьма критичен буквально ко всему материалу статьи [25.34]. Мы согласны с
некоторыми его критическими замечаниями, но не согласны с остальными. Однако
нас заинтересовали следующие высказывания (в них поддерживается наша точка
зрения, что концепция объектов содержит лишь одну хорошую идею, а именно —
надлежащую поддержку типов данных)'. “Многие из нас добивались очищения тео-
рии объектно-ориентированных систем баз данных от сути “объектной ориентиро-
ванности”... Мои взгляды на то, что является наиболее важным в объектно-
ориентированных базах данных, менялись с течением времени. Сначала я думал, что
это было наследование и модель сообщений. Позже я пришел к выводу, что идентич-
ность объектов, поддержка сложного состояния и инкапсуляция поведения более
Глава 25. Объектно-реляционные базы данных
1023
важны. Но в последнее время, когда я услышал мнение пользователей объектно-
ориентированных СУБД о том, чему они придают наибольшее значение в таких сис-
темах, я считаю, что решающее— это возможность расширения типа. Идентич-
ность, сложное состояние и инкапсуляция по-прежнему важны, но лишь настолько,
насколько они поддерживают создание новых типов данных”.
25.24. Patel J. et al. Bilding a Scalable Geo-Spacial DBMS: Technology, Implementation,
and Evaluation // Proc. ACM SIGMOD Int. Conf, on Management of Data. — Tucson,
Ariz. — May, 1997.
Цитата из резюме: “В этой статье представляется ряд методов для распараллелива-
ния геокосмических систем баз данных и обсуждается их реализация в объектно-
реляционной системе баз данных Paradise” [25.15].
25.25. Ramakrishnan R. Database Management Systems. — Boston, Mass.: McGraw-Hill. — 1998.
25.26. Rowe L.A., Stonebraker M.R. The Postgres Data Model // Proc. 13th Int. Conf, on Vary
Large Data Bases. — Brighton, UK. — September, 1987.
25.27. Samet H. The Design and Analysis of Spatial Data Structures.— Reading, Mass.:
Addison-Wesley, 1990.
25.28. Saracco C.M. Universal Database Management: Guide to Object/Relation
Technolody. — San Francisco, Calif.: Morgan Kaufmann, 1999.
Интересный обзор, написанный на высоком уровне. Однако отметим, что его автор
не отвергает (как, кстати, и Стоунбрейкер в [25.31]) очень сомнительную форму
наследования, включающую версию идеи подтаблиц и супертаблиц (о которой мы
отзываемся весьма скептически в начале [13.12]). Данная версия существенно от-
личается от последней версии, включенной в язык SQL3. Поясним это на примере.
Предположим, что таблица PGMR (программисты) определена как подтаблица таб-
лицы ЕМР (служащие). Тогда Саракко и Стоунбрейкер считают, что таблица ЕМР
содержит строки лишь для служащих, которые не являются программистами, в то
время как в языке SQL3 эта таблица воспринималась бы как содержащая строки
для всех служащих (см. приложение Б).
25.29. Seshadri Р., Paskin М. PREDATOR: An OR-DBMS with Enhanced Data Types // Proc.
1997 ACM SIGMOD Int. Conf, on Management of Data. —Tucson, Ariz., May, 1997.
Суть системы PREDATOR— предоставить механизм для каждого типа данных,
чтобы можно было задавать семантику их методов. Эта семантика затем использу-
ется для оптимизации запросов.
25.30. Stonebraker М. The Design of the POSTGRES Storage System 11 Proc. 13th Intern.
Conf, on Very Large Data Bases. — Brighton, UK, September, 1987.
25.31. Stonebraker M., Brown P. (with Moore D.) Object/Relational DBMSs: Tracking the
Next Great Wave (2nd edition). — San Francisco, Calif.: Morgan Kaufmann, 1999.
Эта книга представляет собой руководство по объектно-реляционным системам. В
большой степени — фактически почти исключительно — она базируется на продукте
Universal Data Option для СУБД Informix’s Dynamic Server. Этот продукт основывает-
ся на более ранней системе, которая называлась Illustra (коммерческий продукт, в
разработке которого Стоунбрейкер лично принимал участие). В [3.3] можно найти
дополнительный анализ и критику этой книги. См. также аннотацию к [25.28].
1024
Часть VI. Объектные и объектно-реляционные базы данных
25.32. Stonebraker M., Kemnitz G. The Postgres Next Generation Database Management
System // CACM. — October, 1991. — 34, № 10.
25.33. Stonebraker M., Rowe L.A. The Design of Postgres 11 Proc. ACM SIGMOD Intern.
Conf, on Management of Data. — Washington, D.C., June, 1986.
В работе приведены основные цели создания системы Postgres.
1. Обеспечение усовершенствованной поддержки сложных объектов.
2. Обеспечение расширяемости типов данных, операторов и методов доступа.
3. Обеспечение активных инструментов базы данных (аварийных и пусковых), а
также поддержка логических выводов.
4. Упрощение кода СУБД для восстановления после разрушения системы.
5. Проектирование СУБД с учетом преимуществ оптических дисков, многопро-
цессорных рабочих станций и специальных чипов на основе сверхбольших ин-
тегральных схем.
6. Минимальное количество изменений реляционной модели (а может быть, даже
отсутствие изменений).
25.34.Stonebraker М. et al. Third Generation Database System Manifesto // ACM SIGMOD.—
September, 1990. — 19, № 3.
Отчасти эта работа противопоставляется [24.1], в которой, между прочим, по су-
ществу, полностью игнорируется реляционная модель. Цитата: “Системы второго
поколения внесли большой вклад в развитие непроцедурного доступа к данным и
независимости от данных, и этим вкладом нельзя пренебрегать при разработке
систем третьего поколения”. Приведенные ниже положения являются, по сути,
требованиями (в некоторой степени перефразированными), которые предъявляют-
ся к “СУБД третьего поколения”.
1. Обеспечение традиционных служб базы данных, а также более развитых объ-
ектных структур и правил
Система с более развитыми типами
Наследование
Функции и инкапсуляция
Необязательные идентификаторы кортежей
Правила (например, правила целостности), не связанные с конкретными
объектами
2. Преемственность СУБД второго поколения
Использование путей для адресации объектов только в крайнем случае
Определения интенсиональных и экстенсиональных множеств (которые оз-
начают коллекции, автоматически поддерживаемые со стороны системы, и
коллекции, поддерживаемые вручную пользователем)
Обновляемые представления
Кластеризация, индексирование и т.д., скрытые от пользователя
3. Поддержка открытых систем
Поддержка нескольких языков
Ортогональная перманентность типов
Глава 25. Объектно-реляционные базы данных
1025
Поддержка языка SQL
Запуск запросов и вывод результатов, осуществляемые на самом низком
уровне общения между клиентом и сервером
В [3.3] содержатся подробный анализ и критика этой статьи. См. также [25.23].
Замечание. Кстати, сейчас можно пояснить, почему Третий манифест называется
третьим... Он был написан именно после двух предыдущих манифестов (см. [24.1]
и [25.34]) и, мы надеемся, что заменил их.
25.35.Wilkes M.V. Software and the Programmer// CACM. — May, 1991. — 34, № 5.
1026
Часть VI. Объектные и объектно-реляционные базы данных
Приложения
В приложении А приводятся подробные сведения о синтаксисе и семантике выраже-
ний языка SQL/92, что позволяет использовать его как соответствующий справочник. В
приложении Б содержится обзор основных функций языка SQL3, в частности
“объектных” и “объектно-реляционных”. В приложении В представлен перечень наибо-
лее важных сокращений и специальных символов, используемых в данной книге, вместе
с кратким описанием их значения.
1027
Приложение
Выражения языка SQL
АЛ. Введение
Выражения языка SQL, точнее — табличные, условные и скалярные SQL-
выражения, составляют основу этого языка. В данном приложении детально описаны
синтаксис и семантика подобных выражений (в соответствии со стандартом SQL/92).
Однако необходимо сразу же отметить, что названия синтаксических категорий и конст-
рукций языка SQL чаще всего отличаются от тех, которые употребляются в самом стан-
дарте SQL/92 (см. [4.22]). Такой подход выбран потому, что используемые в стандарте
термины часто не совсем удачны, в частности сами термины табличное выражение, ус-
ловное выражение и скалярное выражение не являются стандартными.
А.2. Табличные выражения
Сначала представим BNF-грамматику для выражений типа (табличное выражением
В грамматике полностью исключены опции, имеющие отношение к NULL-значениям
(см. раздел 18.7 главы 18). Отметим, что в данном приложении широко используются со-
глашения о списках, которые были представлены в разделе 4.6 главы 4.
(табличное выражение>
::= <выражение соединения таблиц>
| (выражение без соединения таблиц>
<выражение соединения таблиц>
::= (ссылка на таблицу> [ NATURAL ] JOIN (ссылка на таблицу>
[ ON (условное выражение>
| USING ( <список имен столбцов> ) ]
| (ссылка на таблицу> CROSS JOIN (ссылка на таблицу>
I ((выражение соединения таблиц>)
(ссылка на таблицу>
::= (имя таблицы> [ [ AS ] (имя переменной диапазона>
[ (<список имен столбцов>) ] ]
| ((табличное выражение> ) [ AS ] (переменная диапазона>
[ (<список имен столбдов> ) ]
| (выражение соединения таблиц>
(выражение без соединения таблиц>
::= (терм без соединения таблиц>
| <табличное выражение> UNION [ ALL ]
1028
Приложения
[ CORRESPONDING [ BY (<список имен столбцовУ ) ] ]
<таблинный термУ
| <табличное выражениеУ EXCEPT [ ALL ]
[ CORRESPONDING [ BY (<список имен столбцовУ) ] ]
табличный терм>
<терм без соединения таблицу
::= <первичная таблица без соединения >
| <табличный терМ> INTERSECT [ ALL ]
[ CORRESPONDING [ BY (<список имен столбцовУ ) ] ]
<первичная таблица>
табличный терм>
::= <терм без соединения таблицу
| <выражение соединения таблицу
<первичная таблицаУ
::= <первичная таблица без соединения >
| <выражение соединения таблицу
<первичная таблица без соединения >
::= TABLE <имя таблицыУ
<конструктор таблицЫУ
<выражение выборкиУ
(<выражение без соединения таблицу )
< конструктор таблицыУ
::= VALUES <список конструкторов строку
< конструктор строку
::= <скалярное выражениеУ
(<список скалярных выраженийУ )
(<табличное выражениеУ )
< выражение выборкиУ
::= SELECT [ ALL | DISTINCT ] <список выбираемых элементовУ
FROM <список ссылок на таблицыУ
[ WHERE <условное выражениеУ ]
[ GROUP BY <список имен столбцовУ ]
[ HAVING <условное выражениеУ ]
<выбираемый элементу
::= <скалярное выражениеУ [ [ AS ] <столбец> ]
| [ <переменная диапазонаУ . ] *
Рассмотрим конкретный случай, бесспорно, наиболее важный на практике, а имен-
но — выражения типа <выражение выборкиУ. Их можно рассматривать, хотя и упрощен-
но, как выражения типа <табличное выражениеУ, которые не содержат ключевых слов
Приложение А. Выражения языка SQL
1029
JOIN, UNION, EXCEPT и INTERSECT. Мы говорим “упрощенно”, поскольку, разумеется, та-
кие операторы могут включаться в выражения, которые вложены в рассматриваемое вы-
ражение типа выражение выборки>. Предложения JOIN, UNION, EXCEPT и INTERSECT под-
робно обсуждаются в разделе 7.7 главы 7.
Как видно из приведенного выше определения, выражение типа <выражение
выборки> включает в указанной последовательности предложения SELECT, FROM и необя-
зательные предложения WHERE, GROUP BY и HAVING. Рассмотрим их поочередно.
Предложение SELECT
Предложение SELECT имеет следующий вид
SELECT [ ALL | DISTINCT ] <список выбираемых элементов>
Пояснения
1. Параметр < список выбираемых элементов> не должен быть пустым (формат пара-
метра <выбираемый элемент> рассматривается ниже).
2. Если уточнения ALL и DISTINCT не указаны, то по умолчанию подразумевается ALL.
3. Допустим, предложения FROM, WHERE, GROUP BY и HAVING уже обработаны. Не имеет
значения, какие из них указаны и какие опущены; концептуальный результат обра-
ботки этих предложений всегда будет таблицей (возможно, “сгруппированной”
таблицей, что поясняется ниже). Обозначим эту таблицу как Т1, хотя такой проме-
жуточный концептуальный результат на самом деле не имеет имени.
4. Пусть таблицей Т2 будет таблица, которая является производной от Т1 и была по-
лучена посредством вычисления заданных параметров <выбираемый элемент> для
таблицы Т1 (см. ниже).
5. Пусть таблица ТЗ будет таблицей, которая является производной от Т2. Таблица ТЗ
получается посредством исключения лишних дублирующих строк из таблицы Т2, ес-
ли указано ключевое слово DISTINCT, или идентична таблице Т2 в противном случае.
6. Полученная таблица ТЗ представляет собой окончательный результат выполнения
всей операции.
Рассмотрим допустимые значения параметра <выбираемый элемент^. Возможны два
случая, причем второй случай представляет собой просто сокращение для списка элемен-
тов выборки первого вида. Таким образом, первый случай по сути является основным.
Случай 1. Параметр <выбираемый элемент> принимает следующий вид.
< скалярное выражение> [ [ AS ] <столбец> ]
Параметр <скалярное выражение> обычно (но необязательно) задает один или не-
сколько столбцов таблицы Т1 (см. приведенный выше п. 3). Для каждой строки таблицы
Т1 указанное скалярное выражение в результате вычисления дает некоторое скалярное
значение. Список таких результатов (соответствующих вычислению всех заданных па-
раметров <выбираемый элемент> в предложении SELECT для одной строки таблицы Т1)
составляет одну строку таблицы Т2 (см. приведенный выше п. 4). Если параметр
<выбираемый элемент> включает предложение AS, то неуточненное значение параметра
1030
Приложения
<столбец> из этого предложения присваивается в качестве имени соответствующему
столбцу таблицы Т2 (необязательное ключевое слово AS является лишним и может быть
опущено без какого-либо ущерба). Если же параметр <вы6ираемый элемент> не включает
предложение AS, то, если он содержит просто (возможно, уточненное) имя <столбец>,
это имя назначается соответствующему столбцу таблицы Т2. В противном случае соот-
ветствующий столбец таблицы Т2 фактически не будет иметь имени (на самом деле при-
сваивается имя, “зависящее от реализации”; см. [4.19], [4.22]).
Рассмотрим некоторые дополнительные аспекты.
Поскольку используется имя столбца именно таблицы Т2, а не Т1, представленное
предложением AS имя не может употребляться в предложениях WHERE, GROUP BY и
HAVING, включаемых непосредственно в конструкцию таблицы Т1. Однако на это
имя можно ссылаться в предложении ORDER BY (в частности, при определении
курсора в предложении DECLARE CURSOR), а также во “внешнем” выражении типа
Табличное выражение^ которое содержит рассматриваемое выражение типа
<выражение выборки> как вложенное.
Если некоторый параметр <выбираемый элемент^ включает вызов оператора обоб-
щения и параметр <выражение выборкИ> не включает предложение GROUP BY
(см. ниже), то ни один параметр <выбираемый элемент^ в предложении SELECT не
может включать никаких ссылок на столбец таблицы Т1, кроме случаев, когда такая
ссылка является аргументом (или частью аргумента) в вызове оператора обобщения.
Случай 2. Параметр <выбираемый элемент> принимает следующий вид.
Г
[ <переменная диадазона> . ] *
Если уточнение опущено, т.е. элемент выборки <выбираемый элемент^ представляет
собой просто неуточненный символ такой элемент выборки должен быть единствен-
ным элементом выборки в предложении SELECT. Этот вид элемента выборки является
сокращением для списка всех имен столбцов таблицы Т1 в порядке их следования слева
направо. Если используется уточнение и параметр <выбираемый элемент^ представляет
собой символ уточненный именем переменной кортежа R, т.е. “Я.*”, то такой пара-
метр представляет список имен столбцов для всех столбцов таблицы, соответствующей
переменной кортежа R, в порядке их следования слева направо. (Напомним, что, как ука-
зывалось в разделе 7.7, имя таблицы может использоваться и часто используется, как яв-
ная переменная кортежа. Поэтому параметр <выбираемый элемент> чаще представляется
в виде “Г.*”, а не в виде “Я.*”.)
Предложение FROM
Предложение FROM имеет следующий вид.
FROM <список ссылок на таблицы>
Параметр <список ссылок на таблицы> не должен быть пустым. Пусть указанный
список ссылается на таблицы А, В, ... С. Тогда результат вычисления предложения FROM
будет представлять таблицу, которая равна декартову произведению таблиц А, В,... С.
Приложение А. Выражения языка SQL
1031
Замечание. Напомним, что декартово произведение одной таблицы Т совпадает с са-
мой таблицей Т (см. упр. 6.12 в главе 6). Иначе говоря, в предложении FROM допускается
наличие лишь одного параметра <ссылка на таблицу>.
Предложение WHERE
Предложение WHERE имеет следующий вид.
WHERE <условное выражение>
Пусть таблица Т представляет собой результат вычисления непосредственно предше-
ствующего предложения FROM. Тогда результат вычисления предложения WHERE является
таблицей, производной от таблицы Т. Результирующая таблица формируется путем ис-
ключения из таблицы Т всех строк, для которых вычисление выражения, заданного па-
раметром <условное выражение>, дает ложь. Если предложение WHERE опущено, резуль-
татом будет просто таблица Т.
Предложение GROUP BY
Предложение GROUP BY имеет следующий вид.
GROUP BY <список имен столбцов>
Параметр <список имен столбцов> не должен быть пустым. Пусть таблица Т пред-
ставляет собой результат вычисления непосредственно предшествующих предложений
FROM и WHERE (если такие имеются). Каждый параметр <имя столбца>, указанный в
предложении GROUP BY, должен являться именем столбца (необязательно уточненным)
таблицы Т. Результат вычисления предложения GROUP BY представляет собой сгруп-
пированную таблицу, т.е. множество групп строк, производных от строк таблицы Т,
посредством ее концептуального переупорядочения в минимальное количество групп,
в которых все строки имеют одно и то же значение для сочетания столбцов, опреде-
ляемых предложением GROUP BY. Подчеркнем, что результат будет “ненастоящей таб-
лицей”, поскольку он представляет таблицу групп, а не таблицу строк. Однако пред-
ложение GROUP BY никогда не используется без соответствующего предложения
SELECT, назначение которого заключается в получении настоящей таблицы
(т.е. таблицы строк) из таблицы групп, так что такое временное отклонение от реляци-
онных правил является лишь небольшим изъяном.
Если параметр <выражение выборки> включает предложение GROUP BY, то на вид
соответствующего предложения SELECT накладываются определенные ограничения. А
именно, каждый параметр <выбираемый элемент> в предложении SELECT, включая лю-
бой элемент, который подразумевается под сокращением “*”, должен принимать
единственное значение в пределах каждой группы. Поэтому параметры
<выбираемый элемент> не должны включать никаких ссылок на столбцы таблицы Т,
которые не указаны в самом предложении GROUP BY, за исключением такой ссылки, ко-
торая представляет собой аргумент, или часть аргумента, в вызове оператора обобще-
ния (поскольку в результате такого вызова некоторое множество скалярных значений
в группе сводится к одному скалярному значению).
1032
Приложения
Предложение HAVING
Предложение HAVING имеет следующий вид.
HAVING <условное выражение»
Пусть G— сгруппированная таблица, полученная в результате вычисления непосредст-
венно предшествующих предложений FROM, WHERE (если оно задано) и GROUP BY (если они
заданы). Если предложение GROUP BY не указано, то таблица G будет результатом вычисле-
ния только предложений FROM и WHERE и будет рассматриваться как сгруппированная таб-
лица, которая содержит ровно одну группу1. Другими словами, в этом случае имеется не-
явное концептуальное предложение GROUP BY, в котором не указано никаких группируемых
столбцов. Результат вычисления предложения HAVING является таблицей, производной от
таблицы G путем исключения всех групп, для которых вычисление выражения, заданного
параметром <условное выражение», дает в результате значение ложь.
Приведем некоторые особенности использования предложения HAVING.
Если предложение HAVING опущено, а предложение GROUP BY указано, результатом
будет просто таблица G. Если оба предложения, HAVING и GROUP BY, опущены, ре-
зультатом будет просто “настоящая”, т.е. не сгруппированная, таблица Т, которая
будет получена в результате вычисления предложений FROM и WHERE.
Любое выражение типа <скалярное выражение» в предложении HAVING должно
иметь одно значение в группе (как и скалярное выражение в предложении SELECT,
если имеется предложение GROUP BY).
Подробный пример
В заключение нашего обсуждения выражений типа выражение выборки» рассмотрим
достаточно сложный пример. С его помощью будут проиллюстрированы некоторые (но
отнюдь не все) особенности, объяснявшиеся выше. Сформулируем запрос: “Для каждой
красной и синей детали, которых в сумме поставлено более 350 штук (исключая из всех
поставок детали, количество которых меньше или равно 200 штук), определить номер,
вес в граммах, цвет и максимальное количество ”. Приведем возможную формулировку
этого запроса на языке SQL.
SELECT P.P#,
'Вес в граммах =' AS ТЕХТ1,
Р.WEIGHT * 454 AS GMWT,
Р.COLOR,
'Максимальное количество =' AS ТЕХТ2,
MAX ( SP.QTY ) AS MXQTY
FROM P, SP
WHERE P.P# = SP.P#
AND ( P.COLOR = 'Red' OR P.COLOR = 'Blue' )
1 Так говорится в стандарте, хотя логичнее следовало бы сказать ‘‘самое большее одну груп-
пу”, поскольку групп может не быть совсем, если в результате вычисления предложений FROM и
WHERE получится пустая таблица.
Приложение А. Выражения языка SQL
1033
AND SP.QTY > 200
GROUP BY P.P#, P.WEIGHT, P.COLOR
HAVING SUM ( SP.QTY ) > 350 ;
Пояснения. Прежде всего необходимо отметить, что (как объяснялось в предыдущем
подразделе) предложения типа <выражение выборки> концептуально вычисляются в том
порядке, в котором пишутся, за исключением самого предложения SELECT, которое вы-
числяется последним. Поэтому можно считать, что результат нашего примера будет
формироваться следующим образом.
1. FROM. Вычислив предложение FROM, получим новую таблицу, которая является де-
картовым произведением таблиц Р и SP.
2. WHERE. Результат выполнения шага 1 преобразуется путем исключения всех строк, ко-
торые не удовлетворяют условию, указанному в предложении WHERE. В данном при-
мере это строки, которые не удовлетворяют следующему условному выражению.
P.P# = SP.P#
AND ( Р.COLOR = 'Red' OR P.COLOR = 'Blue' }
AND SP.QTY > 200
3. GROUP BY. Результат выполнения шага 2 группируется по значениям столбцов, ко-
торые указаны в предложении GROUP BY. В данном примере это столбцы Р.Р#,
Р.WEIGHT иР.COLOR.
Замечание. Теоретически здесь для группирования было бы достаточно одного
столбца Р.Р#, поскольку столбцы Р.WEIGHT и Р.COLOR имеют лишь одно значение
для каждого номера детали, т.е. они функционально зависимы от номера детали.
Однако язык SQL “не знает” об этом факте, и возникнет ошибка, если в предложе-
нии GROUP BY столбцы Р.WEIGHT и Р.COLOR будут опущены, поскольку они упомя-
нуты в предложении SELECT. (См. статью [10.6], где обсуждается этот вопрос.)
4. HAVING. Из результата выполнения шагаЗ исключаются группы, которые не удов-
летворяют заданному условному выражению.
SUM ( SP.QTY ) > 350
5. SELECT. Каждая образованная в результате выполнения шага 4 группа порождает
одну итоговую строку, причем следующим образом. Во-первых, из группы извле-
каются атрибуты “номер детали”, “вес”, “цвет” и “максимальное количество”. Во-
вторых, значение веса преобразуется в граммы по заданной формуле. В-третьих, в
соответствующие места в строке вставляются две символьные строки: 'Вес в
граммах =' и 'Максимальное количество ='. В отношении фразы “вставляются в
соответствующие места в строке” заметим, что мы полагаемся здесь на принятую в
языке SQL упорядоченность столбцов таблицы слева направо. Эти текстовые стро-
ки потеряют всякий смысл, если не будут помещены в “соответствующие места”.
Конечный результат будет подобен приведенному ниже.
P# ТЕХТ1 GMWT COLOR TEXT2 MXQTY
Р1 Вес в граммах = 5448 Red Макс, количество — 300
Р5 Вес в граммах = 5448 Blue Макс, количество = 400
РЗ Вес в граммах = 7718 Blue Макс, количество = 400
1034
Приложения
Не забывайте, что описанный выше алгоритм был приведен исключительно как кон-
цептуальное объяснение того, как в языке SQL должно вычисляться выражение типа
<выражение выборки>. Этот алгоритм, безусловно, корректен, в том смысле, что он га-
рантирует получение правильного результата. Однако буквальное следование данному
алгоритму при его реализации было бы неэффективным. Например, необходимо считать
очень неудачным решением реальное вычисление в системе декартова произведения
таблиц на шаге 1. Именно соображения, подобные приведенному, послужили причиной
появления в реляционных системах оптимизаторов, обсуждавшихся в главе 17. Фактиче-
ски основная задача оптимизатора в SQL-системе заключается в том, чтобы найти такую
процедуру реализации, которая давала бы тот же результат, что и концептуальный алго-
ритм, кратко описанный выше, но была бы эффективнее его.
А.З. Условные выражения
Подобно выражениям типа <табличное выражением выражения типа <условное
выражение> используются в различных контекстах языка SQL, в частности в предложе-
нии WHERE при определении требуемых или исключаемых строк для последующей обра-
ботки2. В этом разделе будут рассмотрены некоторые наиболее важные особенности
данного типа выражений. Заметим, однако, что здесь, разумеется, не ставилась задача
исчерпывающе осветить этот вопрос. В частности, не рассмотрены особенности обра-
ботки NULL-значений. Как указывалось в главе 18, если учитывать наличие NULL-
значений, то для выражений типа <условное выражение^ потребуется существенно более
расширенное толкование. Некоторые форматы условного выражения, которые не приво-
дятся в этом приложении, относятся исключительно к аспектам, связанным с поддерж-
кой NULL-значений. Однако данные аспекты обсуждались в главе 18.
Как и в предыдущем разделе, начнем с BNF-грамматики. Затем перейдем к обсужде-
нию некоторых специфических случаев, а именно— параметров <условие like>,
<условие match>, <условие all или апу> и <условие unique>, которые будут рассмот-
рены более подробно (все другие случаи или обсуждались ранее в этой книге, или на-
столько просты и понятны, что не требуют разъяснений).
<условное выражение>
::= <терм условия?
| <условное выражение> OR <терм условия?
<терм условия*
::= <фактор условия*
| <терм условия? AND <фактор условия?
<фактор условия?
::= [ NOT ] <первичное условие>
I
<первичное условие>
::= <простое условие> | (<условное выражение> )
2 Напомним, что, как указывалось в главе 8, условные выражения представляют в языке SQL
аналог того, что в книге мы называли булевыми или логическими выражениями.
Приложение А. Выражения языка SQL
1035
«простое условие>
::= «условие сравнения?
«условие in>
«условие Пке>
«условие match>
«условие all или алу>
<условие exists>
<условие unique>
<условие сравнения
::= «конструктор строки>
«оператор сравнения? «конструктор строкЯ?
<оператор сравнения?
•••= = I < I <= I > I >= I <>
<условие in>
::= «конструктор строкЯ? [ NOT ] IN («табличное выражение> )
| <скалярное выражение> [ NOT ] IN
(<список скалярных выражения? )
«условие like>
:: = «выражение из символьных строк? [ NOT ] LIKE <шаблон>
[ ESCAPE «исключения? ]
«условие match>
::= «конструктор строкЯ? MATCH UNIQUE («табличное выражение> )
«условие all или апу>
::= «конструктор строкЯ?
«оператор сравнения? ALL (<табличное выражение> )
| «конструктор строкЯ?
«оператор сравнения? kWL («табличное выражение> )
«условие exists>
::= EXISTS (<табличное выражение> )
«условие unique>
::= UNIQUE («табличное выражение> )
Условие LIKE
Условия LIKE предназначены для простой проверки соответствия символьных строк
заданному шаблону. Еще раз приведем синтаксис этого условия.
«выражение из символьных строк? [ NOT ] LIKE «шаблоя?
[ ESCAPE «исключение> ]
1036
Приложения
Здесь параметр <шаблон> представляет собой произвольное выражение наподобие
символьной строки, а параметр <исключениё> (если указана фраза ESCAPE) — выражение
наподобие символьной строки, которое в результате вычисления дает единственный
символ. Рассмотрим пример.
SELECT Р.Р#, Р.PNAME
FROM Р
WHERE Р.PNAME LIKE 'С%';
Это сформулированный на языке SQL запрос “Определить номера и наименования
деталей, назвавания которых начинаются с буквы С”. Результат выполнения запроса
представлен ниже.
P# PNAME
Р5 Cam
Р6 Cog
Поскольку предложение ESCAPE не указано, символы в параметре <ma6notf> интерпре-
тируются так.
Символ подчеркивания задается для любого отдельного символа.
Символ процента “%” устанавливается для любой последовательности из п симво-
лов, где п может быть равно нулю.
Все остальные символы представляют сами себя.
В данном примере по запросу будут возвращены строки из таблицы Р, для которых
значение в столбце PNAME начинается с большой буквы “С”, за которой следует произ-
вольная последовательность символов (в количестве, большем либо равном нулю).
Приведем еще несколько примеров.
ADDRESS LIKE '%Berkley' S# LIKE 'S_' Дает результат истина, если в любом месте значения в столб- це ADDRESS содержится строка “Berkley” Дает результат истина, если значение в столбце S# состоит ровно из трех символов и первый символ — “S”
PNAME LIKE '%C ' Дает результат истина, если значение в столбце PNAME состоит из четырех или более символов и последним трем предшест- вует символ “С”
MYTEXT LIKE ESCAPE ' = ' Дает результат истина, если значение в столбце MYTEXT начи- нается с символа подчеркивания (см. ниже)
В последнем примере символ “=” указан как символ исключения, означающий, что
специальное назначение для символов “%” и может быть отменено, если им будет
предшествовать символ
И наконец отметим, что в предложении LIKE <условие like> условие вида
х NOT LIKE у [ ESCAPE Z ]
определяется как равносильное следующему.
NOT ( х LIKE у [ ESCAPE Z ] )
Приложение А. Выражения языка SQL
1037
Условие MATCH
Параметр <условие match> имеет следующий формат.
<конструктор строке* MATCH UNIQUE (<табличное выражений )
Пусть rl — строка, которая получается в результате вычисления значения параметра
<конструктор строки>, и пусть Т— таблица, которая получается в результате вычисле-
ния выражения в параметре <таблкчное выражением Тогда условие, определенное пара-
метром <условие match>, будет истинным, если и только если таблица Тсодержит ровно
одну строку (скажем, г2), такую, что операция сравнения
rl = г2
дает для нее результат истина. Приведем пример.
SELECT SP.*
FROM SP
WHERE NOT ( SP.S# MATCH UNIQUE ( SELECT S.S# FROM S ) ) ;
Это сформулированный на языке SQL запрос “Найти поставки, которые выполнятся
более чем одним поставщиком из таблицы поставщиков”. Он может быть полезен при
проверке целостности базы данных, поскольку, если база данных корректна, таких по-
ставок, безусловно, не должно быть. Отметим, что для выполнения этой же проверки
могло бы использоваться условие принадлежности (вхождения) <условие in>.
Кроме того, в фразе MATCH UNIQUE ключевое слово UNIQUE может быть опущено, но
тогда фраза MATCH превратится в синоним фразы IN (по крайней мере, если не учитывать
NULL-значения).
Условие ALL или ANY
Параметр <условие all или апу> имеет следующий общий синтаксис.
<конструктор строке* <оператор сравнение* <квалификатор>
(<табличное выражениё> )
Здесь параметр <оператор сравнение* представляет любой оператор из обычного
набора операторов сравнения (=, о и т.д.), а уточнение <квалификатор> может иметь
значение ALL или ANY. В общем случае параметр <условие all или апу> принимает зна-
чение истина, если и только если результат соответствующего сравнения при значении
квалификатора ALL (либо ANY) является истиной для всех (соответственно для каких-
нибудь) строк в таблице, определяемой значением параметра Табличное выражением
(Если таблица пуста, то условие ALL всегда дает значение истина, а условие ANY — зна-
чение ложь). Приведем пример: “Определить наименования деталей, вес которых боль-
ше, чем вес любой из голубых деталей”.
SELECT DISTINCT РХ.PNAME
FROM Р AS РХ
WHERE PX.WEIGTH > ALL ( SELECT PY.WEIGTH
FROM
WHERE
P AS PY
PY.COLOR = 'Blue' ) ;
1038
Приложения
Для данных нашего обычного примера результат будет таким.
PNAME
Cog
Пояснения. Вложенный параметр <табличное выражение> возвращает множество
значений веса голубых деталей. Внешнее предложение SELECT возвращает наименования
тех деталей, вес которых больше любого значения веса из указанного множества. В об-
щем случае в конечном результате, безусловно, может содержаться любое количество
наименований деталей (в том числе и нулевое).
Замечание. Здесь уместно предупредить читателя, что при использовании параметра
<условие all или апу> неискушенные пользователи часто делают ошибки. В формули-
ровке предыдущего запроса на языке SQL было бы естественнее использовать ключевое
слово “любой” (ANY) вместо “каждый” (ALL), что привело бы к (неверному) использова-
нию сравнения > ANY вместо > ALL. Аналогичные замечания справедливы и для всех ос-
тальных операторов сравнения с квалификаторами ANY и ALL.
Условие UNIQUE
Параметр <условие unique> используется для проверки, является ли каждая строка
некоторой таблицы уникальной (т.е. не имеет ли дубликатов). Синтаксис этого условия
следующий.
UNIQUE ( «^табличное выражение> )
Условие принимает значение истина, если в результате вычисления выражения, за-
данного параметром <табличное выражение>, получается таблица, в которой все строки
различны, и ложь — в противном случае.
А.4. Скалярные выражения
В языке SQL допустимые значения параметра <скалярное выражение> образуют
достаточно типичный набор и вполне самоочевидны. Здесь мы ограничимся переч-
нем наиболее важных операторов, которые могут быть использованы в конструкци-
ях таких выражений, и дадим лишь несколько комментариев для операторов CASE и
CAST, смысл которых, возможно, не совсем очевиден. Список операторов в алфавит-
ном порядке выглядит так.
Арифметические операторы ( + , -,
BIT_LENGTH
CASE
CAST
CARACTER_LENGTH
Операция конкатенации (| |)
CURRENT_USER
LOWER
*, /) OCTET_LENGTH
POSITION
SESSION_USER
SUBSTRING
SYSTEM_USER
TRIM
UPPER
USER
Приложение А. Выражения языка SQL
1039
Отметим, что обращение к оператору обобщения также может использоваться внутри
значения параметра <скалярное выражение^ поскольку такой оператор всегда возвра-
щает скалярное значение. Более того, результат вычисления выражения, заданного пара-
метром <табличное выражений и заключенного в круглые скобки, также может считать-
ся скалярным значением, поскольку в результате вычисления получается таблица ровно с
одной строкой и одним столбцом.
Теперь рассмотрим операторы CASE и CAST.
Оператор CASE
Оператор CASE возвращают одно значение из указанного множества значений в зави-
симости от заданного условия, как, например, показано ниже.
CASE
WHEN S.STATUS < 5 THEN 'Обращаться в крайнем случае
WHEN S.STATUS < 10 THEN 'Сомнительный'
WHEN S.STATUS < 15 THEN 'Не очень хороший'
WHEN S.STATUS < 20 THEN 'Посредственный'
WHEN S.STATUS < 25 THEN 'Приемлемый'
ELSE 'Отличный'
END
Оператор CAST
Оператор CAST преобразует заданное скалярное значение в указанный скалярный тип
данного, как, например, показано ниже.
CAST ( Р.WEIGHT AS FLOAT )
Не все пары типов данных взаимно преобразуемы. Например, не поддерживаются пре-
образования между числами и битовыми строками. (См. публикацию [4.22], где подробно и
точно описано, какие типы данных могут быть преобразованы и в какие именно типы.)
1040
Приложения
Приложение
Обзор языка SQL3
Б.1. Введение
Язык SQL3, возможно, будет утвержден как стандарт (SQL/99) приблизительно в то
время, когда будет напечатана эта книга. Однако мы не стали ранее при его обсуждении
основываться на версии SQL3 по причинам, которые указывались в главе 4, а также по-
тому, что рассматриваем язык SQL3, мягко говоря, как какое-то недоразумение, как бы
его ни защищали. С другой стороны, мы сочли необходимым включить в эту книгу обзор
по крайней мере наиболее важных особенностей языка SQL3.
В языке SQL3, конечно, имеются все функциональные возможности, предусмотрен-
ные стандартом SQL/92, за исключением некоторых второстепенных (ни одна из них в
книге не рассматривалась), которые были исключены сознательно. К ним относятся:
ключевое слово SQLCODE, целые без знака вместо имен столбцов в предложении ORDER
BY, “представители” идентификаторов, некоторые множества символов, определяемые
пользователем, а также сопоставления, преобразования и несколько других возможно-
стей. Но по вполне понятным причинам основное внимание здесь будет уделено тем
возможностям, которые были добавлены после 1992 года, и для удобства обсуждения
под “языком SQL3” далее мы будем подразумевать именно эти возможности. Из них, не-
сомненно, наиболее важными являются возможности, которые связаны с типами данных,
определяемыми пользователем (мы рассмотрим их в разделах Б.2-Б.5). Самые важные из
других возможностей будут представлены в разделе Б.6.
Замечание. Подробный анализ и критику по теме разделов Б.2-Б.5 можно найти в [3.3].
Прежде чем перейти к обсуждению непосредственно языка SQL3, необходимо ска-
зать несколько слов о SQLJ [4.6]. Так неформально называют проект, в котором учиты-
вается возможность определенной степени интеграции между языками SQL и Java (этот
проект создается объединенными усилиями нескольких известных поставщиков СУБД).
Часть 0 этого проекта связана с внедрением операторов языка SQL в программы на язы-
ке Java. В части 1 исследуется идея обращения к программам на языке Java из среды SQL
(например, вызов хранимых процедур, которые написаны на языке Java). А в части 2 ре-
шается задача использования классов Java как типов данных языка SQL (например, в ка-
честве основы для определения столбцов в SQL-таблицах). Ни один из этих замыслов
формально не стал частью языка SQL3 как такового, но часть 0 проекта SQLJ уже была
опубликована в виде первого компонента новой части 10 чернового варианта стандарта
языка SQL [4.22] и, по-видимому, вскоре последуют части 1 и 2 проекта SQLJ
(возможно, ко времени формального опубликования описания языка SQL3).
Также вероятно, что приблизительно в то же время появится новая версия интерфей-
са SQL/CLI (см. главу 4).
Необходимо сделать несколько редакционных замечаний. Во-первых, в примерах
книги и, в частности, этого приложения часто используется символ в наименова-
ниях столбцов, хотя на самом деле в языке SQL3 это не допускается. Также использу-
Приложение Б. Обзор языка SQL3
1041
ется точка с запятой как символ завершения оператора. Во-вторых, необходимо
подчеркнуть, что последующее изложение вопросов далеко не полное. И наконец, без-
условно, в порядке вещей, что некоторые детали ко времени утверждения стандарта
SQL3 могут измениться.
Б.2. Новые типы данных
Как указывалось в предыдущем разделе, все наиболее очевидные аспекты новизны в
языке SQL3 связаны с типами данных* 1. Появились новые встроенные типы данных,
точнее — новые встроенные скалярные типы данных, а также новые генераторы типов,
которые в языке SQL3 называются конструкторами типа. Оператор CREATE TYPE по-
зволяет пользователям определять собственные типы (конечно, имеется и соответст-
вующий оператор DROP TYPE). Рассмотрим все эти возможности по порядку.
Встроенные скалярнще типы данных
В языке SQL3 поддерживаются три новых скалярных типа данных.
BOOLEAN. Тип BOOLEAN — это, конечно, тип логических значений. Поддерживаются
обычные логические операторы (NOT, AND, OR), а логические выражения могут ис-
пользоваться, грубо говоря, везде, где обычно используются скалярные выраже-
ния. Однако отметим, что в языке SQL предполагается три логических значения, а
не два, как уже указывалось в главе 18. Этим значениям соответствуют литералы
TRUE, FALSE и UNKNOWN. Тем не менее тип BOOLEAN включает только два значения, а
не три. Неизвестное (UNKNOWN) логическое значение представлено — совершенно
неправильно! — NULL-значением. Например, присвоение значения UNKNOWN пере-
менной типа BOOLEAN на самом деле приведет к установке ее значения равным
NULL. Чтобы понять, насколько это серьезная ошибка, можно поразмышлять об
аналоге числового типа, который для представления нуля использовал бы NULL-
значение вместо числа нуль.
Еще одна экстравагантность заключается в том, что в языке SQL3 (удивительно!) про-
стая ссылка на логическую переменную не считается экземпляром того, что в прило-
жении А называлось параметром <первичное условиё>. Таким образом, например, ес-
ли переменная В относится к типу BOOLEAN, то предложение WHERE В недопустимо!
Наряду с типом BOOLEAN в языке SQL3 вводятся два новых оператора обобщения,
EVERY (Каждый) — а не ALL (Все) по какой-то причине — и ANY (Любой). В обоих
случаях ар1умент представляет столбец значений типа BOOLEAN (почти наверняка
производный столбец, как, например, в предложении WHERE ANY(QTY > 200)). Если
столбец пустой, оба оператора возвращают значение неизвестно (или, правильнее,
NULL-значение')1. Если столбец не пустой, то оператор EVERY возвращает значение
истина, если каждое значение в столбце — истина, и значение ложь в противном
1 Все же добавим, что одним из наиболее неочевидных аспектов являются “домены ” в стиле
языка SQL (см. главы 4 и 5), которые, по-видимому, были тихо забыты.
1 Сравните в этом отношении свойства условий ALL или ANY (см. приложение А).
1042
Приложения
случае; а оператор ANY возвращает значение ложь, если каждое значение в столб-
це — ложь, и значение истина в противном случае. Как и для других операторов
обобщения, NULL-значения перед выполнением операции исключаются.
CLOB (“большой символьный объект”). Этот тип представляет собой символьную
строку переменной длины, по существу, неограниченного размера. Сопутствую-
щий механизм локатора аналогичен (до некоторой степени) привычному меха-
низму курсора и позволяет иметь доступ к отдельным частям таких строк. Многие
операторы обычных символьных строк не поддерживают подобные строки. Среди
тех, которые все-таки поддерживают, — “=” и LIKE.
BLOB (“большой двоичный объект”). Этот тип аналогичен предыдущему, но стро-
ки являются строками “октетов”, т.е., по сути, байтов, а не символов.
Генерируемые типы
В языке SQL3 имеются следующие генераторы типов: REF, ARRAY и ROW. Однако един-
ственный способ определить “тип REF” — неявный, представляющий собой побочный
эффект определения “структурированного типа” с помощью оператора CREATE TYPE
(читайте далее этот раздел). Поэтому мы пока не будем его рассматривать. Что касается
генераторов типов ARRAY и ROW, то они, по существу, вообще не могут быть определены
как таковые (поскольку не существует специальных операторов CREATE ARRAY TYPE и
CREATE ROW TYPE). Они могут использоваться только путем обращения к соответствую-
щему генератору типа, “подключенному”, например, к оператору CREATE TABLE. Приве-
дем пример, в котором показано, как используется тип ARRAY.
CREATE TABLE SALES
( ITEM# CHAR(5),
QTY INTEGER ARRAY [12],
PRIMARY KEY ( ITEM# ) ) ;
Здесь столбец QTY представляет значения-массивы, причем каждое значение QTY яв-
ляется массивом из 12 элементов, каждый из которых имеет тип INTEGER.
Замечание. Массивы языка SQL ограничиваются одним измерением, и его элементы
не могут быть, в свою очередь, массивами.
Ниже приведен пример запроса к определенной выше таблице SALES.
SELECT ITEM#
FROM SALES
WHERE QTY [3] > 100 ;
(Смысловое значение запроса — “Получить номера товаров, которые были проданы в
марте в количестве, превышающем 100 единиц”.) Далее следует пример вставки строки.
INSERT INTO SALES ( ITEM#, QTY )
VALUES ( 'X4320',
ARRAY [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
(Обратите внимание на использование литерала массива.)
Приложение Б. Обзор языка SQL3
1043
Типы ROW аналогичны, как, например, показано ниже.
CREATE TABLE CUST
( CUST # CHAR(3),
ADDR ROW ( STREET CHAR(50),
CITY CHAR(25),
STATE CHAR(2),
ZIP CHAR(5) )
PRIMARY KEY ( CUST# ) ) ;
Пример запроса выглядит следующим образом.
SELECT CUST#
FROM CUST
WHERE ADDR.STATE = 'CA' ;
Далее приведен пример вставки строки.
INSERT INTO CUST ( CUST#, ADDR )
VALUES ( '001', ROW ( '1600 Pennsylvania Ave.',
'Washington', 'DC', '20500' ) ) ;
Типы DISTINCT
С помощью нового оператора CREATE TYPE создается тип, определяемый пользова-
телем. К нему относится или тип DISTINCT, или структурированный тип (отметим, кста-
ти, что генерируемые типы — см. предыдущий раздел — не считаются “типами, опреде-
ляемыми пользователями”, в том же смысле). В данном подразделе будет рассматри-
ваться только тип DISTINCT. Название типа DISTINCT, переводимое как “отдельный”,
здесь пишется прописными буквами, чтобы подчеркнуть, что это слово используется не
в его обычном смысле. Тип DISTINCT ограничивается специальным случаем типа, опре-
деляемого пользователем. В частности, его физическая реализация должна включать
ровно один из встроенных скалярных типов. Ниже приводится синтаксис для определе-
ния типа DISTINCT.
CREATE TYPE <имя типа>
AS <имя встроенного скалярного типа> FINAL
[ <режим приведения> ]
[ <список спецификаций методов> ] ;
Пример определения подобного пользовательского типа приведен ниже.
CREATE TYPE WEIGHT AS NUMERIC (5,1) FINAL ;
Пояснения
1. Тип WEIGHT наследует операторы сравнения, которые применяются к основному
типу, т.е. к типу NUMERIC. Однако отметим, что значения типа WEIGHT сравнимы с
другими его значениями и больше с никакими. Таким образом, если WT — SQL-
переменная типа WEIGHT, следующее сравнение недопустимо.
WT > 14.7
1044
Приложения
Однако, если в параметре <режим приведения* указаны соответствующие опции приве-
дения (детали здесь не уточняются), следующие сравнения уже будут допустимыми.
WT > CAST ( 14.7 AS WEIGHT )
CAST ( WT AS NUMERIC ) > 14.7
Более того, два предыдущих обращения к преобразованию CAST могут быть приве-
дены к виду WEIGHT(14.7) и NUMERIC(WT) соответственно.
Замечание. Имена функций WEIGHT и NUMERIC здесь указываются определителем
типа (в параметре <режим приведения*). Они не подразумеваются именем типа, ко-
торый был определен, или именем их основного типа.
2. Аналогичные замечания применимы и к операции присвоения, т.е. значение типа
WEIGHT может быть присвоено только результату типа WEIGHT и никакому другому.
3. Тип WEIGHT автоматически не наследует другие операторы от основного типа. Од-
нако определение метода в параметре Спецификация метода> (ни один пример не
приведен) позволяет определяющему тип пользователю определить “методы”
(см. следующий подраздел), которые применимы к значениям и переменным типа
WEIGHT. Можно, например, определить функцию ADDW, которая складывает два веса,
получая третий. Поэтому пользователь может написать такие выражения.
ADDW ( WT1, WT2 )
ADDW ( WT1, WEIGHT ( 14.7 ) )
4. В определении типа должна присутствовать спецификация FINAL (см. следующий
подраздел).
Структурированные типы
Еще один вид типа, определяемого пользователем, — структурированный тип.
Ниже представлены два примера3.
CREATE TYPE POINT AS ( X FLOAT, Y FLOAT ) FINAL ;
CREATE TYPE LINESEG AS ( BEGIN POINT, END POINT ) FINAL ;
Пояснения
1. Говорят, что тип POINT имеет атрибуты X и Y (не путайте с атрибутами кортежей и от-
ношений, которые определялись в части II этой книги). Аналогично тип LINESEG также
имеет атрибуты BEGIN и END. Атрибут может относиться к любому известному типу.
2. К сожалению, атрибуты, которые указаны в определении структурированного типа,
представляют физическую реализацию его значений, а не “возможное представле-
ние” в смысле главы 5. Поэтому, например, точки BEGIN POINT и END POINT будут
физически реализованы в терминах их декартовых координат.
3. Определение каждого атрибута автоматически приводит к определению одного
оператора считывания — наблюдателя (проще говоря, оператора “get” —
“получить”) и одного оператора изменения —мутатора (проще говоря, оператора
3 На самом деле второй пример неверный, поскольку BEGIN и END— это зарезервированные слова.
Приложение Б. Обзор языка SQL3
1045
“set” — “установить”), для которых используется синтаксис уточнения с помощью
точки4. Пусть, например, Z, Р и LS— SQL-переменные типов FLOAT, POINT и
LINESEG соответственно. Тогда допустимы следующие выражения.
Р.Х /* Получить значение компонента X точки р */
LS.BEGIN.X /* Получить значение компонента X /* точки BEGIN сегмента линии LS */ */
SET Р.Х = Z ; /* Установить значение Z для */
/* компонента X точки Р */
SET LS.BEGIN.X = Z ; ; /* Установить значение Z для */
/* компонента X точки BEGIN */
/* сегмента линии LS */
4. Поскольку какие-либо дополнительные операторы не были определены, из других
операторов для этих типов допустимы лишь операторы сравнения на равенство и
операторы присвоения, которые допустимы для всякого типа. В частности, отме-
тим, что “операторы-селекторы” типов POINT и LINESEG (в смысле главы 5) не оп-
ределяются автоматически, поэтому нет и литералов типов POINT и LINESEG.
5. Уточнение FINAL означает, что любая попытка определить другой тип как собст-
венный подтип любого из этих типов приведет к ошибке (см. раздел Б.З). Иначе го-
воря, оба эти типа — листовые и будут такими оставаться всегда.
6. Являются ли типы POINT и LINESEG (или структурированные типы вообще)
“инкапсулированными”? К сожалению, ответ на этот вопрос зависит от контекста.
Например, если структурированный тип используется как тип некоторого столбца,
ответ будет “Да” (пожалуй). Однако, если он используется как тип некоторой таб-
лицы (см. раздел Б.4), конечно, ответ будет “Нет ”.
Замечание. В первом случае добавление “пожалуй” означает, что даже в этой ситуа-
ции операторы “получить” (“get”) и “установить” (“set”), по существу, предоставляют
атрибуты данного типа (как уже указывалось) и не могут быть замещены. Возможно,
для первого случая уместно использовать термин “псевдоинкапсулированные типы”
или псевдоскаляры.
Приведем общий синтаксис для определения структурированного типа, который не
является каким-либо подтипом (см. раздел Б.З, где рассматривается случай определения
подтипов).
CREATE TYPE <имя типа>
AS ( <список определений атрибутов> )
[ реализация ссылочного типа> ]
[ [ NOT ] INSTANTIABLE ]
[ NOT ] FINAL
[ <список спецификаций методов> ] ;
4 Следует отметить, что этот “мутатор" не является настоящим мутатором в смысле
главы 5, т.е. типичным оператором обновления, поскольку по определению он возвращает значе-
ние. Обсуждение последствий (неприятных) этого факта, к сожалению, выходит за рамки дан-
ного короткого приложения. (См. [3.3], где этот вопрос обсуждается подробно.)
1046
Приложения
Пояснения
1. Параметр <список определений атрибутов> не должен быть пустым.
2. Необязательный параметр реализация ссылочного типа> подробно обсуждается
в разделе Б.4.
3. Уточнение NOT INSTANTIABLE означает, что тип является фиктивным типом в
смысле главы 19. По умолчанию заданным считается уточнение INSTANTIABLE.
4. Уточнение NOT FINAL означает, что тип может иметь собственные подтипы; в про-
тивном случае используется уточнение FINAL.
5. К значениям и переменным данного структурированного типа Т применяются сле-
дующие операторы.
а) Наблюдатели и мутаторы атрибутов, уже описанные выше.
б) Операторы присвоения “=” и, возможно, сравнения “<” (оба оператора опреде-
ляются с помощью отдельного оператора CREATE ORDERING FOR Т, хотя зачем
требуется упорядочение, если нужно просто определить оператор присвоения
“=”, не совсем понятно).
в) Процедуры и функции, которые определяются, чтобы получить параметр типа Т
(или любой из его собственных подтипов; см. раздел Б.З).
г) Методы, которые определяются, чтобы получить специальный “целевой” пара-
метр типа Тили любой из его собственных подтипов (опять же, см. раздел Б.З).
Замечание. Здесь под методами подразумеваются методы в традиционном объект-
ном смысле (см. главу 24), т.е. они являются операторами, которые рассматривают
один параметр как специальный. Если метод М определен для типа Т и X— выра-
жение типа Т, то специальный синтаксис точечного уточнения Х.М используется
для вызова метода М для объекта X. (Здесь для простоты подразумевается, что ме-
тод М никаких других параметров не имеет.)
В параметре Спецификация метода> задаются “определения сигнатур” метода в
смысле глав 19 и 24. Однако они также включают многое другое, что относится к реали-
зации и, по мнению автора, здесь неуместно. Реальный код, реализующий методы, опре-
деляется в другом месте.
Б.З. Наследование типов
В языке SQL3 поддержка наследования типов не полностью ортогональна, поскольку
применяется только к структурированным типам, т.е. не поддерживается наследование
типов для типов встроенных, генерируемых5 и типов DISTINCT. Кроме того, совсем не
поддерживается множественное наследование типов. В этом разделе будет рассмотрено
только наследование для “псевдоскалярных” структурированных типов, которое может
считаться реализованным более или менее удовлетворительно. Обсуждение наследова-
ния неинкапсулированных структурированных типов откладывается до раздела Б.5.
5 За исключением, может быть, строчных типов. Однако существуют некоторые проблемы,
связанные с наследованием строчных типов, которые здесь не освещаются, поскольку это выхо-
дит за рамки данного приложения.
Приложение Б. Обзор языка SQL3
1047
Перечислим самые существенные различия между моделью наследования типов,
которая была представлена в главе 19, и наследованием “псевдоскалярных” типов в
языке SQL3.
В языке SQL3 поддерживаются структурное наследование, а также наследование
поведения.
В языке SQL3 неверно различаются значения и переменные, и поэтому, в частно-
сти, не различаются заменимость значений и заменимость переменных.
В языке SQL3 нет поддержки ограничений типа, и поэтому также нет поддержки
специализации посредством ограничения.
В языке SQL3 требуется, чтобы операторы обновления (“мутаторы”) наследова-
лись безусловно.
Вследствие этих различий в языке SQL3 допускаются “некруглые окружности” и дру-
гие несуразности, которые обсуждались в главе 19. Кроме того, некоторые операции
сравнения в языке SQI .3 в результате дают значение ложь, когда они должны бы давать
значение истина (поскольку, например, значение менее конкретного типа ELLIPSE может
иметь равные полуоси и, значит, соответствовать окружности в обычном понимании).
Ниже приводятся примеры описания типов эллипсов и окружностей на языке SQL3.
CREATE TYPE ELLIPSE
AS ( A LENGTH, В LENGTH, CTR POINT )
NOT FINAL ;
CREATE TYPE CIRCLE UNDER ELLIPSE
AS ( R LENGTH ) - нереалистично! (см. ниже)
NOT FINAL ;
Однако отметим, что в этих определениях физической реализации типа CIRCLE исполь-
зуются четыре компонента— А, В и CTR (наследуемые от типа ELLIPSE) и R (указываемый
только для типа CIRCLE). Для любой данной окружности, конечно, три из этих компонентов
будут иметь одинаковые значения. В качестве альтернативы вместо атрибута R можно оп-
ределить метод R для типа CIRCLE. Тогда тип CIRCLE будет иметь ту же физическую реали-
зацию, что и тип ELLIPSE, и эта реализация будет менее избыточна. С другой стороны, если
С— переменная объявленного типа CIRCLE, присвоение C.R будет допустимо в первом из
этих проектов, но не допустимо во втором. И опять же, присвоение C.R, если оно поддер-
живается, будет, вообще говоря, давать такую “окружность”, что C.R Ф С.А!
Ниже перечислены некоторые особенности в различии между моделью наследования
типов, описанной в главе 19, и наследованием, которое поддерживается в языке SQL3.
В языке SQL3 используется термин “direct” в понятии direct subtype для обозначе-
ния прямого непосредственного подтипа вместо более соответствующего случаю
термина “immediate”.
В языке SQL3 вместо термина “корневой тип” используется термин “максимальный
супертип”.
В языке SQL3 поддерживается оператор TREAT (аналог оператора TREAT DOWN).
Например, в этом языке аналогом выражения TREAT_DOWN_AS_CIRCLE(E) будет
выражение TREAT Е AS CIRCLE.
1048
Приложения
В языке SQL3 также имеется оператор, который можно рассматривать как опера-
тор TREAT UP, Приведем, например, следующую формулировку оператора.
AREA ( С AS ELLIPSE )
Уточнение AS ELLIPSE обеспечивает вызов версии ELLIPSE для оператора AREA,
даже если объявленный тип переменной С будет CIRCLE.
Замечание. Этот оператор может использоваться лишь в определенном контексте,
' а именно — для операции TREAT UP по отношению к аргументу при вызове неко-
торого оператора, определенного пользователем, как в данном примере. Нужно
сказать, что обеспечение такой функциональности, похоже, приводит к некоторой
путанице между вопросами модели и реализации, ведь пользователи не должны
даже знать, что существуют две версии оператора AREA.
В языке SQL3 также поддерживается метод вида X. SPECIFICTYPE, который воз-
вращает наиболее конкретный тип своего аргумента X как символьную строку.
В языке SQL3 аналоги операторов вида IS_T(X) и IS_MS_T(X) выглядят следую-
щим образом.
X IS OF ( Т )
X IS OF ( ONLY T )
Б.4. Ссылочные типы
Напомним, что, как утверждалось в главе 24, в объектных системах есть лишь одна
хорошая идея, а именно — надлежащая поддержка типов данных (или две идеи, если
считать наследование типа отдельно). Как видим, в язык SQL3 включены некоторые из
этих “хороших” функциональных возможностей, хотя их поддержке еще далеко до со-
вершенства. Однако, к сожалению, в язык SQL3 включены и связанные с ними возмож-
ности, которые, по нашему убеждению, очень плохие. Фактически язык SQL3 довольно
близко подошел к возможности допустить и первую грубейшую ошибку (приравнивание
таблиц и классов), и вторую грубейшую ошибку (смешивание указателей и таблиц). Так-
же необходимо сказать, что “оправдания” для выбора такого подхода не совсем понятны,
по крайней мере автору; в сущности, они представляют собой лишь некую неясную идею
о том, что рассматриваемые возможности каким-то образом делают язык SQL3 более
“объектно-подобным”.
Но как бы то ни было, мы все же попытаемся объяснить, что на самом деле представ-
ляют собой соответствующие возможности. В языке SQL3 разрешено определять базо-
вую таблицу не только в терминах явного множества именованных типизированных
столбцов (обычным способом), но и в терминах структурированных типов, определяе-
мых пользователем, как, например, показано ниже.
CREATE TYPE DEPT_TYPE
AS ( DEPT# CHAR(3),
DNAME CHAR(25),
BUDGET MONEY )
REF IS SYSTEM GENERATED... ;
Приложение Б. Обзор языка SQL3
1049
CREATE TABLE DEPT OF DEPT_TYPE
( REF IS DEPT_ID SYSTEM GENERATED,
PRIMARY KEY ( DEPT# ),
UNIQUE ( DEPT_ID ) )... ;
Пояснения
1. Для данного определения структурированного типа Т система автоматически гене-
рирует связанный ссылочный тип (“REF-тип”), обозначаемый как REF( Г). Значения
типа REF( Т) представляют собой “ссылки” на строки типа Т в базовой таблице6, ко-
торая определена как таблица, “относящаяся к” (“OF”) типу Т(см. п. 3).
Замечание. Тип Т, конечно, может быть использован и в другом контексте, напри-
мер как объявленный тип для некоторой переменной V или некоторого столбца С.
Однако никакие значения REF( Т) не связаны с другими такими его применениями.
2. Предложение REF IS SYSTEM GENERATED в операторе CREATE TYPE означает, что ре-
альные значения связанного REF-типа предоставляются системой. Может исполь-
зоваться и другая опция REF IS USER GENERATED, но здесь она рассматриваться не
будет. Опция REF IS SYSTEM GENERATED применяется по умолчанию.
3. Базовая таблица может быть определена (с помощью оператора CREATE TABLE) как
таблица, “относящаяся к” некоторому структурированному типу. Однако ключевое
слово OF здесь не совсем подходит, поскольку ни таблица в целом, ни даже отдель-
ные ее строки на самом деле не “относятся к” рассматриваемому типу7. В частно-
сти, для таблицы могут быть определены дополнительные столбцы вдобавок к
“столбцам” (или, скорее, к атрибутам) самого структурированного типа. Фактиче-
ски должен быть указан по крайней мере один дополнительный столбец, а имен-
но— столбец подходящего REF-типа. Синтаксис для определения такого столб-
ца— это не обычный синтаксис для определения столбца, который выглядит так.
REF IS <имя столбца> SYSTEM GENERATED
Дополнительный столбец используется для размещения уникальных идентифика-
торов (“ссылок”) для строк данной базовой таблицы (подразумевается уточнение
UNIQUE (<имя столбца>), хотя оно может указываться и явно, как в нашем приме-
ре). Идентификатор присваивается для данной строки, когда она вставляется, и ос-
тается связанным с этой строкой8, пока она не будет удалена.
Замечание. Повторение уточнения SYSTEM GENERATED, конечно, необходимо.
(Возможно, это покажется странным, но генерируемый системой столбец может
быть целевым столбцом в операциях INSERT и UPDATE, хотя и используется по особым
6 Или, возможно, в некотором представлении. Использование представления в этом прило-
жении не рассматривается.
7 В частности, отметим, что если объявленным типом некоторого параметра Р для неко-
торого оператора Ор является некоторый структурированный тип Т, то строка базовой таб-
лицы, которая была определена как таблица, "относящаяся к" типу Т, не может передаваться
как соответствующий аргумент при вызове оператора Ор.
8 Здесь присутствует некоторый порочный круг: "такая строка" может означать лишь
"строку, которая имеет конкретный идентификатор ”. Обратите внимание на смешивание зна-
чения и переменной!
1050
Приложения
соображениям. Подробности здесь не рассматриваются.) Но непонятно, почему тре-
буется определять таблицу как “относящуюся к” некоторому структурированному
типу вместо того, чтобы просто определить соответствующий столбец обычным спо-
собом и обеспечить функциональные возможности “уникального идентификатора”.
4. Как отмечалось в разделе Б.2, структурированный тип, например DEPT_TYPE, не
рассматривается в качестве инкапсулированного, если он используется как основа
для определения базовой таблицы, несмотря на то что считается (в определенной
степени) таковым во всех других контекстах. Поэтому в данном примере базовая
таблица DEPT имеет четыре столбца, а не два, как это было бы, если бы тип
DEPT_TYPE был инкапсулированным.
5. Столбец DEPT# был описан как первичный ключ для таблицы DEPT. Однако, если строки
таблицы DEPT имеют уникальные идентификаторы (“ссылки”), эти идентификаторы
могли бы при желании использоваться в качестве значения первичного ключа.
CREATE TABLE DEPT OF DEPT_TYPE
( REF IS DEPT_ID SYSTEM GENERATED,
PRIMARY KEY ( DEPT_ID ),
UNIQUE ( DEPT# ) )... ;
Теперь расширим пример, представив базовую таблицу ЕМР следующего вида.
CREATE TABLE ЕМР
( EMP# CHAR(5),
ENAME CHAR(25),
SALARY MONEY,
DEPT_ID REF ( DEPT_TYPE ) SCOPE DEPT
REFERENCES ARE CHECKED
ON DELETE CASCADE,
PRIMARY KEY ( EMP# ) )... ;
Обычно базовая таблица EMP включает в качестве внешнего ключа столбец DEPT#, который
ссылается на отделы с помощью номеров отделов. Здесь, однако, в качестве “ссылочного”
столбца используется столбец DEPT_ID, который неявно объявлен в качестве столбца внешне-
го ключа и который ссылается на отделы с использованием значений “ссылок”. Предложение
SCOPE DEPT указывает соответствующую таблицу для ссылок. Предложение REFERENCES ARE
CHECKED означает, что поддерживается контроль целостности; опция REFERENCES ARE NOT
CHECKED допускает наличие “висящих ссылок” (непонятно, зачем кому-либо когда-либо может
потребоваться указывать такую опцию). Опциями ON DELETE... задаются правила удаления,
аналогичные обычным правилам удаления внешнего ключа (поддерживаются те же самые
опции). Однако отметим, что если это в действительности будет случай, когда столбец
DEPT_ID в базовой таблице DEPT не может быть обновлен (см. п. 3 приведенного выше переч-
ня), то не требуется никакого соответствующего правила ON UPDATE.
Теперь рассмотрим несколько примеров запросов в этой базе данных. Вот формулиров-
ка на языке SQL3 запроса “Получить номера отделов для служащего с номером 'Е1'”.
SELECT EX.DEPT_ID -> DEPT# AS DEPT#
FROM EMP EX
WHERE EX.EMP# = 'El' ;
Приложение Б. Обзор языка SQL3
1051
Обратите внимание на операцию разыменовывания9 в предложении SELECT
(выражение EX.DEPT_ID —> DEPT# возвращает значение DEPT# из строки DEPT, на кото-
рую указывает данное значение идентификатора DEPT_ID). Также обратите внимание, что
спецификация AS здесь в определенной степени необходима (если бы она была опущена,
результирующий столбец был бы задан с именем, “зависящим от реализации”). И нако-
нец, отметим интуитивно непонятный характер построения предложения FROM— полу-
чаемое значение DEPT# извлекается из DEPT, а не из ЕМР, но значение DEPT_ID извлекается
из ЕМР, а не из DEPT.
Замечание. Нелегко не поддаться искушению указать, что этот запрос, вероятно, будет
выполняться хуже, чем его аналог в обычном языке SQL (для которого нужна была бы одна
таблица, а не две). Это замечание здесь приводится еще и потому, что обычный аргумент в
защиту “ссылок” состоит в том, что они подразумевают увеличение производительности.
Кстати сказать, если бы запрос был сформулирован как “Получить отдел (вместо
просто номера отдела) для служащего с номером ' Е1операция разыменовывания бы-
ла бы совсем иной.
SELECT DEREF (EX.DEPT_ID ) AS DEPT
FROM EMP EX
WHERE EX.EMP# = 'El' ;
Более того, вызов операции DEREF возвращал бы не значение строки, а “инкапсу-
лированное” (скалярное) значение.
Вот еще один пример: “Получить номера служащих, работающих в отделе ' D1'”
(обратите внимание на разыменовывание в предложении WHERE).
SELECT EX.EMP#
FROM EMP EX
WHERE EX.DEPT_ID -> DEPT# = 'Dl' ;
Ниже приводится пример операции INSERT (вставка сведений о некотором служащем).
INSERT INTO ЕМР ( ЕМР#, DEPT_ID )
VALUES ( 'Е5', ( SELECT DX.DEPT_ID
FROM DEPT DX
WHERE DX.DEPT# = 'D2' ) ) ;
Б.5. Подтаблицы и супертаблицы
Рассмотрим следующие структурированные типы (описывающие служащего и про-
граммиста).
CREATE TYPE EMP_TYPE
AS ( EMP# ...? DEPT# ... )
REF IS SYSTEM GENERATED
NOT FINAL ... ;
9 В большинстве языков, в которых поддерживается операция разыменовывания, также
поддерживается операция привязки, но в языке SQL3 — нет.
1052
Приложения
CREATE TYPE PGMR_TYPE UNDER EMP_TYPE
AS ( LANG ... )
NOT FINAL ... ;
Заметим, что определение типа PGMR_TYPE не имеет предложения REF IS .... Вместо
этого оно фактически наследует такое предложение от своего непосредственного
супертипа EMP_TYPE.
Теперь рассмотрим следующие определения базовых таблиц.
CREATE TABLE ЕМР OF EMP_TYPE
( REF IS EMP_ID SYSTEM GENERATED,
PRIMARY KEY ( EMP# ),
UNIQUE ( EMP_ID ) ) ;
CREATE TABLE PGMR OF PGMR_TYPE UNDER EMP ;
Обратите внимание на спецификацию UNDER ЕМР в определении базовой таблицы
PGMR (также обратите внимание на отсутствие спецификаций REF IS ...,
PRIMARY KEY и UNIQUE для этой базовой таблицы). Такие базовые таблицы, как PGMR
и ЕМР, называются подтаблицей и соответствующей непосредственной супер-
таблицей. Таблица PGMR наследует столбцы таблицы ЕМР и имеет один дополни-
тельный собственный столбец LANG. Интуитивно в этом примере утверждается, что
не программист имеет лишь некоторую строку в таблице ЕМР, а программист имеет
строку в обеих таблицах, поскольку каждая строка в таблице PGMR имеет эквивалент
в таблице ЕМР, но обратное неверно.
Операции обработки данных для этих таблиц выполняются следующим образом.
Операция SELECT. Для таблицы ЕМР операция SELECT выполняется так, как обычно,
а для таблицы PGMR — как будто в этой таблице PGMR действительно содержатся
столбцы таблицы ЕМР и столбец LANG.
Замечание. Уточнение ONLY может использоваться в параметре <ссылочная
таблнца> для исключения строк, которые имеют эквиваленты в некоторой
подтаблице данной таблицы. Поэтому, например, операция
SELECT ... FROM ONLY ЕМР выполняется так, как будто в таблицу ЕМР включе-
ны только строки, которые не имеют эквивалентов в таблице PGMR.
Операция INSERT. Для таблицы ЕМР операция INSERT выполняется так, как обычно.
В результате ее выполнения для таблицы PGMR новые строки вставляются в обе
таблицы, PGMR и ЕМР.
Операция DELETE. При выполнении операции DELETE для таблицы ЕМР удаляются
строки из таблиц ЕМР и (если эти строки соответствуют программистам) PGMR.
Удаление строк из таблицы PGMR приводит к удалению строк из обеих таблиц.
Операция UPDATE. Обновление столбца LANG, обязательно через таблицу PGMR,
приводит к обновлению лишь таблицы PGMR. Обновления других столбцов через
таблицу PGMR или ЕМР приводят к обновлению обеих таблиц (концептуально).
Приложение Б. Обзор языка SQL3
1053
Укажем на некоторые следствия из предыдущих правил.
Предположим, что служащий 'Joe' стал программистом. Если просто вставить
строку для 'Joe' в таблицу PGMR, система попытается вставить строку для 'Joe'
также в таблицу ЕМР, что, конечно, приведет к ошибке. Вместо этого необходимо
удалить строку служащего 'Joe' из таблицы ЕМР, а затем вставить соответствую-
щую строку в таблицу PGMR.
И наоборот, предположим, что служащий 'Joe' перестал быть программистом.
На этот раз необходимо удалить строку 'Joe' из таблицы ЕМР или PGMR (какую бы
таблицу мы ни указали, в результате строки будут удалены из обеих таблиц). За-
тем нужно вновь вставить соответствующую строку в таблицу ЕМР.
А что делать с наследованием типа? Насколько мы можем судить, ответ на этот во-
прос — “Ничего”, т.е. ничего, кроме того (по соображениям, которые непонятны), что
язык SQL3 требует, чтобы подтаблица и ее непосредственная супертаблица были опре-
делены через структурированные типы, которые являются подтипом и его непосредст-
венным супертипом соответственно. Подчеркнем, что никакой заменимости эта схема не
включает и, кроме того, рассматриваемые типы, совершенно определенно, не
“инкапсулированы”.
Итак, насколько привлекательны для нас подтаблицы и супертаблицы? Ответ, по-
видимому, будет “Слегка”, по крайней мере на уровне л/одеуш10. Действительно, опре-
деленная экономия в реализации может быть достигнута, если подтаблица и
супертаблица физически хранятся как одна таблица на диске. Но такие соображения,
безусловно, никак не должны влиять на модель как таковую. Другими словами, непо-
нятно не только, как указывалось в предыдущем абзаце, почему “под- и супертабли-
цы” должны зависеть от “под- и суперструктурированных” типов, но и зачем такая
возможность вообще поддерживается.
Б.6. Другие возможности
Создание таблиц
В языке SQL3 в предложении CREATE TABLE поддерживается опция LIKE, позволяю-
щая скопировать некоторые или все определения новой базовой таблицы из некоторой
существующей именованной таблицы (отметим, что именованная не означает возмож-
ность указать произвольное табличное выражение вместо имени таблицы).
Табличные выражения
В главе 5 было описано предложение WITH, назначение которого — ввести сокращен-
ные имена для определенных выражений. В языке SQL3 включена подобная конструк-
ция, но ее использование ограничивается лишь табличным выражением, как например,
показано ниже.
10 Вероятно, стоит напомнить, какой подход к этому вопросу мы считаем более предпоч-
тительным: подход, в котором используются представления (см. пример в конце раздела 13.5).
1054
Приложения
WITH LONG_TERM_EMPS AS
( SELECT *
FROM EMP
WHERE DATEJ1IRED < DATE '1980-01-01' )
SELECT EMP#, ( LONG_TERM_CT - 1 ) AS #_OF_FELLOW_LONG_TERM_EMPS
FROM LONG_TERM_EMPS AS LI,
( SELECT DEPT#, COUNTf*) AS LONG_TERM_CT
FROM LONG_TERM_EMPS
GROUP BY DEPT# ) AS L2
WHERE LI.DEPT# = L2.DEPT# ;
(Словесная формулировка запроса такова: “Для каждого служащего, который работа-
ет в компании с 1979 года или ранее, получить номер служащего и количество других
служащих в том же отделе”.)
В языке SQL3 предложение WITH может быть использовано, в частности, для форму-
лирования определенных рекурсивных запросов. Например, для данной таблицы
PARENT_OF(PARENT,CHILD) следующий рекурсивный запрос возвращает все пары людей
(а, Ь), таких, что а— предок Ь. Обратите внимание, что определение, которое вводит
имя ANCESTOR_OF, включает ссылку на само имя ANCESTOR_OF.
WITH RECURSIVE ANCESTOR_OF ( ANCESTOR, DESCENDANT )
AS ( SELECT PARENT, CHILD
FROM PARENT_OF
UNION
SELECT A.PARENT, P.CHILD
FROM ANCESTOR_OF AS A, PARENT_OF AS P
WHERE A.CHILD = P.PARENT )
SELECT *
FROM ANCESTOR_OF
Условные выражения
В языке SQL3 предоставляется новое условие DISTINCT (не путайте с существующим
условием UNIQUE; см. приложение А). Оно предназначено для проверки, являются ли две
строки “различными”. Пусть заданы две строки Left и Right. В них должно содержаться
одно и то же количество, например п, компонентов. Пусть i-e компоненты строк Left и
Right— Li и Ri(i = 1, 2, ..., п) соответственно. Тип компонента Ы должен быть совмес-
тимым с типом компонента Ri. Тогда после вычисления выражения
Left IS DISTINCT FROM Right
будет получен результат ложь, если и только если для всех i либо выражение “Li = Ri”
имеет значение истина, либо Li и Ri оба равны NULL-значениям. В противном случае
возвращается истина. (Иначе говоря, строки Left и Right являются “различными”, если и
только если они не “дублируют” одна другую в смысле главы 18.) Отметим, что условие
DISTINCT никогда не дает в результате значение неизвестно.
Приложение Б. Обзор языка SQL3
1055
В языке SQL3 также предоставляется новое условие SIMILAR, которое (как и условие
LIKE) служит для шаблонного сравнения символьных строк, т.е. с его помощью проверя-
ется, удовлетворяет ли данная символьная строка некоторому заданному шаблону. Отли-
чие заключается в том, что условие SIMILAR поддерживает более широкий диапазон воз-
можностей (“символы-заменители” и т.п.) по сравнению с условием LIKE. Синтаксис
этого условия следующий.
<выражение типа символьной строки> [NOT] SIMILAR ТО <шаблон>
[ ESCAPE <исключение> ]
Здесь параметры <шаблон> и <исключение> по сути те же, что и в условии LIKE, но
параметр <шаблон> может включать дополнительные специальные символы — не просто
и “%”, как в условии LIKE, а также и многие другие. Общее их назначение
заключается в поддержке правил анализа выражений, записанных на некотором фор-
мальном языке.
Замечание. Стоит упомянуть, что правила для условия SIMILAR были скопированы с
подобного оператора в языке POSIX.
В завершение этого подраздела отметим, что при наличии нового встроенного типа
BOOLEAN условные выражения становятся просто скалярными выражениями специально-
го вида (чем, впрочем, они и должны были быть всегда).
Целостность
В языке SQL3 поддерживается ограничение RESTRICT <ссылочное действием кото-
рое подобно, но не идентично опции NO ACTION (для уяснения различия обратитесь
к главе 8). Также включена некоторая поддержка триггерных процедур (триггеров), в
частности имеется оператор CREATE TRIGGER, которым определяется триггер— комби-
нация определений события и действия.
Событие — это операция INSERT, UPDATE (необязательно для указанных столбцов)
или DELETE для указанной именованной таблицы.
Действие — это действие (фактически — процедура), которое будет выполнено
AFTER (после) или BEFORE (до) обработки указанного события.
Точнее, действие состоит из необязательного условного выражения (по умолчанию
равного истине) и SQL-процедуры, которая будет выполнена, если и только если усло-
вие истинно, когда событие произойдет. Пользователь может указать, будет ли действие
выполняться один раз, когда случается событие, или же один раз для каждой строки
FOR EACH ROW таблицы, с которой данное событие связано. Более того, спецификации
действия могут ссылаться на значения “до” и “после” в таблице, связанной с конкретным
событием, предоставляя таким образом примитивный уровень поддержки для, помимо
всего прочего, ограничений перехода.
Обновление представлений
В языке SQL3 расширена поддержка обновления представлений за счет включения
представлений типа UNION ALL и представлений, определенных на базе соединений типа
“один ко многим” и “многие ко многим”. Аналогичные расширения имеются и для курсоров.
1056
Приложения
Управление транзакциями
В язык SQL3 включено несколько новых возможностей управления транзакциями.
Использование явного оператора START TRANSACTION (с теми же операндами, что
и у оператора SET TRANSACTION; см. главу 14)
Использование опции WITH HOLD для оператора объявления курсора
DECLARE CURSOR (опять же, см. главу 14)
Поддержка контрольных точек (см. аннотацию к [14.11])
Безопасность
В языке SQL3 поддерживаются привилегии выборки конкретных столбцов
(привилегии SELECT(х) позволяют их обладателю ссылаться на конкретный столбец х
конкретной именованной таблицы в параметре <табличное выражение^. Также поддер-
живаются определяемые пользователем роли. В качестве примера можно привести роль
ACCG, означающую любого сотрудника бухгалтерии. Однажды созданная роль может на-
деляться привилегиями точно так, как если бы это был идентификатор пользователя. Бо-
лее того, роли могут предоставляться, подобно привилегиям, и так же, как все привиле-
гии, могут предоставляться или пользователю, или другой роли.
Отсутствующая информация
Здесь мы ограничимся лишь одним наблюдением. Использование возможностей но-
вых типов в языке SQL3 (как и ожидалось) усложняется наличием NULL-значений. На-
пример, пусть V— переменная некоторого структурированного типа Т. Тогда может
быть так, что значение некоторого компонента переменной V равно NULL-значению (в
этом случае условное выражение V = V вычисляется, как значение неизвестно), тем не
менее условное выражение V IS NULL вычисляется, как ложь\ Фактически в общем слу-
чае можно сказать, что если ((7 = 7) IS NOT TRUE) IS TRUE— истина, то или значе-
ние V равно NULL-значению, или переменная V включает компонент, значение которого
равно NULL-значению.
Поддержка принятия решений
В язык SQL3 включена поддержка опций GROUPING SETS, ROLLUP и CUBE для предло-
жения GROUP BY, как было описано в главе 21.
Приложение Б. Обзор языка SQL3
1057
Приложение
Сокращения и специальные
символы
ACID atomicity/consistency/ isolation/durability
АСМ Association for Computing Machinery
ADT abstract data type
ANSI American National Standards Institute
ANSI/SPARK ANSI/Systems Planning and Requirements Committee
ARIES algorithm for recovery and isolation exploiting semantics
BB GB
BCNF Boyce/Codd normal form
BCS British Computer Society
BLOB binary large object
BNF Backus-Naur form or Backus normal form
CACM Communications of the ACM (ACM publication)
CAD/CAM computer-aided design/computer-aided manufacturing
CASE computer-aided software engineering
CDO class-defining object
CIM computer-integrated manufacturing
CLI Call-Level Interface
CLOB character large object
CNF conjunctive normal form
атомарность/согласованность/
изолированность/продолжительность
Ассоциация по вычислительной технике
абстрактный тип данных
Американский национальный институт
стандартов
Американский национальный институт
стандартов/Комитет системного плани-
рования и требований (упоминался в
главе 2 в связи с трехуровневой архитек-
турой систем баз данных)
алгоритм восстановления и использую-
щей изоляцию семантики
то же самое, что гигабайт (Гбайт)
нормальная форма Бойса-Кодда (НФБК)
Британское компьютерное общество
большой двоичный объект
форма Бэкуса-Наура или нормальная
форма Бэкуса
Средства коммуникации АСМ (издание
АСМ)
автоматизированное проектирование/ ав-
томатизированное производство
(САПР/АСУТП)
автоматизация разработки программного
обеспечения
объект, определяющий класс
автоматизированное интегрированное
производство
интерфейс уровня вызова (процедур)
большой символьный объект
конъюнктивная нормальная форма
1058
Приложения
CODASYL Conference on Data Systems Ассоциация по языкам систем данных;
Languages используется при ссылке на определенные дореляционные системы, такие как IDMS
CPU central processing unit центральный процессор (ЦП)
CS cursor stability (DB2) стабильность курсора (в СУБД DB2)
CWA Closed World Assumption допущение о замкнутости мира
DA data administrator администратор данных (АД)
DB/DC database/data communications база данных/передача данных
DBA database administrator администратор базы данных (АБД)
DBMS database management system система управления базой данных (СУБД)
DBP&D Database Programming & Программирование и проектирование
Design баз данных (журнал, в настоящее время интерактивный)
DBTG Data Base Task Group группа задач баз данных; используется взаимозаменяемо с CODASYL в контек- сте баз данных
DC data communications передача данных
DCO “domain check override” замещение проверки домена
DDB distributed database распределенная база данных
DDBMS distributed DBMS распределенная СУБД (РСУБД)
DDL data definition language язык определения данных (ЯОД)
DES Data Encryption Standard стандарт шифрования данных
DK/NF domain-key normal form доменно-ключевая нормальная форма
DML data manipulation language язык обработки данных (ЯОД)
DNF disjunctive normal form дизъюнктивная нормальная форма
DRDA Distributed Relational архитектура распределенных реляцион-
Database Architecture ных баз данных
DSL data sublanguage подъязык данных
DSS decision support system система поддержки принятия решений
DUW distributed unit of work распределенная часть работы
E/R entity/relationship “сущность/связь”
EB exabyte (1024PB) эксабайт (Ебайт); равен 1024 петабайт (Пбайт)
EDB extensional database экстенсиональная база данных
EKNF elementary key normal form нормальная форма с элементарными ключами
EMVD embedded MVD внедренная многозначная зависимость
FD functional dependence функциональная зависимость (ФЗ)
GB gigabyte (1024MB) гигабайт (Гбайт); равен 1024 мегабайт (Мбайт)
GIS geographic information system географическая информационная система
Приложение В. Сокращения и специальные символы
1059
HOLAP hybrid OLAP гибридная система OLAP
I/O input/output ввод-вывод
IDB intensional database интенсиональная база данных
IDMS Integrated Database Management System интегрированная система управления ба- зой данных — одна из первых СУБД
IEEE Institute for Electrical and Electronics Engineers Институт инженеров электрики и элек- троники (США)
IMS Information Management System система управления информацией — од- на из первых СУБД
IND inclusion dependence включаемая зависимость
IS intent shared lock; information system разделяемая блокировка намерения; ин- формационная система
ISBL Information System Base Language язык баз информационных систем
ISO International Organization for Standardization Международная организация по стандар- тизации
IT information technology информационная технология (ИТ)
IX intent exclusive (lock) эксклюзивная блокировка намерения
JACM Journal of the ACM (ACM publication) Журнал АСМ (издание АСМ)
JD join dependence зависимость соединения (ЗС)
JDBC Java Database Connectivity Java-интерфейс для установки связи с ба- зами данных
К 1024 (sometimes 1000) 1024 (иногда 1000)
KB kilobyte (1024 bytes) килобайт (Кбайт); равен 1024 байт
LAN local area network локальная сеть (ЛВС)
LOB large object большой объект
MB megabyte (1024 KB) мегабайт (Мбайт); равен 1024 килобайт (Кбайт)
MLS multi-level secure многоуровневая система защиты
MOLAP multi-dimensional OLAP многомерные базы данных OLAP
MVD multi-valued dependence многозначная зависимость (МЗЗ)
NCITS National Committee on Infor- mation Technology Standards Национальный комитет по стандартам информационных технологий
NCITS/H2 NCITS database committee комитет по базам данных NCITS
NF2 “NF squeared” = NFNF = non first normal form (?) “NF-квадрат” = NFNF = не первая нор- мальная форма (?)
ODBC Open Database Connectivity открытый интерфейс установки связи с базами данных
ODMG Object Data Management Group Группа управления объектными данны- ми (ODMG также называют предложе-
ния группы: ODL, OQL и т.д.)
1060
Приложения
ODS operational data store операционное хранилище данных
OID object ID идентификатор объекта
OLAP online analytic processing оперативная аналитическая обработка
OLCP online complex processing оперативная комплексная обработка
OLDM online decision management оперативное управление решениями
OLTP online transaction processing оперативная обработка транзакций
OMG Object Management Group Группа управления объектами
00 object-oriented; object объектно-ориентированный; объектная
orientation ориентация (00)
OODB object-oriented database объектно-ориентированная база данных
OOPL object-oriented programming объектно-ориентированный язык про-
language граммирования
OQL Object Query Language объектный язык запросов (часть стан- дарта 0DMG)
OSI Open System Interconnection открытый интерфейс взаимодействия систем
OSQL “Object SQL” “объектный SQL”
PB petabyte (1024TB) петабайт (Пбайт); равен 1024 терабайт (Тбайт)
PC personal computer персональный компьютер (ПК)
PJ/NF projection-join normal form нормальная форма проекции-соединения
PODS Principles of Database Systems принципы систем баз данных
PR.TV Peterlee Relational Test экспериментальная реляционная систе-
Vehicle ма, разработанная в городе Питерли
PSM Persistent Stored Modules постоянные хранимые модули
QBE Query-By-Example запрос-по-образцу
QUEL Query Language язык запросов
RAID redundant array of inexpensive disks надежный массив недорогих дисков
RDA Remote Data Access удаленный доступ к данным
RDB relational database реляционная база данных
RDBMS relational DBMS реляционная СУБД
RID (stored) record ID or row ID (хранимый) идентификатор записи или идентификатор строки
ROLAP relational OLAP реляционная система OLAP
RM/T relational model/Tasmania реляционная модель/Тасмания
RM/V1 relational model/Versionl реляционная модель/версия 1
RM/V2 relational model/Version2 реляционная модель/версия 2
RPC remote procedure call удаленный вызов процедур (протокол)
RR repeatable read повторяющееся чтение
RUW remote unit of work удаленная часть работы
Приложение В. Сокращения и специальные символы
1061
RVA relation-valued attribute атрибут, значение которого — отношение
S shared (lock) разделяемая (блокировка)
SIGMOD Special Interest Group on Management of Data (ACM special interest Group) Специальная группа по управлению дан- ными (специальная группа АСМ)
SIX shared intent exclusive (lock) эксклюзивная разделяемая блокировка намерения
SPARC see ANSI/SPARC см. ANSI/SPARC
SQL Structured Query Language, Standard Query Language структурированный язык запросов, стан- дартный язык запросов
ТВ terabyte (1024GB) терабайт (Тбайт); равен 1024 гигабайт (Гбайт)
TCB Trusted Computing Base надежная вычислительная база
TCP/IP Transmission Control Protocol/Intemet Protocol протокол управления переда- чей/протокол Internet
TID (stored) tuple ID (хранимый) идентификатор кортежа
TOPS Transaction on Database Systems (ACM publication) Транзакции в системах баз данных (издание АСМ)
TPC Transaction Processing Council Совет по обработке транзакций
U update (lock) (блокировка) обновления
UDT user-defined type тип, определяемый пользователем
UML Unified Modeling Language единый язык моделирования
unk unknown (null) неизвестное значение (NULL-значение)
UOW unit of work часть работы
VLDB very large database; Very Large Data Bases (annual conference) очень большая база данных; Очень большие базы данных (ежегодные кон- ференции)
VSAM Virtual Storage Access Method метод доступа к виртуальной памяти
WAL write-ahead log предварительная запись в журнал
WAN wide area network глобальные сети (ГВС)
WFF well-formed formula правильно построенная формула
WORM write once/read many times запись однажды/чтение многоразовое
WYSIWYG what you see is what you get что видите, то и получаете
X exclusive (lock) эксклюзивная, без взаимного доступа (блокировка)
X3 see NCITS см. NCITS
X3H2 see NCITS/H2 см. NCITS/H2
INF first normal form первая нормальная форма (1НФ)
2NF second normal form вторая нормальная форма (2НФ)
2PC two-phase commit двухфазная фиксация (протокол)
1062
Приложения
2PL two-phase locking
2VL two-valued logic
20С same as 2PC
20L same as 2PL
3GL third generation language
3VL three-valued logic
3NF third normal form
4GL fourth generation language
4NF fourth normal form
4VL four-valued logic
5NF fifth normal form (same
PJ/NF)
Е
0
0
F
к
двухфазная блокировка
двузначная логика
то же самое, что и 2РС
то же самое, что и 2PL
язык (программирования) третьего поко-
ления
трехзначная логика
третья нормальная форма (ЗНФ)
язык (программирования) четвертого по-
коления
четвертая нормальная форма (4НФ)
четырехзначная логика
пятая нормальная форма (5НФ) (то же
самое, что и PJ/NF)
принадлежит
оператор сравнения (=, < и т.д.)
пустое множество
функционально определяет
многозначно определяет
равносильно (тождественно)
следует (логическая связка)
следует (металингвистический символ)
всегда справедливо
(металингвистический символ)
конец (доказательства, примера и т.п.)
Приложение В. Сокращения и специальные символы
1063
Предметный указатель
С s
CODASYL, 58 SQL, 34; 69; 108; 119; 266; 322; 380; 794; 797; 801; 807; 838; 1028
D CLI, 135 SQL3, 1041
DataJoiner, 799 DBTG, 58 базовые переменные, 128 базовые таблицы, 177 вложенные подзапросы, 126
Е внедрение операторов, 126 внешние ключи, 324
ER-диаграмма, 42; 510; 514 свойство, 515 связь, 516 сущность, 515 ER-модель, 510; 522 группирование, 272; 1032 динамический, 134 домены, 174 значения по умолчанию, 130 инициализация транзакции, 126; 555 каталог, 124 ключи, 714
F комментарий, 123 курсоры, 129; 131; 132; 548
false, 693; 695 манипулирование данными, 122 недостатки, 136
N неопределенные значения, 711 обновление данных, 123
NULL, 693; 704; 706; 825 обобщающие функции, 271 ограничения домена, 323
О ограничения таблицы, 323 ограничения целостности, 322; 326
ODBC, 135; 797 OID, 953 OLAP, 836 HOLAP, 844 MOLAP, 842 ROLAP, 842 перекрестные таблицы, 841 OLTP, 41;813;818 определение данных, 120; 712 определитель NULL, 271 относительное имя, 267 поддержка представлений, 380 поддержка транзакций, 554 подзапросы, 2 73 потенциальные ключи, 323 предложение SELECT, 1030 предоставление полномочий, 626
Q представления. 125; 626 проверочные условия, 324
QBE, 283 скалярные выражения, 713 сортировка результата, 268
R транзакции, 126; 801 условия выборки, 1032
RDA, 794 условные выражения, 712
1064
Предметный указатель
т
Базы данных
timestamp, 855 программное обеспечение, 38
true, 693; 695 проектирование, 887
Tutorial D, 856 распределенные, 86; 767; 770 связи, 41
и статистические, 615 статистические показатели, 653
unknown, 695 сущности, 41 транзакции, 545
A уровень детализации, 832 хронологические, 853; 855; 863; 887
АБД, 68; 75 Банк данных, 814
Агент, 779 Банк оперативных данных, 829
Администратор базы данных, 75 Блокировка, 569; 791
Администратор данных, 75 граф ожидания, 575
Аксиомы, 900 двухфазная, 577
дедуктивные, 901 протокол, 571
Аксиомы Армстронга, 405 стратегия первичной копии, 791
Алгоритм редукции Кодда, 257 Аномалии, 432 и
Архитектура, 65; 108
ANSI/SPARC, 65 Объекты, 988
внешнее представление, 71 Восстановление, 544
внешний уровень, 68 носителей, 552
внутренний уровень, 73 системы, 550
клиент/сервер, 81; 793 Временная отметка, 855
концептуальный уровень, 72 Время транзакции, 858
отображение, 74 Высказывание, 904
Атрибуты, 152; 431 допустимое время, 857
домены, 698 замыкание множества, 407 неключевые, 431 Г
отношения, 474 ГВС, 780
специальные значения, 711 Граф ожидания, 575; 792
типа отношения, 448 Группирование, 222
! Б д
База знаний, 899 Базовые переменные, 128 Базы данных, 32; 40; 45 Данные, 44 временные, 853 встроенные типы, 1042 защита, 602
администраторы, 40 аппаратное обеспечение, 37 восстановление, 544; 549 интенсиональные, 918 логические, 899
интервалы, 868 логическая независимость, 354 независимость, 50 обобщение, 836
локальные, 768 объекты, 944
однородные, 769 поддержки принятия решений, 815; 817 пользователи, 39 принцип относительности, 357 ограничения, 602; 864 операционные, 813 подтип, 725
Предметный указатель
1065
Данные
распределенные, 770
репликация, 777
структуры хранения, 1015
супертип, 725
тип, 725
физическая независимость, 818; 950
хронологические, 855
целостность, 602
шифрование, 621
экземпляр, 52
Двухфазная фиксация, 553; 779
Декомпозиция, 426
вертикальная, 889
горизонтальная, 887
Декомпозиция запросов, 654
Денормализация, 483
Дерево запроса, 643
Доказательно-теоретический подход, 900
Домен, 152; 512
Допустимое время, 857
Ж
Журнал регистрации, 547; 549
3
Зависимость, 400
включаемая, 820
соединения, 477
Загрузка данных, 828
Законы
ассоциативный, 649
идемпотентности, 650
коммутативный, 649
преобразования, 702
распределительный, 648
Заменимость, 733; 736; 739; 757
Замыкание множества, 405; 407
Запрос, 79; 1014
каноническая форма, 644
произвольный, 973
распределенный, 807
рекурсивный, 899; 924
удаленный, 807
Защита
избирательный контроль, 603; 605
обязательный контроль, 603; 611
полномочия, 605
привилегии, 605
Защита данных, 602
ограничения, 49
Зернистость, 859; 869
“Золотое правило”, 309
И
Идентичность, 508
Избирательная схема контроля, 603; 605
Избыточность, 47: 404; 422; 544; 824
контролируемая, 820
Индексы, 821
Инкапсуляция, 871; 950
Интервал времени, 867; 871
Исчисление, 903
высказываний, 902
доказательство, 905
кортежей, 245
правила вывода, 904
предикатов, 899; 907
термы, 903
формулы, 903
Итоговые таблицы, 824
К
Кардинальность, 152
Каталог, 104; 156; 783
Квант времени, 858
Кванторы
EXISTS, 696
FORALL, 696
Классы
конструктор, 958
сообщения, 951
Клиент, 82; 84
Ключ, 311; 431; 704; 714; 865; 881
альтернативный, 314; 705
внешний, 315; 318; 324; 706
первичный, 151; 314; 318; 705
потенциальный, 311; 314; 323; 432; 442
потенциальный хронологический, 884
суперключ, 408
суррогатный, 957
КНФ, 651
Коллекции, 958
Конвейерная обработка, 94
Контрольные точки, 551
Координатор, 553
Кортеж, 152; 164
0-кортеж, 220
1066
Предметный указатель
Литералы, 157
Ловушка соединения, 43
Логика, 700; 902
высказывания, 904
дублирующиеся кортежи, 699
логическая импликация, 904
теорема, 900
трехзначная, 695
Логическая база данных, 899
Логические выражения, 695
Логическое значение
false, 693
true, 693
unknown, 693
м
Магазины данных, 831
Маркер настоящего момента, 887
Массовые параллельные системы, 802
Менеджер
передачи данных, 81; 768
ресурсов, 553; 787
транзакций, 79
Метаданные, 80; 104
Многозначная зависимость, 469; 472
Модели данных, 44; 56
“сущность-связь”, 510
RM/T, 508
дедуктивная, 58
иерархическая, 57
инвертированные списки, 57
многомерная, 58
объектная, 944
объектно-ориентированные, 58
объектно-реляционные, 58
реляционная, 44; 92; 96; 1011
сетевая, 57
функциональная, 995
Моделирование, 505
ER-модель, 522
правила целостности, 508
семантическое, 506; 507
Момент времени, 858
Моментальные снимки, 378; 787
Мутатор, 751
Наблюдатель, 751
Наследование, 726; 728; 756
Настройка систем, 76
Независимость данных, 50
Неизвестное значение, 693
Неопределенные значения, 693
Нормализация, 423; 424; 481; 489; 490; 887
(3,3)НФ, 491
1НФ, 423; 424; 431
2НФ, 424; 435
ЗНФ, 430; 431; 438
4НФ, 474
5НФ, 479
атомарная переменная-отношение, 441
декомпозиция, 425; 426; 439; 443
ДКНФ, 490
другие НФ, 490
зависимость соединения, 477
многозначная зависимость, 469; 472; 477
нормальные формы, 424
НФБК, 425; 442; 444; 472
ПСНФ, 479
функциональная зависимость, 477
О
Обобщающие функции, 217; 220
Обобщение, 743
Обратное восстановление, 552
Объекты, 944; 948; 949; 962; 1002
идентификатор, 953; 957
иерархия классов, 961
инкапсуляция, 950
класс, 949; 958
коллекции, 958; 965
конфигурации, 989
переменные экземпляра, 950; 951
полиморфизм, 962
указатель, 1011
экземпляры, 958
Обязательная схема контроля, 603; 611
Овеществление, 54; 358
Ограничения целостности, 49; 301; 303; 308;
309; 402; 652; 700; 705; 819; 860; 870
золотое правило, 307; 309
ограничение ключа, 490
ограничения атрибута, 305; 490
ограничения базы данных, 306; 310
ограничения отношения, 305
ограничения подмножеств, 677
Предметный указатель
1067
Ограничения целостности
ограничения причастности, 677
ограничения типа, 303
отношения, 310; 313
ссылочная целостность, 316; 706
Операторы, 742; 748
COALESCE, 874
TREAT DOWN, 739
UNFOLD, 874
выбора, 725; 754
обновления, 885
обобщения для интервалов, 873
присвоения, 726; 737
проверки типа, 726; 746
равенства, 726
скалярные для интервалов, 871
сравнения, 744
чтения и обновления. 751
Операция
хронологическая проекция, 878
хронологическая разность, 880
Оптимизация, 101; 213; 639; 642; 702; 778;
781; 1014
ассоциативный закон, 649
декомпозиция запросов, 654
дерево запроса, 643
закон идемпотентности, 650
каноническая форма, 644
коммутативный закон, 649
логические выражения, 650
отделение подзапросов. 655
план запроса, 646
подстановка кортежей, 655
правила преобразования, 645
процедуры реализации, 645
распределительный закон, 648
семантические преобразования, 651
скалярные выражения, 650
формула стоимости, 646
Ортогональность
языка, 271
Отказы
носителей, 550
системы, 550
Отношения, 97; 151; 423; 1002; 1011
0-кортеж, 220
атрибут, 152
дублирующиеся кортежи, 699
заголовок, 99; 163; 195
значения, 163
“золотое правило”, 359
избыточность, 404; 422
Отношения
кардинальность, 152; 163
кортеж, 152
обновление, 360; 377
выборки, 367
пересечений, 366
проекции,368
разности, 367
расширений, 370
соединений, 372
свойства, 166
степень, 152; 163
тело. 99; 163
функциональная зависимость, 400
хронологическое, 855
Отображение, 67; 74; 75; 77
Отображения, 71
п
Параллельная обработка, 84
Параллельность, 566; 791
блокировка, 569
блокировка намерения, 580
взаимная блокировка, 575
графики, 577
метод управления, 566
упорядочиваемость, 576
Перегрузка, 876
Передача данных
соединения, 801
Переменная кортежа, 244; 247; 251
свободная, 248
связанная, 248
Переменная-отношение, 97: 169; 194; 308;
401; 403; 423; 1007; 1011
атомарная, 441
базовая, 105
виртуальная, 350
декомпозиция, 439
распределенная, 771
самоссылающаяся, 317
фрагментация, 773
Переменные экземпляра, 951
Перманентность. 40
План запроса, 646
Поддержка принятия решений, 813
Покрытие, 409
Полиморфизм, 732; 962
Полномочия, 605
Потенциальный ключ, 403; 866
Правило вывода, 901; 904
1068
Предметный указатель
Предварительная запись, 549
Предикат, 100; 169; 244; 307; 309; 899; 903;
907
Представления, 106; 108; 350; 353; 775
обновление, 358
объединений, 363
определение, 352
параметризованные, 627
принцип взаимозаменяемости, 357
процедура подстановки, 351
Привилегии доступа, 605
Принцип подстановки, 961
Проектирование
ER-диаграмма, 514
ER-моделирование, 516
логическое, 75; 817; 818
ортогональное, 486
физическое, 75; 817; 820
Прозрачность
расположения, 773
репликации, 777
Протоколы
предварительной записи в журнал, 549
Прямое восстановление, 552
Р
Разгруппирование, 223
Разработка данных, 844
Распределенная обработка, 83; 84
Расчетные столбцы, 824
Резервная копия, 552
Резолюция, 925
Рекурсия, 924
Реляционная алгебра. 192; 211; 222; 225;
243; 257; 261; 351; 696
логическая импликации, 256
семантика, 199
синтаксис, 197
сравнения, 744
Реляционная замкнутость, 94
Реляционная модель, 97
замкнутость, 195
Реляционная полнота, 261
Реляционное исчисление, 243; 257; 260; 302;
696
вычислительные возможности, 262
исчисление доменов, 263
исчисление кортежей, 245
кванторы, 249
реляционная полнота, 266
синтаксис, 245
Реляционное исчисление
условие принадлежности, 263
формула WFF, 246; 248; 249; 251; 252
Реляционные операции, 197; 252; 699; 861
внешнее соединение, 707
выборка, 202
вычитание, 200
группирование, 222
деление, 207
звездообразное соединение, 834
обобщение, 217; 218; 220
объединение, 199
переименование, 196
пересечение, 200
полувычитание, 214
полусоединение, 214
проекция, 203; 427
произведение, 201
прототип кортежа, 252
разгруппирование, 223
расширение, 215
реализация, 658
соединение, 205
сравнения, 225
транзитивное замыкание, 221
Репликация, 777; 823
РСУБД, 796
именование объектов, 783
С
Свойство, 512; 515; 520
многозначное, 512
однозначное, 512
производное, 512
Связь, 41; 113; 508; 510; 512; 516; 517
рекурсивная, 516
свойства, 43
участие сторон, 512
Сервер, 82; 84
Сигнатура, 749
Системный каталог. 301; 639
Системы клиент/сервер, 792; 795
Словарь данных, 80
Составные столбцы, 819
Специализация, 741; 742; 748; 757
Ссылочная диаграмма, 316
Ссылочная целостность, 318
ссылочные операции, 319
Статистические показатели, 653
Степень, 152
Страницы, 73
Предметный указатель
1069
СУБД. 35: 38; 77; 767; 768; 780; 980
восстановление
носителей, 552
системы. 550
доступность, 773
инструментальные средства, 82
каталог, 104; 783
многомерные, 842
многопользовательская, 35
надежность, 773
объектно-реляционные, 999
однопользовательская, 35
оптимизация, 101; 642
подсистема защиты, 604
пользовательский интерфейс, 80
распределенные, 796
резервная копия. 552
РСУБД, 768
утилиты, 83
экспертная, 899
Сущность, 41; 75; 113; 507; 511; 515; 516;
725
подтип, 520
подтипы,513
свойства, 43
сильная. 511
слабая, 511
супертип, 513
тип, 507
Схема "звезда", 825
Схемы, 77; 104
внешняя, 71
внутренняя, 73; 75
концептуальная, 71; 72; 75
отображения, 104
т
Теорема Хета, 428
Термы, 903
Тип, 725; 738; 743; 757; 1002; 1007; 1014;
1042
заменимость, 733
иерархия, 729
интервал. 868: 869
корневой, 731
листовой, 731
наследование, 1047
несвязанный, 732
ограничения, 725
подтип, 731; 758
полиморфизм. 733
Тип
представление, 725
проверка, 746
супертип, 731
Типы данных, 152; 169
допустимые представления, 156
ограничения, 156
преобразование, 161
скалярность, 154
физическое представление. 153
Точка фиксации, 548
Транзакции, 48; 109; 307; 545; 807
ACID-свойства, 786
атомарность, 563
восстановление, 547
временные отметки, 590
двухфазная фиксация, 553; 779; 787
параллельность, 566
поддержка в SQL, 554
предполагаемая фиксация, 790
распределенные, 779; 787
режим доступа, 555
упорядоченность, 110; 576
уровень изоляции, 555; 578
четырехфазная фиксация, 810
Трехзначная логика, 693
Триггеры, 302; 321; 888
У
Узел, 767; 772
Унификация, 913; 925
Упорядоченность, 110
Упорядочиваемость, 576
Уровень детализации, 832
Уровень изоляции, 578
Уровни архитектуры. 65
внешний. 68
Утилиты. 73; 82; 83
копирования/восстановления, 552
Ф
Фрагментация, 821
Функциональная зависимость, 400; 403; 405;
425; 426; 443; 472; 473; 817; 818
детерминант, 402
диаграмма, 429; 432
замыкание \z, 442
замыкание множества, 405
неприводимое множество, 409
сохранение, 439
1070
Предметный указатель
Функциональная зависимость
транзитивная, 405; 436; 439; 443
тривиальная, 404; 405
X
Хранилища данных, 41; 829
OLAP, 836
загрузка данных, 828
звездообразное соединение, 834
извлечение данных, 827
консолидация данных, 827
магазины данных, 831
очистка данных, 827
размерность, 833
разработка данных, 844
схема типа “снежинка”, 836
таблица размерностей, 833
таблица фактов, 833
Хранимые процедуры, 302; 795
Хроники, 560
Хронон, 858
ц
Целостность данных, 97; 301; 602
ч
Четырехфазная фиксация, 810
ш
Шифрование, 621
RSA-схема, 623
алгоритм, 621
ключ, 621
открытый текст, 621
с открытым ключом, 623
стандарты, 622
DES, 623
шифрованный текст, 621
Шлюзы, 796
Я
Языки
базовый язык, 69
обработки данных, 69
определения данных, 69; 71; 78
подъязык данных, 69
Языки запросов, 79
Предметный указатель
1071
Научно-популярное издание
К. Дж. Дейт
Введение в системы баз данных,
7-е издание
Литературный редактор
Верстка
Художественный редактор
Технический редактор
Корректоры
Л.Н. Красножон
И. В. Родюк
С.А. Чернокозинский
Г.Н. Горобец
Л.А. Гордиенко, Л.В. Коровкина,
О.В. Мишутина, Л.В. Чернокозинская
Издательский дом “Вильямс”.
101509, Москва, ул. Лесная, д. 43, стр. 1.
Изд. лиц. ЛР № 090230 от 23.06.99
Госкомитета РФ по печати.
Подписано в печать 11.08.01. Формат 70x100/16.
Гарнитура Times. Печать офсетная.
Усл. печ. л. 80,04. Уч.-изд. л. 66,7. Тираж 5000 экз. Заказ № 1379.
Отпечатано с диапозитивов в ФГУП “Печатный двор”
Министерства РФ по делам печати,
телерадиовещания и средств массовых коммуникаций.
197110, Санкт-Петербург, Чкаловский пр., 15.
и георетиком в ооласти технологии оаз данных, а его книга Введение в систем),
баз данных остается важнейшим первоисточником для тех, кто нуждается в
исчерпывающем и не отстающем от времени руководстве по теории баз данных.
Колин Дж. Уайт (Colin J. White),
основатель компании DataBase Associates International, Inc.
“Действительно исчерпывающее, всеобъемлющее описание реляционной
модели, выполненное в характерной для Дейта ясной и точной манере
изложения.’’
Шудха Рам (Sudha Ram), университет штата Аризона.
“В книге К. Дж. Дейта возможности языка SQL представлены яснее и
подробнее, чем в большинстве других книг. Читатель сможет не только получип
теоретические знания, но и научиться применять их на практике.”
— лпм>\ ,'у щшли uu), университет штата Оклахома.
юлее 25 лет книга К. Дж. Дейта Введение в системы баз
данных является одним из самых авторитетных источников
(нформации для всех читателей, заинтересованных
приобретении ясного и глубокого понимания принципов
эункционирования систем баз данных. Превосходно
ыполненное переиздание фундаментального труда автора
о-прежнему представляет собой исчерпывающее
зложение основ технологии баз данных, дополненное
1нением автора о том, в каких направлениях эта технология
'удет развиваться в будущем.
1ри подготовке седьмого издания Введения в системы баз
данных значительная часть книги подверглась серьезной
ереработке, выполненной с целью расширения
углубления материала по важнейшим темам.
Существенно переработан и расширен материал по
реляционной модели, включая обсуждение типов данных
(доменов), сравнительный анализ реляционных значений
и переменных-отношений, расширенное изложение
концепций целостности данных, теории предикатов
и использования представлений.
Книга дополнена новым материалом о работе
с атрибутами, значениями которых являются отношения,
о методах денормализации, ортогонального
проектирования и использования альтернативных
подходов в семантическом моделировании (включая
понятие бизнес-правил).
В книгу включены совершенно новые главы, содержащие
обсуждение проблем наследования типов, применения баз
данных в приложениях поддержки принятия решений
и создания хронологических баз данных.
К основному материалу книги добавлены два новых
приложения. Одно из них содержит обобщенные сведения
о синтаксисе и семантике операторов языка SOL, а другое
представляет собой краткий обзор нового стандарта
SOL3, принятие которого ожидается в ближайшем
будущем.
итатели этой книги смогут приобрести фундаментальные
чания о назначении, основных концепциях и общей
груктуре систем баз данных и научаться применять их на
рактике, а также смогут освоить теоретические принципы,
эторые положены в основу подобных систем.
К. Дж. Дейт является публицистом,
лектором, исследователем и независимым
консультантом, специализирующимся
в области систем реляционных баз данных.
На протяжении 30 лет он является одним из
активнейших членов сообщества
исследователей в области технологии баз
данных. Большую часть своего времени Дейт
посвятил исследованию, расширению
и распространению реляционной технологии
как в ее теоретической части, так и в области
ее практического применения. Он заслужил
репутацию непревзойденного мастера
благодаря присущей ему манере излагать
самый сложный технический материал
в предельно ясном и понятном стиле.
Некоторые другие издания,
выпущенные с участием К. Дж. Дейта
Foundation for Object/Relational
Databases: The Third Manifesto
(Addison-Wesley, 1998)
Relational Database Writings 1994-1997
(Addison-Wesley, 1998)
A Guide to the SQL Standard,
Fourth Edition
(Addison-Wesley, 1997)
Relational Database Writings 1991-1994
(Addison-Wesley, 1995)
A Guide to DB2, Fourth Edition
(Addison-Wesley, 1993)
A Guide to Sybase and SQL Server
(Addison-Wesley, 1992)
Relational Database Writings 1989-1991
(Addison-Wesley, 1992)
A Guide to SQL/DS
(Addison-Wesley, 1989)