Академический Документы
Профессиональный Документы
Культура Документы
МЕХАНИКО-МАТЕМАТИЧЕСКИЙ ФАКУЛЬТЕТ
Базы данных
Подготовил Ковалев А. Д.
I. Установочный модуль 11
1. Введение 12
2. Практическое задание 15
2.1. Формулировка задания . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2. Пример выполнения задания . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.1. Описание предметной области . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.2. Шаг 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.3. Шаг 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.4. Шаг 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.2.5. Шаг 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2.6. Шаг 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.2.7. Шаг 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.2.8. Шаг 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.2.9. Шаг 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.2.10. Шаг 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2.11. Шаг 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.2.12. Шаг 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.2.13. Шаг 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.2.14. Шаг 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.3. Варианты контрольных работ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.3.1. Страховая компания . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.3.2. Гостиница . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.3.3. Ломбард . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.3.4. Реализация готовой продукции . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.3.5. Ведение заказов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.3.6. Бюро по трудоустройству . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.3.7. Нотариальная контора . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.3.8. Фирма по продаже запчастей . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2.3.9. Курсы по повышению квалификации . . . . . . . . . . . . . . . . . . . . . . . . 43
2.3.10. Определение факультативов для студентов . . . . . . . . . . . . . . . . . . . . . 44
2.3.11. Распределение учебной нагрузки . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
2.3.12. Распределение дополнительных обязанностей . . . . . . . . . . . . . . . . . . . 46
2.3.13. Техническое обслуживание станков . . . . . . . . . . . . . . . . . . . . . . . . . 47
2.3.14. Туристическая фирма . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
2.3.15. Грузовые перевозки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
2.3.16. Учет телефонных переговоров . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
2.3.17. Учет внутриофисных расходов . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
2.3.18. Библиотека . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
2.3.19. Прокат автомобилей . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
2.3.20. Выдача банком кредитов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
2.3.21. Инвестирование свободных средств . . . . . . . . . . . . . . . . . . . . . . . . . 55
2.3.22. Занятость актеров театра . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
2.3.23. Платная поликлиника . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
2.3.24. Анализ динамики показателей финансовой отчетности различных предприятий 58
2.3.25. Учет телекомпанией стоимости прошедшей в эфире рекламы . . . . . . . . . . 59
2.3.26. Интернет-магазин . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
2.3.27. Ювелирная мастерская . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
2.3.28. Парикмахерская . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
2.3.29. Химчистка . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
2.3.30. Сдача в аренду торговых площадей . . . . . . . . . . . . . . . . . . . . . . . . . 64
II. Модуль 1 65
3. Реляционная алгебра 66
3.1. Отсутствующие данные . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.2. Пустые значения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.3. Неопределенные значения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
3.3.1. Интерпретации . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
3.3.2. Правила вычисления выражений . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
3.3.3. Следствия . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.3.4. Проверка условий . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
3.4. Реляционные объекты данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
3.4.1. Формальные определения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3.4.2. Домены и атрибуты . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3.4.3. Схема отношения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
3.4.4. Именованное значение атрибута . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
3.4.5. Кортеж . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
3.4.6. Отношение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
3.4.7. Схема базы данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.4.8. База данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.5. Операции реляционной алгебры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.5.1. Унарные операции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
3.5.2. Бинарные операции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
3.5.3. Варианты операции соединения . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
3.5.4. Производные операции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
3.6. Пример построения выражения реляционной алгебры . . . . . . . . . . . . . . . . . . . 96
3.7. Понятие базовых и виртуальных отношений . . . . . . . . . . . . . . . . . . . . . . . . 98
3.8. Понятие полноты реляционной алгебры . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
3.9. Формирование запросов на языке SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
3.9.1. Реализация операций реляционной алгебры . . . . . . . . . . . . . . . . . . . . 101
3.9.2. Пример использования подзапросов . . . . . . . . . . . . . . . . . . . . . . . . . 109
3.9.3. Группирующие запросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
3.9.4. Упорядочение результатов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
3.10. Вопросы для самоконтроля . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
V. Модуль 4 190
6. Проектирование схем баз данных 191
6.1. Уровни логической модели . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
6.2. Миграция ключей и виды связей . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
6.3. Классификация кластеров . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
6.4. Иерархическая рекурсия . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
6.4.1. Абстрактная схема . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
6.4.2. Обобщения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
6.4.3. Пример реализации иерархической рекурсии . . . . . . . . . . . . . . . . . . . . 207
6.5. Сетевая рекурсия . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
6.5.1. Абстрактная схема . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
6.5.2. Сетевая реализация иерархической рекурсии . . . . . . . . . . . . . . . . . . . . 213
6.5.3. Обобщения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
6.5.4. Пример реализации сетевой рекурсии . . . . . . . . . . . . . . . . . . . . . . . . 216
6.6. Ассоциация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
6.6.1. Детализация связей многие-ко-многим . . . . . . . . . . . . . . . . . . . . . . . 220
6.6.2. Обобщения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
6.6.3. Пример реализации ассоциации . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
6.7. Обобщение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
6.7.1. Абстрактная схема . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
6.7.2. Пример реализации обобщения . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
6.8. Композиция . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
6.8.1. Абстрактная схема . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
6.8.2. Пример реализации композиции . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
6.9. Агрегация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
6.9.1. Абстрактная схема . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
6.9.2. Пример реализации агрегации . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
6.10. Унификация атрибутов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
6.11. Вопросы для самоконтроля . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Литература 314
Установочный модуль
1. Введение
Традиционная тема курса – модели данных – рассматривается с той или иной степенью детализации
в широком диапазоне: модели иерархическая, сетевая, реляционная, постреляционная, объектно-
ориентированая, XML, OLAP.
При рассмотрении основных функций СУБД выделяются функции управления данными во внеш-
ней памяти и буферами оперативной памяти, функция управления транзакциями, функции журна-
лизации и восстановления БД после сбоев, поддержки языков баз данных.
При анализе моделей взаимодействия пользователей с базами данных проводится их сравни-
тельный анализ в исторической цепочке: модели с централизованной архитектурой и автономными
персональными компьютерами, архитектуры «файл-сервер», «клиент-сервер» и ее более развитый
трехзвенный вариант, технологии распределенных баз данных и тиражирования данных.
Далее рассматриваются теоретические вопросы обоснования теории реляционных БД и техноло-
гические вопросы разработки РБД.
Вводится реляционная алгебра. Анализируется проблема неопределенных значений и ее влияние
на методы обработки данных. Формализуется понятие базы данных на наиболее абстрактном уровне.
Вводятся реляционные операции и их варианты, анализируется независимость операций. На алгеб-
раическом уровне водятся понятия базовых и виртуальных отношений. Описывается реализация
операций реляционной алгебры на языке баз данных SQL. Демонстрируется техника использования
SQL-подзапросов.
Рассматривается внутреннее устройство базовых и виртуальных отношений. Определяются базо-
вые типы данных и типы данных, определяемые пользователем. Описывается техника индексирова-
ния. Описываются SQL-конструкции для создания и модификации отношений.
Анализируются декларативные и процедурные методы поддержания целостности БД с использо-
вание механизма транзакций и триггеров.
Излагается теория нормализации (до NFBC включительно). Вводится понятие функциональных
зависимостей, и обосновываются правила вывода Армстронга. Определяются и анализируются 1NF,
2NF, 3NF, NFBC.
Описывается методология проектирования схем баз данных в стиле UML. Вводятся понятия диа-
грамм, связей и их элементов. Методология проектирования демонстрируется на таких кластерах,
как иерархическая и сетевая рекурсии, ассоциация, обобщение, композиция, агрегация. Рассматри-
вается назначение унификации атрибутов.
В заключительной обсуждаются фрактальные методы сжатия BLOB – крупных двоичных объек-
тов, что актуально для мультимедийных БД.
О контрольных работах (лабораторном практикуме). К пособию прилагается задания на выполне-
ние лабораторных работ с примерами ее выполнения.
Цель работы – приобретение практических навыков анализа и моделирования предметной об-
ласти; ознакомление с работой специализированных CASE-средств; изучение подхода к обработке
данных на основе применения языка SQL; при наличии возможностей – ознакомление с архитекту-
рой «клиент-сервер».
Лабораторный практикум предполагает последовательное выполнение студентами 3-х циклов ла-
бораторных работ, моделирующих определенную предметную область, предложенную каждому сту-
денту в рамках конкретного задания.
К разделам пособия прилагаются вопросы для самоконтроля, тестовые задания (где целесообраз-
но) и списки рекомендуемой литературы.
К пособию в целом прилагаются методические указания, тестовые задания и списки рекомендуе-
мой литературы.
Содержание пособия соответствует требованиям ГОС ВПО и, как можно ожидать, пособие не
потеряет актуальности и при переходе на новую систему образования.
Пособие может быть рекомендовано студентам специальности прикладная информатика всех форм
обучения и преподавателям.
2. Практическое задание
Каждая лабораторная работа начинается с объяснения преподавателем задания на конкретном при-
мере. Пример сохраняется неизменным на протяжении всего периода изучении дисциплины. После
объяснения преподавателем задания студенты выполняют свой вариант самостоятельно.
По каждому циклу лабораторных работ должен быть подготовлен отчет.
В первом цикле лабораторных работ студенты приобретают навыки анализа и моделирования
предметной области, а также знакомятся с работой в СУБД.
Построенная реляционная модель реализуется средствами СУБД. Вводятся тестовые данные.
Во втором цикле лабораторных работ изучаются запросы языка SQL и строится простой интер-
фейс пользователя. Студенты самостоятельно формируют различные SQL–запросы, получая навыки
решения конкретных практических задач.
В третьем цикле лабораторных работ студенты самостоятельно расширяют предметную область
(или пользуются предложенным им вариантом расширения) и проектируют схему базы данных для
расширенной предметной области. В рамках новой модели производится модифицирование написан-
ных ранее запросов к базе данных и написание новых. При проведении работ используются CASE-
средства. По окончании производится анализ скрипта для генерирования структуры базы данных,
а также изучение принципов создания хранимых процедур и триггеров, созданных преподавателем
или сгенерированных автоматически с помощью CASE-средства.
2.1. Формулировка задания
Задание на выполнение контрольной работы в минимальной формулировке заключается в следую-
щем.
2) Повторить цикл работ с учетом развития постановки задачи. А именно, спроектировать новую
схему базы данных и разработать офисное приложение для ее ведения. В офисном приложе-
нии желательно воспользоваться возможностями используемой СУБД для построения более
дружественного интерфейса.
Ниже дается пример выполнения задания с использованием СУБД MS Access (для 1-го цикла ра-
бот; для 2-го –аналогично). Подробное описание способов установки настроек приводится в примере
в учебных целях для первоначального ознакомления с техникой работы с СУБД. В отчете следует
привести укрупненную разбивку по шагам и описание разработок на этих шагах.
Контрольная работа может быть выполнена с использованием любой СУБД. Единственное огра-
ничение – это использование лицензионных программных продуктов.
2.2. Пример выполнения задания
2.2.1. Описание предметной области
Имеются постоянно действующие курсы переподготовки специалистов. Каждый специалист может
многократно (периодически) являться слушателем курсов (курсы отражают последние достижения
в рассматриваемой области и периодически обновляются). Под слушателем понимается специалист,
заявленный на периодическое слушание курсов и однозначно характеризуемый номером удостовере-
ния (УдостНомер).
Разработать приложение для ведения базы.
2.2.2. Шаг 0
Создать новую базу данных dbВедомость.
2.2.3. Шаг 1
Создать (в режиме конструктора) простые (то есть без подстановок) таблицы.
tblСлушатели (keyСлушатель, Фамилия, Имя, Отчество, УдостНомер)
Ясно, что поле УдостНомер здесь является альтернативным ключевым полем. Причины введения
суррогатного ключа keyСлушатель обусловлены естественным нежеланием использовать семанти-
чески интерпретированные поля в качестве первичных ключей.
Ввести в таблицу (не по алфавиту) несколько записей для тестирования. Задать для таблицы
следующий порядок сортировки: Фамилия, Имя, Отчество, УдостНомер.
Проконтролировать правильность установленного порядка сортировки можно, открыв в режиме
конструктора с помощью контекстного меню окно Свойства таблицы.
tblПредметы (keyПредмет, Наименование).
• Наименование:
• Ф, И, О:
Проблема однофамильцев может быть решена путем искусственного добавления некоторой иден-
тифицирующей информации к фамилии (например, «Иванов, ст.», «Иванов, мл.» и т.п.).
Ввести в таблицу (не по алфавиту) несколько записей для тестирования. Задать для таблицы
следующий порядок сортировки: Фамилия, Имя, Отчество.
Проконтролировать правильность установленного порядка сортировки можно, открыв в режиме
конструктора с помощью контекстного меню окно Свойства таблицы.
tblОценки (Оценка, Наименование).
Поскольку для отдельных предметов экзамен может быть не предусмотрен (и требуется лишь
прослушивание курса), в данной таблице следует ввести псевдооценку 0 с пустым наименованием.
Таблицу tblОценки сформировать полностью (рис. 2.1).
Рис. 2.1.: Таблица tblОценки
2.2.4. Шаг 2
Создать (в режиме конструктора) вспомогательные запросы для использования как списков подста-
новки в сложных таблицах.
subСлушатели (keyСлушатель, ФИО_УдостНомер) – сортировка по алфавиту. Здесь ФИО_УдостН
– единое поле в формате «Фамилия И.О. (УдостНомер)». Поле ФИО_УдостНомер определяется в
построителе в виде следующего выражения:
ФИО_УдостНомер: tblСлушатели!Фамилия+’ ’+
Left(tblСлушатели!Имя;1)+’.’+
Left(tblСлушатели!Отчество;1)+’.(’+
LTrim(Str(tblСлушатели!УдостНомер))+’)’
subПредметы (keyПредмет, Наименование) – сортировка по алфавиту;
subПреподаватели (keyПреподаватель, ФИО) – сортировка по алфавиту. Здесь ФИО – еди-
ное поле в формате «Фамилия И.О.». Поле ФИО определяется в построителе в виде следующего
выражения:
ФИО: tblПреподаватели!Фамилия+’ ’+
Left(tblПреподаватели!Имя;1)+’.’+
Left(tblПреподаватели!Отчество;1)+’.’
2.2.5. Шаг 3
Создать (в режиме конструктора) сложную (то есть с подстановками) таблицу tblВедомость со
следующими полями:
• keyСлушатель:
– с подстановкой subСлушатели,
– свойство Значение по умолчанию – отсутствует,
– свойство Обязательное поле – «Да»;
• keyПредмет:
– с подстановкой subПредметы,
– свойство Значение по умолчанию – отсутствует,
– свойство Обязательное поле – «Да»;
• Оценка:
– с подстановкой tblОценки;
• keyПреподаватель:
– с подстановкой subПреподаватели,
– свойство Значение по умолчанию – отсутствует,
– свойство Обязательное поле – «Да»;
• Дата:
Ввести в таблицу (не по алфавиту) данные для тестирования. Задать для таблицы следующий
порядок сортировки: keyСлушатель, Дата (фактически сортировка будет проводиться по полям
ФИО_УдостНомер, Дата).
Проконтролировать правильность установленного порядка сортировки можно, открыв в режиме
конструктора с помощью контекстного меню окно Свойства таблицы.
2.2.6. Шаг 4
Создать схему данных (установить межтабличные связи и обеспечить целостность данных; для связи
с таблицей tblСлушатели установить флажок каскадного удаления связанных полей; рис. 2.2).
Протестировать связи:
1) убедиться, что при удалении записи из таблицы tblСлушатели автоматически удаляются
соответствующие записи из таблицы tblВедомость;
2.2.7. Шаг 5
Создать (с помощью мастера) на основе таблицы tblСлушатели форму frmСлушатели (в лен-
точном виде, без показа ключевого поля). Для полей ввода из области данных установить свойство
Оформление как «обычное». В свойствах формы запретить разделительные линии и задать подпись
«Список слушателей». Протестировать ввод данных в форму.
2.2.8. Шаг 6
Создать (с помощью мастера) на основе таблицы tblПредметы форму frmПредметы (в ленточном
виде, без показа ключевого поля). Для поля ввода из области данных установить свойство Оформле-
ние как «обычное». В свойствах формы запретить разделительные линии и задать подпись «Список
предметов». Протестировать ввод данных в форму.
2.2.9. Шаг 7
Создать (с помощью мастера) на основе таблицы tblПреподаватели форму frmПреподаватели
(в ленточном виде, без показа ключевого поля). Для полей ввода из области данных установить
свойство Оформление как «обычное». В свойствах формы запретить разделительные линии и задать
подпись «Список преподавателей». Протестировать ввод данных в форму.
2.2.10. Шаг 8
Создать форму frmВедомость (по предметам). Для этого:
1) создать (с помощью мастера) на основе таблицы tblПредметы форму frmВедомость (в один
столбец, без показа ключевого поля);
2) в режиме конструктора в область данных формы вставить с панели элементов подчиненную
форму на основе таблицы tblВедомость (без показа ключевого поля);
3) отредактировать главную форму:
• задать подпись «Ведомость успеваемости по предметам»;
• запретить удаление и добавление записей;
• сделать поле наименования предмета доступным только для чтения, для чего задать для
его свойства Блокировка значение «Да»;
• изменить подпись для надписи «Наименование» на «Предмет»;
• удалить с формы надпись «подчиненная форма . . . »;
• скрыть столбец keyПредмет в подчиненной форме;
4) отредактировать подчиненную форму:
• задать режим по умолчанию «Режим таблицы»;
• отменить показ кнопок перехода;
• изменить наименования столбцов «keyСлушатель» и «keyПреподаватель» на «Слушатель»
и «Преподаватель»;
• установить тот же порядок сортировки, что и в таблице tblВедомость (можно скопиро-
вать свойство Порядок сортировки через буфер обмена).
Протестировать ввод данных в форму.
2.2.11. Шаг 9
Создать форму frmДиаграмма с диаграммой «Число оценок - Оценка» (по предметам). Предва-
рительно создать (в режиме конструктора) запрос qryДиаграмма (ПредметаНаименование,
ОценкиНаименование, Оценка) (рис. 2.3).
Поле ОценкиНаименование определить в построителе в виде следующего выражения:
ОценкиНаименование: LTrim(Str(tblОценки!Оценка))+
’-’+tblОценки!Наименование
Затем создать с помощью мастера диаграмм на основе запроса qryДиаграмма форму frmДиаграмма
(тип диаграммы – гистограмма, название диаграммы – «Распределение числа оценок по предметам»;
рис. 2.4).
Оптимизировать размеры диаграммы и в свойствах формы задать подпись «Диаграмма», запре-
тить разделительные линии, отменить показ кнопок перехода. Отредактировать диаграмму (переход
в режим редактирования – двойным щелчком; доступ к параметрам форматирования элементов
диаграммы – с помощью контекстного меню):
1) для шкалы вертикальной оси (значений) снять автоматическую установку цены основных де-
лений и установить ее в 1;
2) в параметрах диаграммы на вкладке Линии сетки задать режим вывода основных линий и для
оси категорий.
Рис. 2.3.: Запрос qryДиаграмма
Рис. 2.4.: Мастер диаграмм
Рис. 2.5.: Запрос qryОтчет
2.2.12. Шаг 10
Создать отчет rptОтчет (по предметам). Предварительно создать (в режиме конструктора) запрос
qryОтчет (рис. 2.5).
Поля определить следующим образом:
• Слушатель – subСлушатели!ФИО_УдостНомер;
• Предмет – subПредметы!Наименование;
• Оценка – tblОценки!Оценка;
• Преподаватель –subПреподаватели!ФИО;
• Дата – tblВедомость! Дата.
Затем создать (с помощью мастера) на основе запроса qryОтчет отчет rptОтчет (с группиров-
кой по предметам, с сортировкой по слушателям и дате, в макете «блок», в стиле «Обычный»).
Отредактировать отчет (в режиме конструктора):
• в окне Сортировка и группировка (вызывается через аналогичный пункт контекстного меню)
задать для свойства Примечание группы значение «Да»;
• вставить с панели элементов элемент Поле в область примечания группы (под полем Оценка),
настроить размеры поля и области группы;
• задать для надписи подпись «В среднем:»;
• определить для поля свойство Данные как «=Avg(Оценка)».
Отредактировать разделительные линии, установив для них свойство Тип границы в состояние
«Сплошная».
Установить для заголовка отчета подпись «Ведомость успеваемости по предметам» и выравнивание
по центру.
Отредактировать в области данных поле Слушатель, установив свойство Не выводить повторы в
состояние «Да».
Отредактировать в области данных поле Оценка:
• установить свойство Выравнивание текста в состояние «По центру»;
• установить для свойства Формат поля значение «#» (для подавления нулевых значений);
2.2.13. Шаг 11
Создать форму frmВедомостьСводная со сводной ведомостью. Предварительно создать (в режиме
конструктора) запрос qryВедомостьСводная (рис. 2.6) с полями
• Слушатель – subСлушатели!ФИО_УдостНомер;
• Предмет – subПредметы!Наименование;
Затем создать с помощью мастера перекрестных запросов на основе созданного запроса qryВедомостьС
перекрестный запрос crsВедомостьСводная (заголовки строк – по полю Слушатель, заголовки
столбцов – по полю Предмет, вычисление оценки – по максимуму поля Оценка). На основе запроса
crsВедомостьСводная создать (с помощью мастера) форму frmВедомостьСводная (в ленточ-
ном виде). Отредактировать форму. В частности, задать подпись «Сводная ведомость успеваемости».
2.2.14. Шаг 12
Создать меню для управления формами и отчетами приложения. Установить необходимые параметры
запуска.
Рис. 2.6.: Запрос qryВедомостьСводная
• Создать пустую панель управления Настраиваемая Главная типа «Панель инструментов». Для
этого вызвать окно Настройка (меню Вид Панели инструментов Настройка); на вкладке
Панели инструментов нажать кнопку Создать и задать имя Настраиваемая Главная.
Примечание. Тренинг: варианты закрепления панели (перетаскиванием, двойным щелчком);
закрытие и открытие панели (флажок панели инструментов Настраиваемая Главная окна На-
стройка).
• Изменить тип панели управления Настраиваемая Главная на тип «Строка меню» (окно На-
стройка, Свойства).
• Создать подменю Формы и Отчеты. Для этого в окне Настройка во вкладке Команды выбрать
категорию Новое меню и (дважды) перетащить команду Новое меню на панель. переименовать
подменю (в контекстном меню соответствующего подменю - непосредственно или в свойствах).
• Добавить команды в подменю Формы и Отчеты. Для этого в окне Настройка во вкладке
Команды выбрать категорию Все формы или Все отчеты и перетащить команды в подменю.
Примечание. Тренинг: создание команд меню перетаскиванием объектов непосредственно из
окна базы данных (окно Настройка должно быть закрыто); перестановка команд (перетас-
киванием при открытом окне Настройка); группирование команд, т.е. создание разделителей
между группами (откройте контекстное меню первой команды группы); выбор значков для
команд (откройте контекстное меню команды).
Для отключения параметров запуска при открытии базы данных удерживайте в нажатом положе-
нии клавишу SHIFT.
2.3. Варианты контрольных работ
2.3.1. Страховая компания
Описание предметной области
Вы работаете в страховой компании. Вашей задачей является отслеживание финансовой деятель-
ности компании. Компания имеет различные филиалы по всей стране. Каждый филиал характери-
зуется названием, адресом и телефоном. Деятельность компании организована следующим образом:
к Вам обращаются различные лица с целью заключения договора о страховании. В зависимости
от принимаемых на страхование объектов и страхуемых рисков, договор заключается по определен-
ному виду страхования (например, страхование автотранспорта от угона, страхование домашнего
имущества, добровольное медицинское страхование). При заключении договора Вы фиксируете дату
заключения, страховую сумму, вид страхования, тарифную ставку и филиал, в котором заключался
договор.
Таблицы
Договоры (Номер договора, Дата заключения, Страховая сумма, Тарифная ставка, Код
Вид страхования (Код вида страхования, Наименование).
Филиал (Код филиала, Наименование филиала, Адрес, Телефон).
Книги (Код книги, Название, Автор, Залоговая стоимость, Стоимость проката, Жанр)
Читатели (Код читателя, Фамилия, Имя, Отчество, Адрес, Телефон).
Выданные книги (Код книги, Код читателя, Дата выдачи, Дата возврата).
Ценные бумаги (Код ценной бумаги, Минимальная сумма сделки, Рейтинг, Доходность
Инвестиции (Код инвестиции, Код ценной бумаги, Код клиента, Котировка, Дата поку
Клиенты (Код клиента, Название, Вид собственности, Адрес, Телефон).
Торговые точки (Код торговой точки, Этаж, Площадь, Наличие кондиционера, Стоимос
Клиенты (Код клиента, Название, Реквизиты, Адрес, Телефон, Контактное лицо).
Аренда (Код аренды, Код торговой точки, Код клиента, Дата начала, Дата окончания
Модуль 1
3. Реляционная алгебра
3.1. Отсутствующие данные
Проблема отсутствующих данных довольно часто встречается в реальной жизни. Например, в ис-
торических записях встречаются такие записи, как «Дата рождения неизвестна»; в повестке дня
собрания часто докладчик «указан» в виде «Будет объявлен»; милицейские доклады могут включать
такие записи, как «номер автомобиля неизвестен».
Для решения проблемы представления отсутствующих данных был предложен подход, основанный
на использовании специального маркера, соответствующего понятию неопределенных значений и
называемого null-значением (будем произносить «нул-значение» вместо «нал-значение»).
В различных источниках на неопределенное значение, то есть на null-значение, часто ссылаются
как на «пустое значение» или «нулевое значение». Однако нулевое значение, то есть число 0 –
это пустое значение для числовых типов данных, а понятия пустого и неопределенного значений
принципиально различаются. Поэтому необходимо обращать внимание на контекст употребления
этих терминов.
Вначале рассмотрим понятие пустого значения.
3.2. Пустые значения
Пустое значение – это просто одно из возможных значений определенного типа данных, названное
пустым. Естественными пустыми значениями, например, являются
• строка из пробелов, знаков табуляции и других неотображаемых символов для строк символов
постоянной длины.
Не всем типам данных можно естественным образом сопоставить пустое значение. Например, ка-
кое значение можно назвать пустым для данных типа даты, если в СУБД поддерживается диапазон
представления дат от 01.01.0100 до 31.12.9999? В некоторых СУБД в подобных случаях вводится
специальное обозначение для константы пустого значения. Так, например, для пустого значения да-
ты может вводиться специальное обозначение {..}, а непустые константы представляться в формате
{ДД.ММ.ГГГГ}. Если понятие пустого значения введено для всех типов данных, поддерживаемых
СУБД, то тогда появляется возможность использования оператора вставки в таблицу строки пустых
значений:
Значения по умолчанию задаются для каждого столбца при создании таблицы. В частности, в
качестве значения по умолчанию можно задать и пустое значение. Поэтому единственная цель, с
которой выше вводилось понятие пустого значения – это показать отличие понятия пустого значения
от понятия неопределенного значения.
3.3.1. Интерпретации
Null-значения допускают следующие интерпретации:
2) значение неприменимо.
Паспортные данные
№ пп Фамилия . . . Г.р. № паспорта Интерпретация
1 Иванов 1980 null неизвестно
2 Петров 2000 null неприменимо
3 Сидоров null null ???
null-значению номера паспорта, поскольку год рождения имеет null-значение (интерпретируемое как
неизвестное). Кроме того, с течением времени интерпретация null-значения номера паспорта во 2-ом
случае изменится.
Таким образом, интерпретация null-значений существенно зависит от семантики данных. Правила
вычисления выражений с null-значениями, реализованные в СУБД, следует рассматривать лишь как
правила, действующие в системе по умолчанию.
(1 + 2) × x2 ⇒ (1 + 2) × 32 ⇒ 3 × 32 ⇒ 3 × 9 ⇒ 27
2) Как общее правило, результат выполнения отдельной операции с null-значением в качестве
операнда считается null-значением. Например, при x, имеющим null-значение, имеем
Здесь символ подстановки «:=» разделяет список выражений и значение, которым они мо-
гут быть заменены. Таким образом, законы поглощения имеют место при любых значениях
операнда, в том числе и при значении null:
f alse and null ⇒ null and f alse := f alse, true or null ⇒ null or true := true
3.3.3. Следствия
К каким следствиям приводят правила? Следствием является нарушение привычных законов вычис-
лений. В частности, для операций арифметических, логических, строковых и сравнения имеем при
null-значении операнда x. Следовательно, число нуль уже не является поглощающим элементов для
Таблица 3.2.: Таблица истинности
x not x x y x and y x or y
false false false false
false true false null false null
false true false true
null false false null
null null null null null null
null true null true
true false false true
true false true null null true
true true true true
Таблица 3.3.: Операции с null-значением
операции умножения, закон исключенного третьего уже не имеет места, отношение равенства не
рефлексивно и нельзя сказать, равно или нет null-значение самому себе.
Таким образом, null-значение не является значением в обычном смысле этого слова и непосред-
ственное сравнение выражения с null-значением невозможно, так как при любых значениях операнда
x в результате сравнения будет получено null-значение.
Как проверить значение переменной или выражения на null-значение? Следует использовать спе-
циальный встроенный предикат IsNull(выражение) – «есть null». Предикат возвращает значение
false или true (но не null) и может применяться к выражению любого типа, например
Ясно, что применительно к пустым значениям предикат IsNull всегда возвращает значение false.
Таблица 3.4.: Предикат IsNull
IsNull(Выражение) Значение
IsNull(0) false
IsNull(x + ’abc’ + null) true
IsNull(2 × null) true
2) Порядок строк в теле таблицы должен быть несущественным. Это требование также не явля-
ется ограничительным, поскольку при необходимости можно ввести дополнительный столбец,
определяющий порядок строк.
3) Среди строк тела таблицы не должно быть дубликатов (в теории). Это требование не являет-
ся ограничительным, поскольку при необходимости можно ввести дополнительный столбец с
данными о числе дубликатов строк.
Примечание. Данное требование приводит к построению реляционной алгебры, в которой отноше-
ния (таблицы) рассматриваются как множества кортежей (строк тела таблицы). Если рассматривать
отношения как мультимножества кортежей (в мультимножествах дубликаты элементов допускаются
и поэтому можно говорить не только о вхождении элемента в мультимножество, но и о числе этих
вхождений), то это привело бы к построению так называемой псевдореляционной алгебры. Даже ес-
ли в исходном состоянии база данных не содержит отношений с дубликатами кортежей, то все равно
дубликаты могут появиться в результирующих запросах. В этом смысле на практике реализуется как
бы псевдореляционная алгебра. Однако операторы языка SQL, реализующие запросы с потенциальной
возможностью появления дубликатов кортежей, имеют специальные опции, позволяющие управлять
исключением дубликатов •
4) Данные в столбце должны быть одного и того же и, что принципиально важно, простого
типа. Это требование лежит в основе всех принципов проектирования и реализации (чисто)
реляционных баз данных.
Примечание. Простой тип данных – это тип, значения данных которого не содержат составных частей.
Таким образом, данные в столбце не должны быть ни списками, ни массивами, ни деревьями, ни тому
подобными составными объектами. Составные объекты в реляционной модели сами представляются в
виде множества взаимосвязанных таблиц. Еще раз подчеркнем, что это требование относится к чисто
реляционной модели данных. СУБД с расширениями это требование могут не выдвигать, но тогда они
должны иметь и соответствующие механизмы доступа к подобъектам таких составных объектов •
1) перечислением значений,
2) характеристическим предикатом,
3) порождающей процедурой.
3.4.6. Отношение
Отношение r ≡ r(S) = {t(S) | t ∈ r} со схемой отношения S определяется как конечное множество
кортежей со схемой S. Количество кортежей в отношении называется мощностью отношения и обо-
значается как мощность множества |r|. В табличной форме представления отношению соответствует
тело таблицы.
Отношение со схемой S может быть пустым, и тогда для него необходимо использовать расши-
ренную форму обозначения ∅(S). Это обозначение совпадает с обозначением нигде не определенного
кортежа и, следовательно, интерпретация обозначения должна определяться по контексту.
Сравнимыми считаются отношения с одной и той же схемой.
В следующих случаях отношение называется
2) |r[S 0 ]| 6 |r|
3) |ρhσir| = |r|
2) r1 ⊆ r2 ⇒ r1 [S 0 ] ⊆ r2 [S 0 ]
3) r1 ⊆ r2 ⇒ ρhσir1 ⊆ ρhσir2
3) |r1 \ r2 | ≤ |r1 |
(1) r1 (S1 )
(2) r2 (S2 )
(3) r3 (S1 ∪ S2 ) := r1 (S1 ) ×P r2 (S2 )
(4) r4 (S1 ) := r3 (S1 ∪ S2 )[S1 ]
(5) r5 (S1 ) := r1 (S1 ) \ r4 (S1 )
(6) r6 (S2 ) := {∅(S2 )}
(7) r7 (S1 ∪ S2 ) := r5 (S1 ) × r6 (S2 )
(8) r8 (S1 ∪ S2 ) := r3 (S1 ∪ S2 ) ∪ r7 (S1 ∪ S2 )
Здесь (1) – левый операнд, (2) – правый операнд, (3) – их внутреннее соединение, (4) – соеди-
нимые кортежи левого операнда, (5) – несоединимые кортежи левого операнда, (6) – отношение
со схемой S2 , содержащее один кортеж, состоящий из null-значений, (7) – несоединимые корте-
жи левого операнда, дополненные null-значениями на схеме правого операнда, (8) – левое внешнее
соединение.
Таким образом, операции левого и правого внешних соединений по заданному условию соедине-
ния P (обозначения операций L ×P и R ×P соответственно, мнемоника от Left и Right) определяются
следующим образом:
r1 (S1 )L ×P r2 (S2 ) = (r1 ×P r2 ) ∪ [(r1 \ (r1 ×P r2 )[S1 ]) × {∅(S2 )}] = r2 (S2 )R ×P r1 (S1 )
r1 (S1 )R ×P r2 (S2 ) = (r1 ×P r2 ) ∪ [(r2 \ (r1 ×P r2 )[S2 ]) × {∅(S1 )}] = r2 (S2 )L ×P r1 (S1 )
Основным свойством этих операций является возможность восстановления операнда по результату
соединения:
r1 (S1 ) = (r1 L ×P r2 )[S1 ], r2 (S2 ) = (r1 R ×P r2 )[S2 ]
Операция полного внешнего соединения по заданному условию соединения P (обозначение опе-
рации F ×P , мнемоника от Full) определяется как результат пополнения внутреннего соединения
кортежами и левого, и правого операндов:
r1 (S1 ) F ×P r2 (S2 ) = (r1 L ×P r2 ) ∪ (r1 R ×P r2 ) = r2 (S2 ) F ×P r1 (S1 )
Примеры для операций внутреннего и внешних соединений с условием соединения P = (B1 = B2 )
для исходных отношений (рис. 3.5) приведены на рис 3.6, 3.7. Из примера видно, что по результату
полного внешнего соединения операнды могут быть восстановлены, но с точностью до возможного
появления нигде не определенного кортежа.
Решение. По условию задания в отношении Детали могут быть детали с различными кодами
КодД, но одним и тем же родовым именем РодД.
Применим линейную форму представления запроса в виде набора операторов присваивания.
Образуем естественное соединение всех отношений:
hD+ ; σ, π, ρ, ∪, ∩, \, ×, ./i
Таким образом, исходя из отношений D, хранимых в базе данных, можно получить в результате
запроса отношение не только из D, но и из D+ \ D. Но в базе данных хранятся отношения двух
видов – базовые (обозначим D0 ) и виртуальные (обозначим D1 ). (Ясно, что D0 ∩ D1 = ∅, D0 ∪
D1 = D). Базовые отношения содержат независимые данные и не могут быть выражены через
другие отношения базы данных. В СУБД базовые отношения обычно называются таблицами (table).
Виртуальные отношения выражаются в конечном итоге через базовые и (на логическом уровне)
хранятся в базе данных в виде выражений реляционной алгебры. В СУБД виртуальные отношения
обычно называются представлениями (view). Реально они реализуются на языке SQL.
3.8. Понятие полноты реляционной алгебры
Сигнатура реляционной алгебры, так, как она была введена выше, содержала операции, производные
от других операций, и в этом смысле была избыточной. Однако на практике производные операции
полезны, так как позволяют в более компактной форме представлять выражения.
Важен другой вопрос: а достаточно ли этих операций для выражения практически значимых за-
просов? Действительно, если из сигнатуры алгебры исключить операции типа произведения (× и ./),
то в результате запроса, формулируемого в виде выражения реляционной алгебры над отношения-
ми базы данных с оставшимися операциями (σ, π, ρ, ∪, ∩, \) могут быть получены результирующие
отношения со схемами, с точностью до переименования атрибутов являющимися подмножествами
или совпадающими со схемами исходных отношений. Такого ограниченного набора операций для
практики явно не достаточно. Возникает вопрос о полноте набора операций реляционной алгебры.
Если проанализировать определения операций реляционной алгебры, то можно заметить, что все
они с точностью до обозначений определяются в виде выражений вида «множество кортежей над
такой-то схемой, удовлетворяющих такому-то предикату»:
{t(S) | f (t)}
Здесь f – некоторый предикат над переменным кортежем t. Это выражение обозначает отношение
r(S), которое состоит из всех кортежей t(S), для которых f (t) истинно.
Можно задаться вопросом, не будут ли получены новые запросы-отношения из базы данных, если
в качестве предиката f в таких выражениях использовать произвольный предикат, включающий
логические связки ∀ (квантор общности, или всеобщности), ∃ (квантор существования) и ¬, &, ∨
(отрицание, конъюнкция, дизъюнкция)? (Такие выражения с произвольным предикатом f , выра-
женным в элементарных высказываниях, использованных при определении операций реляционной
алгебры, называются выражениями исчисления кортежей.) Можно показать, что нет.
Таким образом, полнота реляционной алгебры понимается в том смысле, что система запросов,
построенная на основе реляционной алгебры (запрос – это выражение реляционной алгебры над
множеством отношений базы данных D), приводит к тому же множеству допустимых запросов D+ ,
что и система запросов, построенная на основе исчисления кортежей (запрос – это выражение
исчисления кортежей над D).
select *
from УспеваемостьОперации левого, правого и полного внешних соединений
where NЗК = 100 and Семестр = 6
Условие выборки может содержать предикаты в следующих формах:
1. выражение {< | <= | = | < > | >= | >} выражение;
2. выражение [not] between выражение1 and выражение2;
3. выражение is [not] null;
4. строковое_выражение [not] like шаблон [escape ‘escape_символ’];
5. выражение [not] in (выражение,..);
6. выражение [not] in (подзапрос);
7. выражение {< | <= | = | < > | >= | >} {all | any} (подзапрос);
8. exists (подзапрос).
1-я форма предиката применяется для выражений любого типа, за исключением BLOB – крупных
двоичных объектов.
2-я форма предиката с оператором [not] between (между) является сокращением следующего
условия:
[not] (выражение1 <= выражение and выражение <= выражение2)
3-я форма предиката предназначена для тестирования null-значений.
4-я форма предиката с оператором like (похожий) позволяет отбирать строки по шаблону с ис-
пользованием следующих символов замещения.
Символ 1. % (процент) – любая строка из нуля или более символов. Например, конструкция like
‘%t%’ соответствует любым строкам, содержащим хотя бы один символ ‘t’.
Символ 2. _ (подчеркивание) – любой одиночный символ. Например, конструкция like ‘a_’ соот-
ветствует двухсимвольным строкам, начинающимся с символа ‘a’.
Символ 3. [символ-символ], либо [символ. . . ] – любой одиночный символ, содержащийся в ука-
занном диапазоне или последовательности символов. Например, конструкция like ‘[b-d]at’, как и like
‘[bcd]at’, соответствует строкам ‘bat’, ‘cat’, ‘dat’. Конструкции like ‘[ [ ]’ соответствует символ ‘[’.
Символ 4. [ b символ-символ], либо [ b символ. . . ] – любой одиночный символ, не содержащийся
в указанном диапазоне или последовательности символов. Например, конструкция like ‘[ b 0-9]%’
соответствует любым строкам, первый символ которых не является цифрой.
Если символ замещения ‘%’ или ‘_’ необходимо сам по себе включить в шаблон, то следует или
заключить его в квадратные скобки, или определить escape-символ (то есть символ перехода) и
использовать его перед символом замещения. Например, следующие конструкции соответствуют
двухсимвольным строкам, начинающимся с символа подчеркивания:
like ’[_]_’
like ’/_ _’ escape ’/’
like ’!_ _’ escape ’!’
5-я форма предиката соответствует предикату принадлежности элемента списку.
6-я форма предиката отличается от 5-й тем, что вместо списка задается подзапрос, возвращающий
один столбец (но не одну строку, так как требуется однотипность данных). Например, следующий
запрос выводит список студентов, получивших к моменту запроса хотя бы одну оценку отлично:
Студенты(NЗК, Ф, И, О)
Сессия (NЗК, Предмет, Оценка)
select *
from Студенты
where NЗК in (select NЗК from Сессия where Оценка = 5)
Здесь в результирующем запросе поля из таблицы Сессия не используются и поэтому можно
использовать подзапрос, а не соединение.
7-я форма предиката позволяет сравнивать выражения со всеми (all) или некоторыми (any) значе-
ниями, возвращаемыми в подзапросе. В частности, следующие предикаты эквивалентны:
выражение in (подзапрос)
выражение = any (подзапрос)
8-я форма предиката проверяет подзапрос на пустоту. С помощью этого предиката последний
пример может быть записан в виде
Студенты(NЗК, Ф, И, О)
Сессия (NЗК, Предмет, Оценка)
select *
from Студенты
where exists(select * from Сессия where NЗК = Студенты.NЗК and Оценка = 5)
Здесь подзапрос является примером так называемого коррелированного подзапроса, поскольку
условие выборки в подзапросе зависит от текущей анализируемой записи внешнего запроса.
Указывать конкретные столбцы в подзапросе предиката exists смысла не имеет.
Операция проекции
Операция проекции реализуется оператором
select [distinct] список_имен_атрибутов
from имя_отношения
Здесь необязательная опция distinct задает режим исключения дубликатов кортежей. Если ре-
зультат проекции гарантированно не содержит дубликатов кортежей или дубликаты допустимы, то
из соображений производительности опцию distinct лучше не указывать, например
Здесь первые три возвращаемые атрибута образуют ключ отношения. Поэтому опция distinct ста-
новится излишней. Запрос возвращает исходное отношение Успеваемость, в котором опущен атрибут
Дата.
Операция проекции
Операция переименования атрибутов заключается в добавлении ключевого слова as и нового
имени атрибута после исходного имени атрибута в списке имен атрибутов фразы select, например
Операция объединения
Операция объединения реализуется с помощью операции union, применяемой к базовым операторам
select:
select список_имен_атрибутов_отношения_1
from имя_отношения_1
union [all]
select список_имен_атрибутов_отношения_2
from имя_отношения_2
Операция пересечения
Операция пересечения проще всего реализуется с использованием ключей отношений:
select *
from R1
where Ключ in (select Ключ from R2)
Здесь R1 и R2 – имена отношений. Оператор select в скобках является так называемым подза-
просом. Он возвращает список значений ключа отношения R2. Согласно условию выборки в резуль-
тирующее отношение выбираются те кортежи отношения R1, ключ которых содержится в списке
ключей отношения R2. Имена ключей отношений могли бы быть и различными. Сами отношения
могли бы иметь различные наборы дополнительных атрибутов.
Операция разности
Операция разности реализуется аналогично операции пересечения с заменой ключевого слова in
на not in:
select *
from R1
where Ключ not in (select Ключ from R2)
select *
from R1 cross join R2
Здесь предполагается, что отношения не имеют совпадающих имен атрибутов. В противном случае
потребовалось бы с помощью переименования атрибутов разрешить коллизию имен, например,
Здесь ссылаться на общие атрибуты B и C просто по именам нельзя, так как будет неясно, к како-
му отношению они относятся. Использованная формулировка условия соединения (после ключевого
слова on) предполагает, что общие атрибуты соединяемых отношений null-значений не допускают.
Операции левого, правого и полного внешних соединений реализуются аналогичным образом с
заменой ключевого слова inner на left outer, right outer и full outer соответственно.
3.9.2. Пример использования подзапросов
Практическое задание. Имеется следующий фрагмент базы данных:
Предметы(КодП, ИмяП)
Студенты(NЗК, Ф, И, О, ...)
Сессия (КодП, NЗК, Оценка)
Решение. Используем функцию RTrim(строка), которая возвращает строку без концевых пробе-
лов, и функцию Left(строка, число) которая возвращает заданное число символов левой части стро-
ки.
select Студенты.NЗК,
RTrim(Ф) + ’ ’ + Left(И,1) + ’.’ + Left(О,1) + ’.’ as ФИО,
Оценка
from Студенты inner join
(
select NЗК, Оценка
from Сессия
where КодП = (select КодП from Предметы where ИмяП = ’БД’)
) as СессияБД
on Студенты.NЗК = СессияБД.NЗК
Внутренний подзапрос (select КодП from Предметы where ИмяП = ’БД’) может возвра-
щать не более одного значения, так как атрибут ИмяП является кандидатным ключом отношения
Предметы. В запросе, которому присвоен псевдоним СессияБД, этот подзапрос позволяет выделить
из отношения Сессия те кортежи, которые относятся к рассматриваемому предмету. Внутреннее со-
единение отношения Студенты с запросом СессияБД по условию равенства номера зачетной книжки
добавляет к отношению Студенты оценку. Так как атрибуты Ф, И, О студента не допускают null-
значений и не являются пустыми, то формула вычисления возвращаемого атрибута ФИО не требует
соответствующих проверок и упрощается.
1. count(*)
2. { count | sum | avg | min | max} ([all | distinct] выражение_над_столбцами)
Функции применяются к группам строк и возвращают для каждой из групп единственное значе-
ние.
Функция count(*) возвращает общее количество кортежей в группе. Остальные функции приме-
няются к выражению над столбцами, то есть к столбцу значений, полученных из группы строк
при вычислении выражения для каждой из строк. Null-значения в столбце значений игнорируются.
Опция all действует по умолчанию и означает учет дубликатов строк. Если указана опция distinct,
то дубликаты строк игнорируются. Эти опции значимы для функций подсчета числа строк, сумми-
рования и осреднения, но не для функций экстремальных значений.
Результат осреднения целочисленных значений округляется до целого. Поэтому в этом случае
может потребоваться использование функции явного преобразования типов. Приведем пример вы-
числения средней оценки по всем предметам в целом:
Фраза having ограничивает строки, возвращаемые фразой group by, таким же образом, как фраза
where ограничивает строки, возвращаемые фразой select. В один оператор select могут быть вклю-
чены и фраза where, и фраза having. При этом фраза where применяется до операции группировки,
а фраза having после нее.
Синтаксис фразы having идентичен синтаксису фразы where за исключением того, что фраза
having может включать функции агрегирования.
В следующем примере данные о суммарном балле выдаются для тех студентов, которые сдали 3
экзамена:
Для повышения производительности во фразу having имеет смысл включать лишь те условия, ко-
торые действительно требуют предварительные вычисления сгруппированных данных. В противном
случае условия следует размещать во фразе where.
• Что означает термин «пустое значение»? Укажите пустые значения для числовых типов данных,
логического, строк символов постоянной и переменной длины.
Неопределенные значения
• Дайте определение домена атрибута и атрибута. Какими способами можно задать домен?
• Дайте определение схемы отношения, кортежа и отношения. Что такое степень отношения?
• Какие операции реляционной алгебры являются потенциально опасными с точки зрения воз-
никновения дубликатов кортежей и почему?
• Как на языке SQL реализуется операция выборки? Предикаты в каких формах может содержать
условие выборки?
• Как на языке SQL реализуется операция проекции? Как задается режим исключения дублика-
тов кортежей?
• Как на языке SQL реализуется операция декартова произведения? Как разрешается коллизия
имен?
Модуль 2
4. Базовые и виртуальные отношения
4.1. Типы данных
Тип данных задает множество значений, объединенных определенной совокупностью допустимых
операций. От типа данных зависит размер выделяемой для значений памяти.
1. Числовые
• integer – целый,
• перечислимые типы,
• float(n), real – вещественный,
• decimal(n[, d]) – десятичный с фиксированной точкой,
• money, или currency – денежный.
2. Логический
• logical.
3. Строковые
4. Даты и времени
• date – дата,
• datetime – дата-время.
5. Идентификационные
• BLOB.
Целочисленный тип данных integer может иметь варианты, различающиеся по диапазону представ-
ления данных. Например, вариантами 4-байтового типа integer могут быть 8- и 2-байтовые типы
bigint и smallint соответственно.
Примечание. Аналогичные варианты могут иметь и другие типы данных – денежный, даты и времени,
идентификационный •
Тип, в объявлении которого указывается набор символических имен, называется перечислимым.
В качесве примера перечислимого типа можно назвать множество названий дней недели (пн, вт, ср,
чт, пт, сб, вс). Значения перечислимых типов представляются посредством целочисленных кодов с
использованием требуемого количества байтов.
Тип вещественных чисел float(n), real применяется для описания данных, которые нельзя точ-
но представить в компьютере. Вещественные числа (числа с плавающей точкой) представляются в
научной нотации, при которой число записывается с помощью мантиссы, умноженной на опреде-
ленную степень десяти (порядок), например: 10Е3, +5.2Е6, -0.2Е-4. Параметр n (точность) задает
количество хранимых бит мантиссы. Точность типа real зависит от конкретной реализации.
Тип decimal(n[, d]) – десятичный с фиксированной точкой с точностью в n десятичных цифр, из
которых d (при d > 0) – после десятичной точки, а при d < 0 – до десятичной точки (по умолчанию
d = 0). Например: ± 123.45 (d = 2 > 0, n = 5); ± 1234500. (d = - 2 < 0, n = 5).
Денежный тип money (в некоторых СУБД обозначаемый как currency) представляет числа в
денежном формате в очень широком диапазоне с фиксированной точностью от денежной единицы
(например, .0001).
Логический тип данных logical в некоторых СУБД подменяется типом bit(1).
Битовый тип данных используется для определения строк бит, то есть последовательностей дво-
ичных цифр, каждая из которых может иметь значение либо 0, либо 1. Типы bit(n), varbit(n)
соответствуют строкам бит фиксированной длины n и переменной длины, не превышающей n бит.
Последовательности бит обычно делятся на группы по 8 бит в каждой, которые упаковываются в
байты. Если n не делится на 8 нацело, неиспользуемые биты последнего байта игнорируются.
Строки символов состоят из последовательности символов, входящих в определенный создателя-
ми СУБД набор символов. Поскольку наборы символов являются специфическими для различных
диалектов языка SQL, перечень символов, которые могут входить в состав значений данных сим-
вольного типа, также зависит от конкретной реализации. Чаще всего используются наборы символов
ASCII и EBCDIC. Типы char(n), varchar(n) соответствуют строкам символов фиксированной длины
n и переменной длины, не превышающей n символов.
Поле, соответствующее типу char(n), представляет собой массив из n байтов в случае, если симво-
лы относятся к одному из традиционных 8-битовых наборов данных (скажем, ACSII или EBCDIC).
Символ Unicode представляется 16 битами, или двумя байтами. Если значением атрибута оказы-
вается более короткая строка, в каждую «лишнюю» позицию заносится специальный незначащий
символ, 8-битовый код которого не совпадает с кодом любого другого символа из числа тех, которые
разрешено включать в строки SQL.
SQL-тип varchar(n) на самом деле представляет поле фиксированной длины, хотя размер содер-
жимого может варьироваться. Существуют два общих способа представления строк типа varchar.
Способ 1 : длина плюс содержимое. Система организует массив из n+1 байт. В первом байте в
виде 8-битового целого числа сохраняется количество байтов в строке. Длина строки не может
превысить n, а величина n, в свою очередь, должна быть не больше значения 255 – в противном
случае длину строки нельзя представить с помощью одного байта. Второй и последующие
байты отображают символы содержимого строки. Если строка состоит их меньшего количества
символов, оставшиеся байты массива не могут интерпретироваться как часть содержимого и
игнорируются.
Способ 2 : строки, завершаемые незначащим символом. В этом случае также формируется массив
из n+1 байт. Массив заполняется символами строки, а в элемент, следующий за послед-
ним байтом содержимого строки, заносится незначащий символ. Как и в предыдущем случае,
оставшиеся байты массива игнорируются.
Типы date, time, datetime представляют значения дат и времени. Тип данных date используется
для хранения календарных дат, включающих поля год-месяц-день. Тип данных time – для хранения
отметок времени, включающих поля часы-минуты-секунды. Тип данных datetime – для совместного
хранения даты и времени.
Значения дат обычно представляются в виде символьных строк постоянной длины и принципи-
ально ничем не отличаются от обычных строк символов подобного формата. Временные величины
допускают аналогичное представление. В стандарте SQL, однако, предусмотрен и тип time, позволя-
ющий сохранять значения времени с точностью до дробных долей секунды. Формат значений time
относится к категории строк произвольной длины. Таким образом, имеются два альтернативных
средства описания значений времени. Во-первых, система способна ограничить точность представ-
ления временных величин, как если бы они относились к типу varchar(n), где n – максимально
допустимая длина строки с описанием значения времени. Во-вторых, временные значения могут
сохраняться и использоваться в виде строк действительно переменной длины.
Значения данных типа счетчика counter(x0 , 4x) являются целочисленными, но не задаются, как
для других базовых типов, а генерируются системой. Тип счетчика может быть задан лишь при
определении таблицы, причем лишь для одного столбца. В программном коде тип счетчика исполь-
зовать нельзя. Значения данных типа счетчика генерируются автоматически при вставке строк в
таблицы. Параметры x0 и 4x задают начальное значение и шаг приращения. Генерация проводится
без повторений, так что счетчик всегда будет уникально идентифицировать каждую строку. На-
пример, пусть в таблицу введены 4 строки. Удаление строк 2, 4 и добавление еще одной строки
приведет к следующему преобразованию исходной таблицы (рис. 4.1).
Изменить значение счетчика или объявить несколько счетчиков в одной таблице СУБД не позво-
лит. Уникальных значений 4-байтового счетчика при скорости генерации 1 знач/сек хватит на более
чем 100 лет:
Рис. 4.1.: Модификация таблицы со счетчиком
Счетчик обычно используется как суррогатный, то есть искусственный, первичный ключ табли-
цы.
BLOB – это обобщенное название типов данных, предназначенных для хранения крупных двоич-
ных объектов (Binary Large OBjects). Такими объектами могут быть графические изображения в
различных форматах, видеозаписи, звук, сигналы радаров и т.п. Для данных типа BLOB понятие
сравнения не определено.
4.1.2. Типы данных, определяемые пользователем
Далеко не все современные СУБД в полной мере поддерживают типы данных, определяемые
пользователем. СУБД Ingres включает такой механизм. Эта система предоставляет программи-
сту возможность определять собственные типы данных и операции над ними и использовать их
в операторах SQL. Для определения нового типа данных необходимо написать и откомпилировать
функции на языке СИ, после чего собрать редактором связей некоторые модули Ingres. Введение
новых типов данных является, по сути, изменением ядра СУБД. Важно и то, что в Ingres типы
данных, определяемые пользователем, могут быть параметризованными.
Определение нового типа данных сводится к указанию его имени, размера и идентификатора в
глобальной структуре, описывающей типы данных. Чтобы с новым типом данных можно было ис-
пользовать функции, которые реализуют стандартные операции (сравнение, преобразование в раз-
личные форматы, и т.д.), программист должен разработать их самостоятельно (интерфейс функций
предопределен). Указатели на эти функции являются элементами глобальной структуры. Как только
новый тип данных определен, то все операции выполняются над ним, как над данными стандартно-
го типа. Разрешение пользователю создавать собственные типы данных – один из шагов развития
реляционных СУБД в направлении объектно-реляционных систем.
Многие СУБД позволяют пользователю создавать пользовательские подтипы базовых типов (под-
типы данных, определяемые пользователем). В записи на псевдокоде пользовательский подтип
создается с помощью оператора
create subtype имя_подтипа
type имя_базового_типа
as ограничение
Ограничение подтипа записывается как условие, зависящее от имени определяемого подтипа, на-
пример:
create subtype ПочтовыйИндекс
type decimal(6, 0)
as ПочтовыйИндекс > 0
В общем случае ограничение подтипа может содержать логические связки not, and, or и быть вы-
ражением произвольной сложности. Определенные таким образом подтипы могут использоваться
наряду с другими базовыми типами и в программном коде, и при определении типа данных в столб-
цах таблиц. В визуальной среде разработки базы данных они появляются в списках допустимых
типов вместе с другими базовыми типами.
Пользовательский подтип данных может быть удален с помощью оператора
drop subtype имя_подтипа
Пользовательские подтипы данных рекомендуется вводить для подтипов достаточно общего назна-
чения. В противном случае лучше ограничение ввести при объявлении соответствующего атрибута
таблицы.
1) допустимо объявление не более одного первичного ключа, тогда как кандидатных ключей
может быть несколько;
2) атрибуты первичного ключа не могут принимать null-значений, тогда как для кандидатных
ключей это ограничение не обязано накладываться (но может).
При выборе первичного ключа следует отдавать предпочтение простым ключам или ключам, состав-
ленным из минимального числа атрибутов. Нецелесообразно также использовать ключи с длинными
текстовыми значениями, как, например (для блюда) – «Заяц в сметане с картофельными крокетами
и салатом из красной капусты». Но как же сослаться на такое блюдо в базе данных ресторана?
Просто нужно ввести словарь-справочник c двумя атрибутами, первый из которых – суррогатный
ключ типа счетчика, а второй – наименование, объявленное кандидатным ключом.
4.3. Индексы
Создание ключей (в развитых СУБД автоматически) связано с созданием индексов.
Простой или составной индекс для подсхемы из одного или нескольких атрибутов – это систем-
ная структура данных, в которой (по крайней мере, на логическом уровне) размещается упорядо-
ченный перечень значений индекса со ссылками на те кортежи базового отношения, в которых эти
значения встречаются.
Индексы могут быть уникальными и неуникальными, как показано на рис. 4.2 на примере пас-
портных данных (№ П – номер паспорта, Ф – фамилия). Здесь предполагается, что атрибут № П
– первичный ключ. Поэтому индекс для него является уникальным. Индекс атрибута Ф является
неуникальным.
Представим себе, что по заданному номеру паспорта требуется найти соответствующие паспорт-
ные данные (левая таблица, миллион записей). Последовательный просмотр записей этой таблицы
может привести к миллиону сравнений. Но в данном случае имеется структура Индекс № П. В
ней имеется упорядоченный список номеров паспортов с указанием на номера записей, содержащих
соответствующие паспортные данные. Поэтому можно применить алгоритм дихотомического поиска
Рис. 4.2.: Индексы
При объявлении базового атрибута в общем случае задаются его тип, ограничение значений,
флажок допустимости null-значений и значение по умолчанию. Тип и ограничение значений атрибута
определяют его домен. Ограничение значений атрибута записывается как условие (в общем случае
с логическими связками not, and, or), зависящее от имени атрибута, например,
update имя_таблицы
set {имя_столбца = новое_значение},..
[where условие]
Подобно оператору вставки insert, один оператор обновления update может модифицировать только
одну таблицу или одно представление. За ключевым словом set следует перечень имен подлежащих
обновлению столбцов с указанием их новых значений. Новое значение может быть константой или
выражением, которое также может ссылаться на сам столбец. Например, следующий оператор будет
уменьшать значения в столбце Цена на 10%:
update Товары
set Цена = Цена * 0.90
Фраза where не является обязательной. Если она указана, то должна задавать строки, подлежащие
обновлению. Если фраза where отсутствует, то будут обновляться все строки.
Необязательная фраза where дает возможность отбирать удаляемые строки. Если эта фраза опущена,
то будут удалены все строки в указанной таблице.
Все строки таблицы могут быть удалены одновременно с помощью оператора
Это оператор отличается от оператора delete без фразы where тем, что не записывается в журнал
транзакций и, как следствие, выполняется существенно быстрее. Кроме того, оператор truncate table
сбрасывает значение счетчика для идентификационного столбца.
4.6. Целостность
Ограничение целостности (integrity – нетронутость, неприкосновенность, сохранность, целост-
ность) реляционного объекта данных (по состоянию) – это инвариант данных, что означает правиль-
ность данных в любой момент времени. Но эта цель может быть достигнута лишь в определенных
пределах: СУБД не может контролировать правильность каждого отдельного значения, вводимого в
базу данных (хотя каждое значение можно проверить на правдоподобность). Например, нельзя об-
наружить, что вводимое значение 5 (представляющее номер дня недели) в действительности должно
быть равно 3. С другой стороны, значение 9 явно будет ошибочным и СУБД должна его отверг-
нуть. Однако для этого ей следует сообщить, что номера дней недели должны принадлежать набору
(1,2,3,4,5,6,7).
Поддержание целостности базы данных может рассматриваться как защита данных от ошибочных
изменений.
Целостность следует отличать от безопасности, которая подразумевает защиту данных от несанк-
ционированного (незаконного) доступа к ним с целью раскрытия, изменения или разрушения дан-
ных.
Современные СУБД имеют ряд средств для обеспечения поддержания целостности (как, впрочем,
и средств обеспечения поддержания безопасности).
Правила поддержания ссылочной целостности во фразах on update и on delete могут быть различ-
ными.
Вставка кортежа в дочернее отношение или обновление значения ключа в дочернем отношении
не будут выполнены, если это будет приводить к нарушению ссылочной целостности. Удаление
кортежей из дочернего отношения не может привести к появлению висящих кортежей.
Дочернее отношение в одной связи может выступать в качестве родительского в другой связи со
своими правилами поддержания ссылочной целостности.
Процедурная поддержка нестандартных ограничений целостности реализуется с помощью тригге-
ров.
Предполагается, что лектор может участвовать в чтении лекций, не числясь в какой-либо органи-
зации из имеющегося списка организаций. Ключи (КодК, КодО и КодЛр) являются суррогатными.
Напишите на псевдокоде операторы создания указанных базовых отношений и обоснуйте на содер-
жательном уровне формулировку правил целостности.
Решение. При создании отношения Курсы требуем, чтобы наименование курса (ИмяК) было уни-
кальным и не могло принимать null-значений (можно было бы запретить и пустые значения):
create table Курсы
КодК counter,
ИмяК char not null
primary key(КодК)
candidate key(ИмяК)
Аналогичные ограничения сформулируем и для отношения Организации:
create table Организации
КодО counter,
ИмяО char not null
primary key(КодО)
candidate key(ИмяО)
Так как лектор может не числиться в какой-либо организации, то при создании отношения Лекторы
для внешнего ключа КодО null-значения полагаем допустимыми и для операции удаления сведений
об организации применяем правило присвоения null-значений (on delete set null):
create table Лекторы
КодЛр counter,
Ф char not null, И char not null, О char not null,
КодО integer null
primary key(КодЛр)
foreign key(КодО) references Организации(КодО) on delete set null
Примечание. Реакцию на обновление значения КодО в родительском отношении определять нет необходи-
мости, так как это значение обновить нельзя •
В отношении Лекции внешние ключи КодЛр и КодК являются атрибутами первичного ключа.
Поэтому для них null-значения объявляются недопустимыми. Реакции на обновление их значений в
родительских отношениях определять нет необходимости, т.к. эти значения обновить нельзя. Приме-
нение правила каскадной модификации (on delete cascade) при удалении данных о Лекторах и Кур-
сах соответствует стратегии хранения оперативных данных. Для атрибута ДатаНач null-значения
объявляются недопустимыми, так как атрибут входит в первичный ключ. Для атрибута ДатаКон
null-значения объявлены допустимыми с тем, чтобы можно было вводить данные о чтении лекций
с пока не определенной датой их окончания. Ограничение кортежа (ДатаНач < ДатаКон) не будет
препятствовать вводу таких данных.
BEGIN TRANSACTION
UPDATE счет-1 ...
IF возникла ошибка THEN GOTO undo
UPDATE счет-2 ...
IF возникла ошибка THEN GOTO undo
COMMIT TRANSACTION
RETURN
undo: ROLLBACK TRANSACTION
С понятием транзакции тесно связано понятие блокировки. Блокировки необходимы для того, чтобы
дать различным пользователям возможность одновременно работать с базой данных. При одновре-
менной работе в некоторый момент времени разные пользователи, могут обратиться к одной и той
же записи. Или один пользователь может использовать данные, которые в данный момент меняет
другой пользователь. СУБД должна запрещать подобные действия, поскольку они могут привести
к ошибкам.
Для реализации этого запрета СУБД устанавливает блокировку на объекты, которые использует
транзакция. Существуют разные типы блокировок – табличные, страничные, строчные и другие, ко-
торые отличаются друг от друга количеством заблокированных записей. Чаще других используется
строчная блокировка – при обращении транзакции к одной строке блокируется только эта строка,
остальные строки остаются доступными для изменения.
Таким образом, процесс внесения изменений в базу данных состоит из следующей последова-
тельности действий: выдается оператор начала транзакции, выдается оператор изменения данных,
СУБД анализирует оператор и пытается установить блокировки, необходимые для его выполнения,
в случае успешной блокировки оператор выполняется, затем процесс повторяется для следующего
оператора транзакции. После успешного выполнения всех операторов внутри транзакции выполняет-
ся оператор фиксации транзакции. СУБД фиксирует изменения, сделанные транзакцией и снимает
блокировки. В случае неуспеха выполнения какого-либо из операторов, транзакция откатывается,
данные получают прежние значения, снимаются блокировки.
4.6.4. Триггеры
Триггеры являются одной из разновидностей хранимых процедур. Хранимые процедуры представ-
ляют собой группу команд SQL, объединенных в один модуль. Такая группа команд компилируется
и выполняется как единое целое. Хранимая процедура является объектом базы данных.
Однако вызов триггеров, в отличие от вызовов хранимых процедур, не производится явно. Триг-
геры вызываются автоматически при выполнении над таблицей какой-либо операции модификации
(вставки, обновления или удаления строки). Триггеры используются для контроля целостности дан-
ных, а также для отката транзакций.
Триггер – это откомпилированная SQL-процедура, исполнение которой обусловлено наступлени-
ем определенных событий внутри реляционной базы данных. Применение триггеров большей частью
весьма удобно для пользователей базы данных. И все же их использование часто связано с дополни-
тельными затратами ресурсов на операции ввода/вывода. В том случае, когда тех же результатов (с
гораздо меньшими непроизводительными затратами ресурсов) можно добиться с помощью хранимых
процедур или прикладных программ, применение триггеров нецелесообразно.
Триггеры – особый инструмент SQL-сервера, используемый для поддержания целостности дан-
ных в базе данных. С помощью ограничений целостности, правил и значений по умолчанию не
всегда можно добиться нужного уровня функциональности. Часто требуется реализовать сложные
алгоритмы проверки данных, гарантирующие их достоверность и реальность. Кроме того, иногда
необходимо отслеживать изменения значений таблицы, чтобы нужным образом изменить связанные
данные.
Триггер представляет собой специальный тип хранимых процедур, запускаемых сервером автома-
тически при попытке изменения данных в таблицах, с которыми триггеры связаны. Каждый триггер
привязывается к конкретной таблице. Все производимые им модификации данных рассматриваются
как одна транзакция. В случае обнаружения ошибки или нарушения целостности данных происхо-
дит откат этой транзакции. Тем самым внесение изменений запрещается. Отменяются также все
изменения, уже сделанные триггером.
Создает триггер только владелец базы данных. Это ограничение позволяет избежать случайного
изменения структуры таблиц, способов связи с ними других объектов и т.п.
Триггер представляет собой весьма полезное и в то же время опасное средство. Так, при непра-
вильной логике его работы можно легко уничтожить целую базу данных, поэтому триггеры необхо-
димо очень тщательно отлаживать.
В отличие от обычной процедуры, триггер выполняется неявно в каждом случае возникновения
триггерного события; к тому же он не имеет аргументов. Приведение его в действие иногда называют
запуском триггера.
С помощью триггеров достигаются следующие цели:
Неправильно написанные триггеры могут привести к серьезным проблемам, таким, например, как
появление «мертвых» блокировок. Триггеры способны длительное время блокировать множество
ресурсов, поэтому следует обратить особое внимание на сведение к минимуму конфликтов доступа.
• Опишите понятие ключа схемы базового отношения. Что понимается под требованием «неиз-
быточности»?
Индексы
• Для чего предназначены индексы?
Целостность
• Что понимается под ограничением ссылочной целостности? Какие кортежи называются вися-
щими?
Виртуальные отношения
Модуль 3
5. Нормальные формы
Все проводимые ниже рассуждения о нормальных формах (как, впрочем, и о проектировании схем
баз данных) относятся к системам оперативной обработки транзакций OLTP и базовым отношениям.
Для OLAP-систем, как и для виртуальных отношений OLTP-систем, характерной является как раз
ненормализованность данных, связанная с избыточной формой их хранения и представления.
поставить можно лишь не более одной оценки). Однако помимо ограничения уникальности, свя-
занного с этим ключом, на отношение должно быть наложено то условие, что зачетка выдается
одному конкретному лицу и, следовательно, в этом отношении кортежи с одинаковым номером за-
четки должны содержать одинаковые значения атрибутов Ф, И, О (рис. 5.1). Поэтому, как говорят,
атрибуты Ф, И, О функционально зависят от атрибута № ЗК.
Таким образом, функциональная зависимость – это однозначная зависимость, затабулированная
в базе данных. Термин «зависимость» не означает, что в данном случае по № ЗК (числу) можно
без использования данных, хранимых в отношении, «вычислить» Ф, И, О. Он означает лишь, что
одному значению № ЗК нельзя в отношении сопоставить два или более значений Ф, И или О.
Определение. Пусть X и Y – подсхемы схемы отношения S, определяющие над схемой S схему
функциональной зависимости X → Y (читается «X стрелка Y»). Определим ограничение функци-
ональной зависимости invhX → Y i как утверждение о том, что в отношении со схемой S любые
два кортежа, совпадающие в проекции на подсхему X, должны совпадать и в проекции на подсхему
Y:
invhX → Y ir(S) = ∀t1, t2 ∈ r(t1[X] = t2[X] ⇒ t1[Y ] = t2[Y ]); X, Y ∈ S
В этом случае говорят, также, что X функционально определяет Y или что Y функционально
зависит от X. В схеме функциональной зависимости X → Y подсхема X называется левой частью,
а Y – правой частью. На схему функциональной зависимости для краткости обычно ссылаются как
на функциональную зависимость Конец определения.
Введенное понятие ограничения функциональной зависимости относится к ограничению на уровне
отношения, так как оно накладывает ограничения на возможные значения различных кортежей
одного и того же отношения.
Приведем примеры изображения функциональных зависимостей:
{№ ЗК} → {Ф, И, О}
{№ ЗК, МнемоП} → {Оценка}
ПВ1. ` X → X рефлексивность
ПВ2. X → Y ` X ∪ Z → Y пополнение
ПВ3. X → Y, Y ∪ W → Z ` X ∪ W → Z псевдотранзитивность
ПВТ. ` X ∪ Z → X тривиальность
ПВА. X → Y, X → Z ` X → Y ∪ Z аддитивность
ПВП. X → Y ∪ Z ` X → Y, X → Z проективность (обращение аддитивности)
При построении цепочек вывода после формулировки посылок применяется правило рефлексивно-
сти с тем, чтобы ввести функциональную зависимость с правой частью, фигурирующей в заключе-
нии. В правой части цепочки даются ссылки на правила, посылки правил и шаги, обосновывающие
шаг вывода.
Доказательство правила тривиальности
1. X → X ПВ1
2. X ∪ Z → X ПВ2, 1
Доказательство правила аддитивности:
1. X → Y посылка 1 ПВА
2. X → Z посылка 2 ПВА
3. Y ∪ Z → Y ∪ Z ПВ1
4. X ∪ Z → Y ∪ Z ПВ3, 1, 3
5. X ∪ X → Y ∪ Z ПВ3, 2, 4
6. X → Y ∪ Z 5
Доказательство правила проективности:
1. X → Y ∪ Z X → Y ∪ Z посылка ПВП
2. Y → Y Z→Z ПВ1
3. Y ∪ Z → Y Z ∪ Y → Z ПВ2, 2
4. X → Y X→Z ПВ3◦ , 1, 3
Конец теоремы.
Функциональная зависимость с левой частью, являющейся надмножеством правой части, называ-
ется тривиальной. Согласно правилу тривиальной зависимости, ограничение тривиальной зависи-
мости выполняется автоматически. Правило тривиальности является обобщением правила рефлек-
сивности и, как и последнее, могло бы быть получено непосредственно из определения ограничения
функциональной зависимости. Тот факт, что это правило является производным, не случаен и связан
с полнотой системы правил Армстронга (о чем позже).
Правила аддитивности и проективности применительно к функциональным зависимостям с
одинаковыми левыми частями позволяют объединять и расщеплять правые части зависимостей.
Смысл нормализации схемы базы данных состоит в определении схем базовых отношений, позво-
ляющих максимально уменьшить необходимость в написании программного кода, увеличить произ-
водительность и облегчить поддержку целостности данных.
Вернемся к ранее рассмотренному отношению, содержащему данные о результатах экзаменаци-
онной сессии (см. рис. 5.1), и опишем схему базы данных с учетом ограничений функциональных
зависимостей:
Вариант 1 схемы БД
Здесь для поддержания целостности данных, то есть для выполнения ограничения функциональ-
ной зависимости {№ ЗК} → {Ф, И, О}, при изменении фамилии необходимо просматривать все
кортежи отношения и вводить необходимые изменения (что чревато ошибками; ситуация усугуб-
ляется, если Ф, И, О имеются и в других отношениях). Однако поддержку этой функциональной
зависимости можно реализовать автоматически с помощью объявлений ключей, если провести де-
композицию этого отношения так, чтобы ненавязанная функциональная зависимость {№ ЗК} → {Ф,
И, О} была навязана объявлением ключа № ЗК в отношении, полученным из исходного проекцией
на объединение атрибутов левой и правой частей функциональной зависимости (рис. 5.2):
Вариант 2 схемы БД
Студенты(№ ЗК, Ф, И, О)
primary key(№ ЗК)
Вариант 1 схемы БД
Должности(КодД, Наименование)
primary key(КодД)
candidate key(Наименование)
2) атрибут Телефоны является многозначным, то есть его значением является множество значе-
ний;
Вариант 2 схемы БД
Должности(КодД, Наименование)
primary key(КодД)
candidate key(Наименование)
Примечание. В отношении Телефоны атрибут № таб является одновременно атрибутом первичного ключа
и внешним ключом, ссылающимся на первичный ключ отношения Сотрудники •
На отношение, находящееся в первой нормальной форме, в общем случае наложены ограничения
уникальности первичного и кандидатных ключей, ограничения внешних ключей, а также ограниче-
ния функциональных зависимостей.
Как провести классификацию ограничений функциональных зависимостей?
Атрибут, содержащийся в каком-либо первичном или кандидатном ключе отношения, называет-
ся ключевым. Все атрибуты отношения, следовательно, разбиваются («разбиваются» – значит без
пересечения) на ключевые и неключевые. Поэтому все ограничения функциональных зависимостей
можно разбить на два класса – с ключевыми и неключевыми атрибутами в правой части.
В левой части функциональной зависимости могут быть представлены атрибуты, не образующие в
совокупности первичный или кандидатный ключ («не ключ»), так как зависимости с левой частью,
образующей ключ, навязываются ограничениями уникальности при объявлении ключей.
Таким образом, схема отношения, находящегося в первой нормальной форме, имеет следующие
ограничения функциональных зависимостей, не навязанные объявлениями ключей:
Вариант 1 схемы БД
Сотрудники(№ таб, Ф, И, О)
primary key(№ таб)
Здесь неключевой атрибут № таб коменданта (корпуса) функционально зависит от части ключа.
Примечание. Это произошло из-за смешения понятий Корпуса и Аудитории •
После приведения ко второй нормальной форме путем декомпозиции отношения Аудитории полу-
чим
Вариант 2 схемы БД
Сотрудники(№ таб, Ф, И, О)
primary key(№ таб)
Аудитории(№ К, № А, ПлощадьКвМ)
primary key(№ К, № А)
foreign key(№ К) references Корпуса (№ К)
Примечание. Обратим внимание на то, что в отношении Аудитории атрибут первичного ключа № К
является одновременно внешним ключом, ссылающимся на первичный ключ отношения Корпуса •
В данном примере все требуемые функциональные зависимости навязаны объявлениями первич-
ных и внешних ключей (кандидатных нет). Поэтому дальнейшая нормализация не требуется.
Понятие второй нормальной формы самостоятельного значения не имеет. Оно является ослаблен-
ной формой понятия третьей нормальной формы.
Вариант 1 схемы БД
Должности(КодД, Наименование)
primary key(КодД)
candidate key(Наименование)
Вариант 2 схемы БД
Должности(КодД, Наименование)
primary key(КодД)
candidate key(Наименование)
Примечание. Обратим внимание на то, что в отношении Сотрудники атрибут КодД является одновремен-
но атрибутом двух различных внешних ключей •
В данном примере все функциональные зависимости оказались навязанными объявлениями клю-
чей, и дальнейшая нормализация не потребовалась. Однако в общем случае схема отношения, на-
ходящегося в третьей нормальной форме, может иметь ограничения функциональных зависимостей
для ключевых атрибутов:
Вариант 1 схемы БД
R(X, Y, Z)
primary key(X, Y)
{Z} → Y}
Если, как обычно, провести декомпозицию так, чтобы ненавязанная функциональная зависимость
{Z} → {Y} была навязана объявлением ключа Z в выделяемом отношении R1(Z, Y), то получим
R1(Z, Y)
primary key(Z)
R2(X, Z)
foreign key(Z) references R1(Z)
Но что объявить ключом в отношении R2? Построим табличный пример для исходного отношения
R (рис. 5.4). Пример показывает, что в отношении R2(X, Z) ≡ R[X, Z] ни X, ни Z не могут быть
ключами. Следовательно, ключом будет их пара:
Вариант 2 схемы БД
Рис. 5.4.: Пример допустимого состояния R
R1(Z, Y)
primary key(Z)
R2(X, Z)
primary key(X, Z)
foreign key(Z) references R1(Z)
{X, Y} → {Z}
Декомпозиция исходного отношения R связана с разрушением его первичного ключа, который
навязывал функциональную зависимость {X, Y} → {Z}. Поэтому в варианте 2 ее следует добавить
в качестве ограничения. Но это ограничение выражено в терминах атрибутов обоих отношений,
что означает невозможность их независимой модификации. Данный пример ограничения является
примером ограничения функциональной зависимости на уровне базы данных, так как здесь огра-
ничение накладывается на два (но в общем случае может накладываться и на более чем два) отно-
шения базы данных. Все ранее рассмотренные примеры функциональных зависимостей относились
к одному отношению, то есть формулировались на уровне отношения.
Как в варианте 1, так и в варианте 2 для контроля ограничения функциональной зависимости
необходимо прибегать к использованию триггеров. Но в варианте 1 (отношение находится в 3NF)
триггер будет оперировать кортежами одного отношения, тогда как в варианте 2 (отношения нахо-
дятся в NFBC, но они не являются независимыми) – двумя. Первый вариант проще.
Таким образом, на практике обычно ограничиваются приведением отношений к третьей нормаль-
ной форме (что всегда возможно). В большинстве случаев при этом оказывается, что отношения
находятся и в форме Бойса-Кодда. Контроль над ограничениями, не связанными с понятием функ-
циональных зависимостей, реализуют с помощью триггеров.
Примечание. Ситуации, когда отношение находится в 3NF, но не находится в NFBC, крайне редки на
практике •
Из определений нормальных форм следует их вложенность, иллюстрируемая диаграммой на рис. 5.5.
По отношению к третьей нормальной форме вторая форма является ослабленной, а форма Бойса-
Кодда – усиленной.
Отметим важность того, что понятия нормальных форм вводятся по отношению к заданному множеству
функциональных зависимостей. Например, следующее отношение Сотрудники не находится в тре-
тьей нормальной форме:
Должности(КодД, Наименование)
primary key(КодД)
candidate key(Наименование)
Построение схем начинаем со схем независимых отношений, так что каждое отношение будет
ссылаться только на предыдущие:
Организации(КодОрг, Наименование)
primary key(КодОрг)
candidate key(Наименование)
• Как понимать фразу «объявления (первичных и кандидатных) ключей навязывают схеме отно-
шения соответствующие ограничения функциональных зависимостей»?
Нормальные формы
• Всегда ли отношение может быть приведено к 3NF? А к NFBC (если иметь в ввиду декомпо-
зицию на независимые отношения)?
Модуль 4
6. Проектирование схем баз данных
Наиболее распространенным средством абстрактного представления схем баз данных на логическом
уровне является модель «сущность-связь» (ER-модель, Entity-Relationship model). Элементами моде-
ли являются классы сущностей, их атрибуты и связи.
Примечание. Далее диаграммы, составляющие графическую основу модели, изображаются в стиле уни-
фицированного языка моделирования UML •
Класс сущностей – это как бы «лишенный методов» класс объектов в смысле объектно-ориентированног
программирования. Он представляет собой множество реальных или абстрактных «чего-то», обла-
дающих общими атрибутами. Отдельный элемент этого множества называется экземпляром класса
сущностей.
Каждый класс сущностей может характеризоваться любым числом атрибутов и иметь произволь-
ное число связей с другими классами.
Связь между двумя классами сущностей может характеризоваться наименованием и кратно-
стью роли класса в связи, а также наименованием связи (безотносительно к роли) Типичными
кратностями являются:
1) 1 – один,
2) 0 . . . 1 – не-более-один,
3) 0 . . . ∞ – много («много» допускает и «ничего»),
Рис. 6.1.: Диаграмма со связью типа один-ко-многим
4) 1 . . . ∞ – один-или-более.
1) 1 : 1 – один-к-одному,
4) 0 . . . ∞ : 0 . . . ∞ – многие-ко-многим (М:М).
1) презентационные,
2) ключевые,
3) полные атрибутивные.
2) PK 7→ FK
Каждый атрибут первичного ключа может мигрировать по любой из этих схем. Но всевозмож-
ные комбинации таких составных миграций можно разбить на два класса со следующими схемами
миграции первичного ключа:
1) ∀ PK (PK 7→ PF)
2) ∃ PK (PK 7→ FK)
Первая схема миграции означает, что каждый атрибут первичного ключа родительского класса
переносится в состав первичного ключа дочернего класса. Такая связь называется идентифициру-
ющей, так как все атрибуты родительского ключа участвуют в идентификации дочерней сущности.
Вторая схема миграции означает, что некоторые атрибуты первичного ключа родительского класса
переносятся в состав неключевых атрибутов дочернего класса. Такая связь называется неиденти-
фицирующей, так как не все атрибуты родительского ключа участвуют в идентификации дочерней
сущности.
Идентифицирующая связь может быть двух видов в зависимости от того, полностью или непол-
ностью (частично) атрибуты мигрировавшего ключа формируют первичный ключ дочернего класса.
Полностью идентифицирующая связь называется также категориальной.
Неидентифицирующая связь может быть также двух видов, но в зависимости от того, запрещены
ли null-значения для всех атрибутов мигрировавшего ключа, или для некоторых разрешены. Если
запрещены, то неидентифицирующая связь называется обязательной. Если разрешены, то необяза-
тельной.
Этих четырех декларативно поддерживаемых СУБД видов связей, – полностью и неполностью
идентифицирующих, обязательных и необязательных неидентифицирующих, – достаточно для боль-
шинства задач, возникающих на практике. Нестандартные виды связей должны поддерживаться
процедурно с помощью триггеров.
Важно отметить, что на презентационных диаграммах разработчиком устанавливаются проек-
тируемые(требующие последующей реализации) кратности на концах связей. Например, между
сущностями Отдел и Сотрудник при проектировании может быть установлена связь типа не-более-
один-ко-многим (0 . . . 1 : 0 . . . ∞), один-ко-многим (1 : 0 . . . ∞), многие-ко-многим (0 . . . ∞ : 0 . . . ∞)
или, скажем, два-ко-многим (2 : 0 . . . ∞). Во всех случаях здесь каждому отделу разрешается иметь
много сотрудников. Но в первом случае каждый сотрудник может вообще не числиться или чис-
литься только в одном отделе. Во втором – обязан числиться в одном отделе. В третьем – может
числиться во многих отделах, а в последнем случае обязан числиться в двух отделах (совместитель).
Выбор того или иного типа устанавливаемых связей определяется правилами, установленными для
предметной области проектируемой базы данных.
При переходе к ключевым диаграммам ситуация иная. Здесь уже представлены спроектирован-
ные (реализованные) кратности на концах связей. Эти кратности являются следствием вида уста-
новленных связей. Но возможностей, предоставляемых механизмом миграции ключей, может быть
недостаточно для выражения всех требований, представленных на презентационных диаграммах.
Тогда при изображении классов сущностей следует указать необходимость их поддержки, включив
описания или ссылки на описания дополнительных ограничений и используемых триггеров в секцию
ограничений (рис. 6.2).
Между родительским и дочерним классами сущностей устанавливаются различные типы связей
в зависимости от вида связи (рис. 6.3).
Почему возникают такие кратности? Рассмотрим примеры, соответствующие видам связи (рис. 6.4,
6.5).
Рис. 6.2.: Изображение класса сущностей
На родительском конце связи только в последнем случае из-за возможности появления среди
значений внешнего ключа null-значений устанавливается необязательная связь (допускающая крат-
ность 0). В остальных случаях устанавливается кратность 1, так как согласно ограничению ссылоч-
ной целостности значению внешнего ключа должно быть сопоставлено значение первичного ключа
родительской сущности. Но оно может быть лишь одно, так как значения первичного ключа уни-
кальны.
На дочернем конце связи все связи являются необязательными (допускают кратность 0), так как
это не противоречит ограничениям ссылочной целостности – запрещено лишь появление висящих
дочерних сущностей. Значит, значению первичного ключа родительской сущности может быть и не
сопоставлено значение внешнего ключа дочерней сущности, но если оно сопоставлено, то только в
первом случае оно будет единственным, так как тогда значения внешнего ключа будут уникальными.
Рис. 6.3.: Типы связей в зависимости от вида связи
Рис. 6.4.: Миграция в PF
Рис. 6.5.: Миграция в FK
6.3. Классификация кластеров
В процессе моделирования для повышения уровня абстракции рассуждений используются такие
понятия, как ассоциация, обобщение, композиция, агрегация. Все эти понятия представляют со-
бой некоторые группы классов объектов (сущностей), тесно взаимосвязанных между собой. Такие
группы называются кластерами (cluster – гроздь, пучок, группа, скопление).
Но откуда возникли эти кластеры? Нельзя ли придумать еще какие либо кластеры? Как их выде-
лить из всего многообразия возможных взаимосвязей классов?
Проведем классификацию кластеров, исходя из числа родительских и дочерних классов сущно-
стей, представленных в нем. С учетом того, что родительский и дочерний классы могут совпадать,
получим три группы кластеров.
Группа 1. Родительский и дочерний классы сущностей совпадают. Это означает связь класса
сущностей с самим собой. Такая связь называется рекурсивной. Можно выделить два важных вида
рекурсивных связей:
Группа 2. Несколько родительских классов сущностей и один дочерний класс. Связи между клас-
сами могут быть произвольного вида. Такие кластеры приводят в реляционной модели к понятию
ассоциации (дочерний класс ассоциирует, объединяет, родительские классы).
Группа 3. Один родительский и несколько дочерних классов. В зависимости от вида устанавлива-
емых между классами связей получим следующую классификацию кластеров:
такая связь может быть только неидентифицирующей, и, кроме того, необязательной. В противном
случае null-значения для внешнего ключа были бы не допустимы, и рекурсия была бы бесконечной.
Атрибуты не могут появляться дважды в одном классе сущностей под одним и тем же именем.
Поэтому атрибуты мигрировавшего ключа обязательно должны получить имя роли.
Таким образом, в иерархической рекурсии атрибуты узла расширяются атрибутом (внешним клю-
чом), представляющим необязательную ссылку на первичный ключ узла – непосредственного пред-
ка.
Построим абстрактные диаграммы (рис. 6.6, 6.7), реализующие иерархическую рекурсию в реля-
ционной модели, и приведем пример в табличной форме (рис. 6.8).
Как прийти к подобным построениям? Пусть есть некоторое множество узлов, определяемых кодом
узла КодУ и некоторыми атрибутами:
Узлы(КодУ, Атрибуты)
primary key(КодУ)
Подчеркнем, что пока это множество узлов, а не их иерархия. Каждый узел в иерархии имеет не
более одного предка (корень предка не имеет). Поэтому достаточно просто ввести дополнительный
атрибут, допускающий null-значения и ссылающийся на этого предка:
Рис. 6.7.: Ключевая диаграмма
Примечание. Здесь под Атрибутами, понятно, подразумеваются собственные атрибуты класса сущностей,
не имеющие отношения к ключам (ключи – это тоже атрибуты) •
Примечание. Заметим, что в реляционной модели с помощью механизма внешних ключей реализуется
принцип «дочерние сущности знают о родительских, но не наоборот». В объектно-ориентированных моделях
часто применяется обратный принцип, при котором родительские классы объектов содержат в себе данные о
дочерних объектах •
6.4.2. Обобщения
Может ли данная схема иерархической рекурсии описывать не одну иерархию, а несколько однотип-
ных иерархий (то есть не дерево, а лес)? Да, так как число корневых узлов в схеме хранения данных
может быть произвольным. Число хранимых деревьев – это число null-значений, появляющихся в
значениях внешнего ключа КодУ_Предок.
Что делать, если дерево взвешенное, то есть каждой дуге сопоставлены некоторые атрибуты?
Включить их в число атрибутов класса УзловИерархия и разрешить принимать им null-значения,
так как для корневых узлов значения этих атрибутов не определены.
Как описать более сложную иерархию, например, с двумя предками для описания отношений отец-
дитя, мать-дитя? Так как число предков ограничено двумя, то отношение, описывающее множество
людей, расширяется двумя внешними ключами, ссылающимися на предка-отца и предка-мать:
При обновлении мнемокода подразделения (МнемоП) здесь применяется правило каскадного об-
новления (on update cascade), так что все непосредственно нижестоящие подразделения (посред-
ством мнемокода МнемоП_Выше) станут ссылаться на это новое значение мнемокода. В рассмат-
риваемом ниже примере при изменении значения первичного ключа (МнемоП) c 2 на 20 значения
внешнего ключа (МнемоП_Выше) также изменятся с 2 на 20.
При удалении подразделения применение правила присвоения null-значений (on delete set null)
приведет к тому, что все непосредственно нижестоящие подразделения приобретут самостоятельный
статус и станут корнями иерархий (например, при расформировании полка составляющие его бата-
льоны станут отдельными). В рассматриваемом ниже примере при удалении данных о подразделении
со значением первичного ключа (МнемоП), равным 2, значения внешнего ключа (МнемоП_Выше)
изменятся с 2 на null-значение.
Пример в табличной форме для организации со структурой 1(2(3,4),5(6)) приведен на рис. 6.11
Построения в данном примере укладываются с точностью до наименований в схему абстрактных
построений в терминах «Узлы – КодУ – КодУ_Предок»: эти термины заменяются на «Подразделения
– МнемоП – МнемоП_Выше».
Рис. 6.11.: Пример в табличной форме
класс в общем случае называется классом ассоциативных сущностей. Если класс ассоциативных
сущностей не имеет собственных дополнительных атрибутов, то он называется именующим, так как
каждый экземпляр класса «именует» связь предок/потомок путем ссылок на них.
Таким образом, первичный ключ класса сущностей, представляющих узлы сети, должен дважды
мигрировать в класс ассоциативных сущностей. В этом классе мигрировавшие ключи в совокуп-
ности должны образовывать составной первичный ключ. Поэтому устанавливаемые связи будут
неполностью идентифицирующими.
Атрибуты не могут появляться дважды в одном классе сущностей под одним и тем же именем.
Поэтому атрибуты мигрировавшего ключа обязательно должны получить имя роли.
Построим абстрактные диаграммы рис. 6.12, 6.13, реализующие сетевую рекурсию в реляционной
модели, и приведем пример в табличной форме (рис. 6.14).
Граф, описываемый приведенной схемой, является ориентированным (упоминание об этом для
краткости терминологии мы будем опускать), и потому для обозначения связи между узлами ис-
пользуется термин «дуга».
Примечание. Дуга, связывающая узлы, ориентирована от одного узла к другому, тогда как «ребро»,
связывающее узлы, ориентации не имеет •
Рис. 6.13.: Ключевая диаграмма
Примечание. При изображении родительских и дочерних классов удобно по возможности придерживаться
следующего правила: изображать родительский класс слева, а дочерний справа, так как родительский класс
не зависит от дочернего, а дочерний зависит от родительского •
Узлы(КодУ, Атрибуты)
primary key(КодУ)
Подчеркнем, что пока это множество узлов, а не их сеть. Каждый узел в сети может иметь много
предков и много потомков. Поэтому ясно, что расширение атрибутов узла ссылками на предков и
(или) потомков невозможно. Но как можно образовать связь между узлами, то есть, как можно
описать дугу, идущую из одного узла в другой? Очевидно, парой ссылок (КодУ_Из, КодУ_На). Из
этих элементарных соображений и возникает класс ассоциативных (в данном случае именующих)
сущностей Дуги:
Дуги(КодУ_Из, КодУ_На)
primary key(КодУ_Из, КодУ_На)
foreign key(КодУ_Из) references Узлы(КодУ)
foreign key(КодУ_На) references Узлы(КодУ)
Ключом здесь будет пара ссылок на узлы, так что узлы в одном направлении могут соединяться не
более чем одной дугой.
КодУ_Из должен быть объявлен ключом. Для этого следует сменить статус атрибута КодУ_На с PF
на FK и при этом наследовать запрет null-значений (рис. 6.15).
Здесь между классами Узлы и Дуги устанавливаются полностью идентифицирующая и обязатель-
ная неидентифицирующая связи.
Данный вариант реализации иерархической рекурсии отличается от ранее рассмотренного вариан-
та «УзловИерархия» тем, что теперь дуги вынесены в отдельный класс сущностей и класс сущностей
Узлы не смешен с понятием их иерархии. Это может быть полезным на практике в случае, когда в
проектируемой схеме базы данных дуги выступают в качестве самостоятельных сущностей.
6.5.3. Обобщения
Что делать, если допускаются кратные дуги, то есть речь идет не о графе, а о мультиграфе?
Достаточно в класс Дуги включить дополнительный атрибут Кратность.
Что делать, если граф взвешенный, то есть каждой дуге сопоставлены некоторые атрибуты?
Включить их в число атрибутов класса Дуги.
Выше даже в случае рассмотрения мультиграфа речь шла, по-существу, о том, что узлы связыва-
ются не более чем одной дугой, на которую «навешиваются» атрибуты, в частности, кратность.
Примечание. В классе Дуги ключом является пара ссылок на узлы, и, следовательно, эта пара (дуга) не
может дублироваться •
Что делать, если каждая из кратных дуг мультиграфа должна характеризоваться своим набором
значений атрибутов? Следует ввести «индивидуальность» дуги, соединяющей узлы. Например, дан-
ные об авиарейсах из пункта A в пункт B могут характеризоваться временем отправления, временем
прибытия, количеством посадочных мест и т.д. В данном случае индивидуальность дуги – это номер
рейса из пункта A в пункт B, и его следует включить в состав атрибутов первичного ключа:
Пункты(КодП, Название)
primary key(КодП)
Если атрибут № рейса не включить в состав первичного ключа, то число возможных рейсов из
одного пункта в другой будет не более одного.
Как и иерархическая, сетевая рекурсия допускает многочисленные обобщения.
Основная идея реализации сети и ее обобщений в реляционной модели проста: создание класса
ассоциативных сущностей, описывающего связи элементов сети.
6.5.4. Пример реализации сетевой рекурсии
Практическое задание. Построить реляционную модель, описывающую сетевую взаимосвязь до-
кументов по ссылкам. При этом
4) Привести пример в табличной форме для следующего случая перекрестных ссылок документов
1-4: 1(3,4), 2(1), 4(1,2,3).
При обновлении мнемокода документа (МнемоД) здесь применяются правила каскадного обновления
(on update cascade), так что все ссылки (МнемоД_Из и МнемоД_На) станут ссылаться на это новое
значение мнемокода. В рассматриваемом ниже примере при изменении значения первичного ключа
(МнемоД) 4 на 40 значения внешних ключей (МнемоД_Из и МнемоД_На) также изменятся с 4 на
40.
При удалении документа (МнемоД) применение правила каскадного удаления (on delete cascade)
для документа, из которого производится ссылка (МнемоД_Из), приведет к тому, что все ссылки из
этого документа также удалятся (если это не будет противоречить описываемому ниже правилу on
delete restrict).
При удалении документа (МнемоД) применение правила ограничения (on delete restrict) для до-
кумента, на который производится ссылка, приведет к тому, что документ не будет удален, если на
него имеются ссылки из каких-либо документов.
Пример в табличной форме для перекрестных ссылок документов 1-4 (1(3,4), 2(1), 4(1,2,3)) при-
веден на рис. 6.18. В примере на все документы имеются ссылки. Поэтому какой-либо документ
можно будет удалить, если предварительно из отношения Ссылки удалить ссылки на него.
Построения в данном примере укладываются с точностью до наименований в схему абстрактных
построений в терминах «Узлы – КодУ – Дуги – КодУ_Из – КодУ_На» : эти термины заменяются на
«Документы – МнемоД – Ссылки – МнемоД_Из – МнемоД_На».
Рис. 6.18.: Пример в табличной форме
6.6. Ассоциация
Ассоциация реализуется как взаимосвязь между несколькими родительскими и одним дочерним
классом, описываемая связями различных видов – полностью или неполностью идентифицирующи-
ми, обязательными или необязательными неидентифицирующими. Родительский класс может быть
и один, как, например, в сетевой рекурсии, но число связей, идущих от дочернего класса, должно
быть не менее двух (иначе теряется смысл ассоциации как «объединения»). Дочерний класс в ас-
социации в общем случае называется классом ассоциативных сущностей. В частном случае, когда
класс ассоциативных сущностей не имеет собственных дополнительных атрибутов и содержит толь-
ко атрибуты, мигрировавшие вместе с ключами из родительских классов, такой класс называется
классом именующих сущностей. Ассоциация называется n-арной, если число определяемых в ней
связей равно n (n ≥ 2).
Рис. 6.19.: Презентационная диаграмма
Примечание. Здесь, разумеется, собственные атрибуты классов сущностей УзлыA и УзлыB не обязаны
совпадать •
Ребра, связывающие эти узлы, описываются парой ссылок (КодУA, КодУВ). Из этих элементарных
соображений возникает класс ассоциативных (в данном случае именующих) сущностей Ребра:
Ребра(КодУA, КодУB)
primary key(КодУA, КодУB)
foreign key(КодУA) references УзлыA(КодУA)
foreign key(КодУB) references УзлыB(КодУB)
Ключом здесь будет пара ссылок на узлы, так что узлы разных долей могут соединяться не более
чем одним ребром. Естественно, как и в схемах реализации рекурсии, здесь возможны различные
обобщения.
6.6.2. Обобщения
Рассмотрим одно из обобщений, связанное с «индивидуализацией» дуг, в результате чего узлы
разных долей смогут соединяться произвольным числом ребер (двудольный мультиграф).
Пусть требуется описать график приема пациентов (рис. 6.22 и 6.23). Здесь атрибут Дата-время
включен в первичный ключ. Если этого не сделать, то для каждой пары врач-пациент можно было
бы зарегистрировать не более одной встречи.
Рис. 6.22.: Презентационная диаграмма
При обновлении значения любого мнемокода применяется правило каскадного обновления, так как
это полностью сохраняет содержательную часть хранимых данных. При удалении данных о Заказчи-
ках и Исполнителях помимо принятого правила каскадного удаления можно было бы использовать
правило ограничения restrict. При удалении данных о Консультанте применяется правило присвое-
ния null-значения, позволяющее сохранить данные о встречах Заказчика и Исполнителя.
Пример в табличной форме приведен на рис. 6.26.
Рис. 6.27.: Связь «обобщение-категория» в нотации UML
6.7. Обобщение
6.7.1. Абстрактная схема
Обобщение реализуется как взаимосвязь одного родительского с несколькими дочерними классами,
описываемая категориальными связями, то есть полностью идентифицирующими. При обобщении
реализуется иерархия категорий (иерархия наследования). Родительский класс определяет класс
обобщенных сущностей, характеризуемых атрибутами, общими для сущностей дочерних классов
(категориальных сущностей).
Термин «обобщение» соответствует переходу от детализированных, категориальных сущностей к
обобщенной сущности. Обратный переход называется детализацией.
Иерархии категорий делятся на два типа – полные и неполные. В полной иерархии категорий
одному экземпляру обобщенной сущности обязательно соответствует экземпляр какой-либо катего-
риальной сущности. Если иерархия категорий еще не выстроена полностью и в классе обобщенных
сущностей могут существовать экземпляры, которые не имеют соответствующих экземпляров в
классе категориальных сущностей, то такая иерархия категорий будет неполной.
На презентационных диаграммах связь «обобщение-категория» удобно изображать в нотации
UML (рис. 6.27).
Построим абстрактные диаграммы, реализующие обобщение в реляционной модели (рис. 6.28,
Рис. 6.28.: Презентационная диаграмма
Примечание. Вид при обобщении – это центральное место триады «род – вид – индивид». Стрелки,
идущие от категорий к обобщению, можно и не сливать •
6.29).
Полную или неполную иерархию категорий описывает данная схема реализации обобщения?
Неполную, так как это не противоречит кратностям, устанавливаемым на дочерних концах связей.
6.8. Композиция
6.8.1. Абстрактная схема
Композиция реализуется как взаимосвязь одного родительского с несколькими дочерними классами,
описываемая связями, обязательными на родительском конце. Это означает, что дочерние сущности
(компоненты) не могут существовать вне родительской сущности (композита).
Обязательными на родительском конце являются связи трех видов – полностью и неполностью
идентифицирующие и обязательные неидентифицирующие.
Рис. 6.32.: Пример в табличной форме
Но полностью идентифицирующие связи используются при обобщении. Почему они возникли при
композиции?
Все дело в идентификации компонента, принадлежащего композиту. Например, дом – это компо-
зит, состоящий из квартир и крыши. Как сослаться на крышу дома? По номеру дома. Следовательно,
класс сущностей Крыши будет связан с классом сущностей Дома с помощью полностью идентифи-
цирующей связи. Но в данном случае эта связь не имеет смысл «обобщение-категория», а имеет
смысл «композит-компонент».
Примечание. Крыша – это не дом, обладающий дополнительными специфическими свойствами, а часть
дома •
Различия в идентификации компонентов проявляются и случаях установления неполностью иден-
тифицирующих и обязательных неидентифицирующих связей. Обе связи устанавливают тип связи
один-ко-могим (1 : 0 . . . ∞) и в этом смысле аналогичны. Но рассмотрим пример композитной иерар-
хии «Дом – Подъезд – Квартира»:
Дома(№ Д)
primary key(№ Д)
Подъезды(№ Д, № П)
primary key(№ Д, № П)
foreign key(№ Д) references Дома(№ Д)
Квартиры(№ Д, № П, № кв)
primary key(№ Д, № кв)
foreign key(№ Д) references Дома(№ Д)
foreign key(№ Д, № П) references Подъезды(№ Д, № П)
Рис. 6.33.: Cвязь «композит-компонент» в нотации UML
Здесь можно было бы применить правило ограничения restrict, но это ввиду большого числа
аудиторий существенно затруднило бы удаление данных о корпусах.
Пример в табличной форме приведен на рис. 6.39.
Рис. 6.40.: Связь «агрегат-компонент» в нотации UML
6.9. Агрегация
6.9.1. Абстрактная схема
Агрегация реализуется как взаимосвязь одного родительского с несколькими дочерними классами,
описываемая связями, необязательными на родительском конце. Это означает, что дочерние сущно-
сти (компоненты) могут существовать вне родительской сущности (агрегата).
Необязательными на родительском конце являются связи единственного вида – необязательные
неидентифицирующие. Следовательно, компоненты агрегата, ссылающиеся на агрегат посредством
внешнего ключа, допускающего null-значения, существуют вне агрегата в случае, когда внешний
ключ имеет null-значение.
На презентационных диаграммах связь «агрегат-компонент» удобно изображать в нотации UML
(рис. 6.40).
Построим абстрактные диаграммы (рис. 6.41, 6.42), реализующие агрегацию в реляционной мо-
дели.
Рис. 6.41.: Презентационная диаграмма
Примечание. Например, для двери, как агрегата, видами компонентов могут быть дверное полотно, ручка,
петли. Стрелки, как и в случаях обобщения и композиции, можно и не сливать •
Рис. 6.42.: Ключевая диаграмма
6.9.2. Пример реализации агрегации
Практическое задание. Построить реляционную модель, описывающую маркированные компонен-
ты автомобиля (двигатель, шасси). При этом
1) Построить презентационную диаграмму.
2) Построить ключевую диаграмму. Привести маркеры атрибутов ключей и указать кратности
связей. Списывание автомобиля предполагает списывание шасси, но не двигателя. Какие виды
связей используются?
3) Сформулировать и записать на псевдокоде декларативные правила поддержания ссылочной
целостности. Обосновать на содержательном уровне выбор правил.
Решение. Данный пример представляет агрегацию общего вида, когда часть компонентов мо-
гут, а часть не могут существовать вне агрегата. Согласно презентационной диаграмме (рис. 6.43)
предполагается, что разукомплектованный автомобиль может и не иметь шасси, но если шасси в
комплектацию входит, то оно одно. Число двигателей, приписанных автомобилю (с учетом запас-
ных), не ограничивается. Чтобы подчеркнуть это, на презентационной диаграмме явно указывается
соответствующая кратность.
Ключевая диаграмма представлена на рис. 6.44.
Здесь в секцию атрибутов класса Двигатели введен виртуальный атрибут, формула вычисления
которого указана в секции ограничений.
В классе Шасси внешний ключ, ссылающийся на номер автомобиля, объявлен кандидатным клю-
чом. В результате тип устанавливаемой обязательной неидентифицирующей связи изменяется с
один-ко-многим (1 : 0 . . . ∞) на один-к-не-более-одному (1 : 0 . . . 1). Такой вариант установления
связей часто полезен на практике.
Рис. 6.43.: Презентационная диаграмма
Примечание. Здесь квадратные скобки, в которые должен быть заключен идентификатор № А, опускаются
в случаях, исключающих двусмысленность •
Согласно сформулированным правилам поддержания ссылочной целостности при изменении номе-
ра автомобиля проводится каскадное изменение и ссылок на него. При удалении данных об автомо-
биле разрывается связь с данными о двигателях, и удаляются данные о шасси.
пределах организации.
В правой части диаграммы установлена связь не-более-один-ко-многим (0 . . . 1 : 0 . . . ∞) между
Отделами и Сотрудниками организации (не все сотрудники организации числятся в отделах).
Таким образом, атрибут КодОрг попадает в класс Сотрудники дважды – один раз из класса
Организации с маркером PF, и один раз из класса Отделы с маркером FK. При унификации атрибут
КодОрг получает статус атрибута первичного/внешнего ключа PF, поглощающего статус атрибута
внешнего ключа (рис. 6.46).
В заключение приведем фрагмент оператора создания базового отношения Сотрудники:
create table Сотрудники
КодОтд null
primary key(КодОрг, № таб)
Рис. 6.46.: Ключевая диаграмма после унификации атрибутов
foreign key(КодОрг) references Организации(КодОрг)
foreign key(КодОрг, КодОтд) references Отделы(КодОрг, КодОтд)
• Что понимается под наименованием и кратностью роли класса в связи, наименованием связи?
• Как описать более сложную иерархию, например, с двумя предками для описания отношений
отец-дитя, мать-дитя?
Сетевая рекурсия
Обобщение
Дополнительные главы
7. Технологии баз данных
7.1. Информационные системы
С появлением вычислительной техники сразу образовались два основных направления ее использо-
вания:
Поэтапная итерационная модель предполагает наличие циклов обратной связи между этапами
«Анализ – Проектирование – Реализация – Внедрение – Сопровождение»:
Преимущество такой модели заключается в том, что межэтапные корректировки обеспечивают
большую гибкость и меньшую трудоемкость по сравнению с каскадной моделью. Однако время
жизни каждого из этапов может растянуться на весь период создания системы.
Спиральная модель опирается на начальные этапы жизненного цикла: анализ, предварительное и
детальное проектирование. Каждый виток спирали соответствует поэтапной модели создания фраг-
мента или версии системы, на нем уточняются цели и характеристики проекта, определяется его
качество, планируются работы следующего витка спирали.
Рис. 7.3.: Спиральная модель
Основная проблема спирального цикла – определение момента перехода на следующий этап. Для
ее решения необходимо ввести временные ограничения на каждый из этапов жизненного цикла.
Переход осуществляется в соответствии с планом, даже если не вся запланированная работа закон-
чена. План составляется на основе статистических данных, полученных в предыдущих проектах, и
личного опыта разработчиков.
Нерешенные вопросы и ошибки, допущенные на этапах анализа и проектирования ИС, порождают
на последующих этапах трудные, часто неразрешимые проблемы и, в конечном счете, приводят к
неуспеху всего проекта.
Главная особенность разработки современных ИС состоит в концентрации усилий на двух на-
чальных этапах ее жизненного цикла - анализе и проектировании, при относительно невысокой
сложности и трудозатратах на последующих этапах.
7.1.2. СУБД и БД
Основные потребности, которые при создании информационных систем не покрываются возможно-
стями обычных систем управления файлами – это
1) поддержка логической согласованности данных,
2) поддержка языка манипулирования данными,
3) восстановление данных после различного рода сбоев,
4) обеспечение параллельной работы пользователей.
Если информационная система опирается на некоторую систему управления данными, обладаю-
щую этими свойствами, то эта система управления данными является системой управления базами
данных (СУБД).
Базы данных (БД) – это наборы данных, находящиеся под контролем СУБД. Они представляют
собой совокупность описаний объектов конкретной предметной области и связей между ними.
СУБД относятся к категории наиболее сложных программных продуктов, имеющихся в настоящее
время. Они
• позволяют пользователям создавать новые базы данных и определять их схемы, то есть опи-
сывать логические структуры данных;
• позволяют модифицировать хранящиеся данные и извлекать данные в том или ином аспекте с
помощью так называемых запросов;
Затем возникли СУБД, основанные на реляционной модели данных. Реляционная модель предло-
жена Коддом (Codd) в 1970 году. В настоящее время реляционные СУБД и их модификации состав-
ляют основу рынка. Дальнейшие исследования ведутся в направлении сочетания в той или иной сте-
пени реляционной модели, объектно-ориентированного программирования и интернет-технологий.
Примечание. Строго говоря, понятие модели данных появилось позже разработки ранних СУБД вместе
с развитием реляционного подхода, широко применяемого в настоящее время. Абстрактное представление о
моделях данных ранних систем появилось на основе сравнительного анализа и выявления общих признаков
у различных СУБД, имеющихся к моменту развития реляционного подхода •
Рис. 7.4.: Пример одного из деревьев базы медицинских данных
• перейти от одного узла к другому внутри дерева (например, от отдела – к первому сотруднику);
• доступ к данным возможен только через корень дерева, что может значительно увеличить
время поиска данных для некоторых запросов.
2) атрибутов и методов;
3) классов;
3) управление транзакциями,
1) так называемые мягкие сбои, которые можно трактовать как внезапную остановку работы
компьютера, например, из-за аварийного отключения питания;
• аварийное завершение работы СУБД по причине ошибки в программе или в результате неко-
торого аппаратного сбоя,
1) наиболее внутреннюю часть – ядро СУБД (часто его называют Data Base Engine),
4) набор утилит.
В некоторых системах эти части выделяются явно, в других – нет, но логически такое разделение
можно провести во всех СУБД.
Ядро СУБД отвечает за управление данными во внешней памяти, управление буферами опера-
тивной памяти, управление транзакциями и журнализацию. Соответственно, можно выделить такие
компоненты ядра (по крайней мере, логически, хотя в некоторых системах эти компоненты выделя-
ются явно), как менеджер данных, менеджер буферов, менеджер транзакций и менеджер журнала.
Функции этих компонентов взаимосвязаны, и для обеспечения корректной работы СУБД все эти
компоненты должны взаимодействовать по тщательно продуманным и проверенным протоколам.
Ядро СУБД обладает собственным интерфейсом, не доступным пользователям напрямую и исполь-
зуемым в программах, производимых компилятором SQL (или в подсистеме поддержки выполнения
таких программ) и утилитах БД. Ядро СУБД является основной резидентной частью СУБД. При
использовании архитектуры «клиент-сервер» ядро является основной составляющей серверной части
системы.
Основной функцией компилятора языка БД является компиляция операторов языка БД в неко-
торую выполняемую программу. Основной проблемой реляционных СУБД является то, что языки
этих систем (а это, как правило, SQL) являются непроцедурными, то есть в операторе такого язы-
ка специфицируется некоторое действие над БД, но эта спецификация не является процедурой, а
лишь описывает в некоторой форме условия совершения желаемого действия. Поэтому компилятор
должен решить, каким образом выполнять оператор языка прежде, чем произвести программу. При-
меняются достаточно сложные методы оптимизации операторов. Результатом компиляции является
выполняемая программа, представляемая в некоторых системах в машинных кодах, но более часто
в выполняемом внутреннем машинно-независимом коде. В последнем случае реальное выполнение
оператора производится с привлечением подсистемы поддержки времени выполнения, представля-
ющей собой, по сути дела, интерпретатор этого внутреннего языка.
Наконец, в отдельные утилиты БД обычно выделяют такие процедуры, которые слишком наклад-
но выполнять с использованием языка БД, например, загрузка и выгрузка БД, сбор статистики, гло-
бальная проверка целостности БД и т.д. Утилиты программируются с использованием интерфейса
ядра СУБД, а иногда даже с проникновением внутрь ядра.
Построение кривой начинается с отрезка единичной длины – это 0-е поколение кривой Кох. Далее
каждое звено (в нулевом поколении один отрезок) заменяется на образующий элемент, соответству-
ющий n = 1. В результате такой замены получается следующее поколение кривой Кох. В 1-ом
поколении – это кривая из четырех прямолинейных звеньев, каждое длиной по 1/3. Для получения
следующего поколения проделываются те же действия – каждое звено заменяется на уменьшенный
образующий элемент. Кривая n-го поколения при любом конечном n называется предфракталом.
При n, стремящемся к бесконечности, кривая Кох становится фрактальным объектом.
Другим примером геометрического фрактального объекта является «дракон» Хартера-Хейтуэя.
Для его получения нужно изменить правила построения. Пусть образующим элементом будут два
равных отрезка, соединенных под прямым углом. В нулевом поколении заменим единичный отрезок
на этот образующий элемент так, чтобы угол был сверху. Можно сказать, что при такой замене
происходит смещение середины звена. При построении следующих поколений выполняется правило:
самое первое слева звено заменяется на образующий элемент так, чтобы середина звена смещалась
влево от направления движения, а при замене следующих звеньев, направления смещения середин
отрезков должны чередоваться. На рисунке представлены несколько первых поколений и 11-е поко-
ление кривой, построенной по вышеописанному принципу. Предельная фрактальная кривая при n,
стремящемся к бесконечности, называется «драконом» Хартера-Хейтуэя.
В машинной графике использование геометрических фракталов необходимо при получении изоб-
ражений деревьев, кустов, береговой линии. Двухмерные геометрические фракталы используются
для создания объемных текстур (рисунка на поверхности объекта).
системы (итерационного процесса). Меняя алгоритм выбора цвета, можно получить сложные фрак-
тальные картины с причудливыми многоцветными узорами. Неожиданностью для математиков стала
возможность с помощью примитивных алгоритмов порождать очень сложные нетривиальные струк-
туры.
В качестве примера рассмотрим множество Мандельброта.
Алгоритм его построения достаточно прост и основан на простом итеративном выражении:
Zi+1 = Zi ∗ Zi + C
Здесь Zi и C – комплексные переменные. Итерации выполняются для каждой стартовой точки
C прямоугольной или квадратной области – подмножестве комплексной плоскости. Итерационный
процесс продолжается до тех пор, пока Zi не выйдет за пределы окружности радиуса 2, центр
которой лежит в точке (0, 0), (это означает, что аттрактор динамической системы находится в бес-
конечности), или после достаточно большого числа итераций (например, 200-500) Zi сойдется к
Рис. 7.10.: Участок границы множества Мандельброта, увеличенный в 200 pаз
[10] Рамбо, Дж. UML: специальный справочник / Дж. Рамбо, А. Якобсон, Буч Г. Пер. с англ. —
СПб.: Питер, 2002. — С. 656.